Repository: nuxt/nuxt
Pull request #31190: fix(nuxt): fall back to wasm if oxc native bindings are missing
Author: login: danielroe
Labels: name: 3.x
name: 🐛 bug
description: Something isn't working as expected
Created: 2025-03-03T10:42:12Z | Merged: 2025-03-07T11:51:20Z

### 🔗 Linked issue

<!-- Please ensure there is an open issue and mention its number. For example, "resolves #123" -->

### 📚 Description

<!-- Describe your changes in detail. Why is this change required? What problem does it solve? -->

<!----------------------------------------------------------------------
Before creating the pull request, please make sure you do the following:

- Check that there isn't already a PR that solves the problem the same way. If you find a duplicate, please help us reviewing it.
- Read the contribution docs at https://nuxt.com/docs/community/contribution
- Ensure that PR title follows conventional commits (https://www.conventionalcommits.org)
- Update the corresponding documentation if needed.
- Include relevant tests that fail without this PR but pass with it.

Thank you for contributing to Nuxt!
----------------------------------------------------------------------->


Linked issue #123: What is the best way to load json.
I have a json file with data to initialise my pages. I put it in `/static` folder e.g. `/static/data.json`. Then I use `axios.get()` to load it from `/data.json`. That works on the client, but fails on the server. 

I have these questions, which I think will be very useful for wider audience as well:
1. What is wrong with the example below?
2. Is `/static` the best place to put data files?
3. is loading them via axios the best way ?
4. What if I want to load from 3 different locations for server, for client and for static build? 


```js
 export default {
    data({ req, params, store }) {
      
      return axios.get('/data.json')
        .then((res) => {
          return {
            authors: res.data
          }
        })
    }
  }
```

Thanks in advance
Linked issue comments: user: login: SkaterDad
created_at: 2017-01-11T23:32:54Z
body: Is this a file you will be changing often on the fly?   

If this configuration can be baked into the builds, another option could be to import the JSON file in the components that need it, utilizing Webpack's JSON loader?  Or convert it to a JS module and export the values. 
author_association: NONE
user: login: atinux
created_at: 2017-01-12T18:46:02Z
body: Hi @husayt 

To answer your questions:

## What is wrong with the example below?

When the http call is made from the server, axios has no idea that you're on http://localhost:3000, so it can't call the route `/data.json`. You have to give the full url.

It can be made by setting a `baseURL` variable in the `env` of your `nuxt.config.js`:

```js
// nuxt.config.js
module.exports = {
  env: {
    baseURL: (process.env.NODE_ENV === 'production' ? 'http//your-url' : 'http://localhost:3000')
  }
}
```

Then in you data method:

```js
async asyncData({ req, params, store }) {
  const authors = await axios.get(process.env.baseURL + '/data.json').then(res => res.data)

  return { authors }
  })
}
```

**I recommend to use the [axios module](https://axios.nuxtjs.org/) to avoid giving a `baseUrl` environment key.**

## Is `static/` the best place to put data files?

If you want to access them via an http call, it's a good place yes.

## Is loading them via `axios` the best way ?

Not really since from the server-side, you will have to make an HTTP call, which is not the best for performances.

So you can load the file from the server-side using `fs.readFile` to solve this (and also avoid to set the baseURL in the nuxt.config.js):

```js
async asyncData({ req, isServer, params, store }) {
  const data = {}

  if (process.server) {
    data.authors = JSON.parse(require('fs').readFileSync('../static/data.json', 'utf8'))
  } else {
    data.authors = await axios.get('/data.json').then(res => res.data)
  }

  return { authors }
}
```

Furthermore, if your data does not change often (and I guess it does not if it's in the static folder), then importing the file via Webpack is **a great solution** (credits to @SkaterDad for pointing it out).

```html
<script>
import authors from '~/static/data.json'

export default {
  asyncData ({ params }) {
    return { authors }
  }
}
</script>
```

The other advantage of using Webpack is that you don't have to expose this data in the `static/` folder, you can have a `data` folder an do `import authors from '~/data/authors.json'`

Another advantage, is that you can use the code-splitting feature to avoid putting the `data.json` inside the page bundle and load it asynchronously on the client-side (so it could be cached separately):

```html
<script>
const getAuthors = () => import('~/data/authors.json').then(m => m.default || m)

export default {
  async asyncData ({ req }) {
    const authors = await getAuthors()

    return { authors }
  }
}
</script>
```

The only disadvantage of using webpack is that `data.json` is linked to your bundle. In development there is no problem since Webpack will listen on the file and re-bundle everytime `data.json` changes. But in production, if you're changing the data file directly on your server, you will have to run `nuxt build` manually to reflect the changes.

## What if I want to load from 3 different locations for server, for client and for static build?

I'm not sure to understand the question, but all the code example I wrote works for all of them :)
author_association: MEMBER
user: login: husayt
created_at: 2017-01-15T19:27:50Z
body: @Atinux thanks for very detailed reply. This will be very useful addition to FAQ page.

We covered the following data file reading patterns:
1) to ajax download resources from both server/client (with axios) via baseurl, based on environment
2) read local files on server side via `fs.readFile`
3) import with webpack

There might be even more patterns.


So all is cool with running it in dev mode. Now I hit two problems running from static generated files (after `generate` completed).
1) the data is embedded in `window.___NUXT___` variable in the html and I would prefer it to be loaded from external file
2) When I open the page I can see all the information from the file ( basically list of names), but then in two seconds the list disappears. I have been trying to debug to catch what event is causing it, but maybe you are aware of something like that.

Thanks
author_association: CONTRIBUTOR
user: login: atinux
created_at: 2017-01-16T11:15:19Z
body: @husayt 

The data embedded in `window.__NUXT__` is required to hydrate the application before mounting it, this cannot be loaded from an external file.

For your error you're experiencing, can you provide me some code samples so I can reproduce this behaviour on my setup?
author_association: MEMBER
user: login: husayt
created_at: 2017-01-21T00:24:17Z
body: Hi @Atinux, thanks for detailed reply.

As for disappearing data here is the screen gif, showing that data disappears few seconds after loading.

![sozler](https://cloud.githubusercontent.com/assets/1169324/22169855/70c8b3a4-df6f-11e6-8b71-e0cb9370f9f8.gif)


Here is the code:
```js
<template>
  <section class="container">
  
    <h1 class="title">    {{title}}</h1>
    <li v-for="author in authors">
      <nuxt-link :to="{ name: 'authors-id', params: { id: author.id } }">{{ author.text }}</nuxt-link>
    </li>
  </section>
  
</template>

<script>
  import {axiosGet} from '~plugins/util'

  export default {
    data({ env,req,params,store}) {
     return axiosGet(env.baseURL +'rest/authors.json')
        .then((res) => {
          return {
            authors: res.data,
            title: 'Müəlliflər'
          }
        })
    },
    head() {
      return {
        title: this.title
      }
    },
  }
</script>
```
author_association: CONTRIBUTOR
user: login: patrickrodee
created_at: 2017-02-22T00:34:32Z
body: @husayt I've encountered the exact same issue. It appears to be an issue with Vue's vdom throwing a mismatch of the server rendered DOM and the virtual DOM. I've encountered it with homegrown Vue SSR and Nuxt. If the Nuxt team can get a fix, that'd be dope.
author_association: NONE
user: login: NateTheGreatt
created_at: 2017-03-27T14:20:20Z
body: @husayt I'm not sure if this is causing your issue, but you have invalid HTML in your template. Your `<li>` tag needs to be wrapped in a `<ul>` tag. Hopefully that will fix the problem.
author_association: NONE
user: login: maxschulmeister
created_at: 2017-04-09T19:08:49Z
body: is there a proper way to automatically webpack assets such as images that are defined in a json file?
author_association: NONE
user: login: heishung
created_at: 2017-10-02T04:54:59Z
body: hi i need help i'm try trans  variable {{location.slug}} in nuxt-link , 

 `<nuxt-link :to="{ name: 'location', params: { slug: location.slug} }">
              <img alt="" src="~/assets/public/orchidcruise-cabins-suites.png" width="100%">
                <div class="product-title has-text-centered">
                  <span class="text">{{location.name}}</span>
                </div></nuxt-link>`

author_association: NONE
user: login: lock[bot]
created_at: 2018-11-05T10:08:12Z
body: This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

author_association: NONE

Diff:
diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json
index 92acc146ea03..7a6865637171 100644
--- a/packages/nuxt/package.json
+++ b/packages/nuxt/package.json
@@ -80,6 +80,7 @@
     "@nuxt/schema": "workspace:*",
     "@nuxt/telemetry": "^2.6.5",
     "@nuxt/vite-builder": "workspace:*",
+    "@oxc-parser/wasm": "^0.56.3",
     "@unhead/vue": "^2.0.0-rc.1",
     "@vue/shared": "^3.5.13",
     "c12": "^3.0.2",
@@ -111,7 +112,7 @@
     "ofetch": "^1.4.1",
     "ohash": "^2.0.11",
     "on-change": "^5.0.1",
-    "oxc-parser": "^0.56.0",
+    "oxc-parser": "^0.56.3",
     "pathe": "^2.0.3",
     "perfect-debounce": "^1.0.0",
     "pkg-types": "^2.1.0",
diff --git a/packages/nuxt/src/core/nuxt.ts b/packages/nuxt/src/core/nuxt.ts
index 65dc280627e3..3def9d8c6545 100644
--- a/packages/nuxt/src/core/nuxt.ts
+++ b/packages/nuxt/src/core/nuxt.ts
@@ -51,6 +51,7 @@ import { ResolveDeepImportsPlugin } from './plugins/resolve-deep-imports'
 import { ResolveExternalsPlugin } from './plugins/resolved-externals'
 import { PrehydrateTransformPlugin } from './plugins/prehydrate'
 import { VirtualFSPlugin } from './plugins/virtual'
+import { initParser } from './utils/parse'
 
 export function createNuxt (options: NuxtOptions): Nuxt {
   const hooks = createHooks<NuxtHooks>()
@@ -336,6 +337,8 @@ async function initNuxt (nuxt: Nuxt) {
     }
   }
 
+  await initParser()
+
   // Support Nuxt VFS
   addBuildPlugin(VirtualFSPlugin(nuxt, { mode: 'server' }), { client: false })
   addBuildPlugin(VirtualFSPlugin(nuxt, { mode: 'client', alias: { '#internal/nitro': join(nuxt.options.buildDir, 'nitro.client.mjs') } }), { server: false })
diff --git a/packages/nuxt/src/core/utils/parse.ts b/packages/nuxt/src/core/utils/parse.ts
index ded886c53641..e59d7c124d59 100644
--- a/packages/nuxt/src/core/utils/parse.ts
+++ b/packages/nuxt/src/core/utils/parse.ts
@@ -1,7 +1,6 @@
 import { walk as _walk } from 'estree-walker'
 import type { Node, SyncHandler } from 'estree-walker'
 import type { ArrowFunctionExpression, CatchClause, FunctionDeclaration, FunctionExpression, Identifier, ImportDefaultSpecifier, ImportNamespaceSpecifier, ImportSpecifier, Program, VariableDeclaration } from 'estree'
-import { parseSync } from 'oxc-parser'
 import { type SameShape, type TransformOptions, type TransformResult, transform as esbuildTransform } from 'esbuild'
 import { tryUseNuxt } from '@nuxt/kit'
 
@@ -35,10 +34,25 @@ export function walk (ast: Program | Node, callback: Partial<WalkOptions>) {
   })
 }
 
+let parseSync: typeof import('oxc-parser').parseSync
+
+export async function initParser () {
+  try {
+    parseSync = await import('oxc-parser').then(r => r.parseSync)
+  } catch {
+    // this can fail on stackblitz so we fall back to wasm build
+    const { parseSync: wasmParse } = await import('@oxc-parser/wasm')
+    parseSync = (sourceFilename, code, options) => wasmParse(code, {
+      sourceFilename: sourceFilename.replace(/\?.*$/, '') + `.${options?.lang || 'ts'}`,
+      sourceType: 'module',
+    }) as any
+  }
+}
+
 export function parseAndWalk (code: string, sourceFilename: string, callback: WalkerCallback): Program
 export function parseAndWalk (code: string, sourceFilename: string, object: Partial<WalkOptions>): Program
 export function parseAndWalk (code: string, sourceFilename: string, callback: Partial<WalkOptions> | WalkerCallback) {
-  const lang = sourceFilename.match(/\.[cm]?([jt]sx?)$/)?.[1] as 'js' | 'ts' | 'jsx' | 'tsx' | undefined
+  const lang = sourceFilename.match(/\.[cm]?([jt]sx?)$/)?.[1] as 'js' | 'ts' | 'jsx' | 'tsx' | undefined || 'ts'
   const ast = parseSync(sourceFilename, code, { sourceType: 'module', lang })
   walk(ast.program as unknown as Program, typeof callback === 'function' ? { enter: callback } : callback)
   return ast.program as unknown as Program
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e716cf62863d..46f0a31414dc 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -348,6 +348,9 @@ importers:
       '@nuxt/vite-builder':
         specifier: workspace:*
         version: link:../vite
+      '@oxc-parser/wasm':
+        specifier: ^0.56.3
+        version: 0.56.3
       '@types/node':
         specifier: 22.13.9
         version: 22.13.9
@@ -445,8 +448,8 @@ importers:
         specifier: ^5.0.1
         version: 5.0.1
       oxc-parser:
-        specifier: ^0.56.0
-        version: 0.56.0
+        specifier: ^0.56.3
+        version: 0.56.3
       pathe:
         specifier: ^2.0.3
         version: 2.0.3
@@ -959,7 +962,7 @@ importers:
         version: 6.2.0(@types/node@22.13.9)(jiti@2.4.2)(sass@1.78.0)(terser@5.32.0)(tsx@4.19.2)(yaml@2.7.0)
       vite-node:
         specifier: ^3.0.7
-        version: 3.0.7(@types/node@22.13.9)(jiti@2.4.2)(terser@5.32.0)(tsx@4.19.2)(yaml@2.7.0)
+        version: 3.0.8(@types/node@22.13.9)(jiti@2.4.2)(sass@1.78.0)(terser@5.32.0)(tsx@4.19.2)(yaml@2.7.0)
       vite-plugin-checker:
         specifier: ^0.9.0
         version: 0.9.0(eslint@9.21.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.8.2)(vite@6.2.0(@types/node@22.13.9)(jiti@2.4.2)(terser@5.32.0)(tsx@4.19.2)(yaml@2.7.0))(vue-tsc@2.2.8(typescript@5.8.2))
@@ -1399,6 +1402,15 @@ packages:
     resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==}
     engines: {node: '>=10.0.0'}
 
+  '@emnapi/core@1.3.1':
+    resolution: {integrity: sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==}
+
+  '@emnapi/runtime@1.3.1':
+    resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==}
+
+  '@emnapi/wasi-threads@1.0.1':
+    resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==}
+
   '@es-joy/jsdoccomment@0.49.0':
     resolution: {integrity: sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==}
     engines: {node: '>=16'}
@@ -2027,6 +2039,9 @@ packages:
   '@module-federation/webpack-bundler-runtime@0.8.4':
     resolution: {integrity: sha512-HggROJhvHPUX7uqBD/XlajGygMNM1DG0+4OAkk8MBQe4a18QzrRNzZt6XQbRTSG4OaEoyRWhQHvYD3Yps405tQ==}
 
+  '@napi-rs/wasm-runtime@0.2.7':
+    resolution: {integrity: sha512-5yximcFK5FNompXfJFoWanu5l8v1hNGqNHh9du1xETp9HWk/B/PzvchX55WYOPaIeNglG8++68AAiauBAtbnzw==}
+
   '@netlify/functions@3.0.0':
     resolution: {integrity: sha512-XXf9mNw4+fkxUzukDpJtzc32bl1+YlXZwEhc5ZgMcTbJPLpgRLDs5WWSPJ4eY/Mv1ZFvtxmMwmfgoQYVt68Qog==}
     engines: {node: '>=18.0.0'}
@@ -2235,48 +2250,70 @@ packages:
   '@one-ini/wasm@0.1.1':
     resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==}
 
-  '@oxc-parser/binding-darwin-arm64@0.56.0':
-    resolution: {integrity: sha512-mFBzGjrkwLQpEPr5nML/Y2nFjp4bZIdBjCrqhW68y8tQRF9AJEGInt4qlXx9iqaw4E/H03fWs4TARiZCBQz0Kw==}
+  '@oxc-parser/binding-darwin-arm64@0.56.3':
+    resolution: {integrity: sha512-ednZ2jpUeIyqq6QI/eaP2XqbTyQ1Wi91PWNcTbudwisgWsjZ3LEFbfF5JxrTkriqfssQLcj9/5OUv13e37/CNw==}
+    engines: {node: '>=14.0.0'}
     cpu: [arm64]
     os: [darwin]
 
-  '@oxc-parser/binding-darwin-x64@0.56.0':
-    resolution: {integrity: sha512-w2koO1X0Uv2wtFS4y6qRmnVoz/1HyCW3JcBvtCHqCR/gJ5X2od2sjuNHBrK3aWrYIUhyWRjNvIqx/Fc0RINPZA==}
+  '@oxc-parser/binding-darwin-x64@0.56.3':
+    resolution: {integrity: sha512-lNPQXH+brKtQemzIdHV/4ZNzRG5HTggMWKkGwFDf4jihmp+qiX92vsk5vs7H5WkLSGEDfvfFfMVjIYJf8Iip5A==}
+    engines: {node: '>=14.0.0'}
     cpu: [x64]
     os: [darwin]
 
-  '@oxc-parser/binding-linux-arm64-gnu@0.56.0':
-    resolution: {integrity: sha512-N3GIeonnhtJ7hdIZcoOrz6vhfolejpyDdZl8isK13lDJNHoPqn9I4nuuTKPLpcVQi7uKrobwYYBfy4TeRKKu2Q==}
+  '@oxc-parser/binding-linux-arm-gnueabihf@0.56.3':
+    resolution: {integrity: sha512-qViWSDPplxgUi+nEiOtmjod60+yUYwdyQ7z84JzmA7qpDRjmSzsXdIMKUIVj2kaHSIYOumSJV7A/u61iUvmCbA==}
+    engines: {node: '>=14.0.0'}
+    cpu: [arm]
+    os: [linux]
+
+  '@oxc-parser/binding-linux-arm64-gnu@0.56.3':
+    resolution: {integrity: sha512-b5EHflhLVoZlsRTQytgYGC4uJ/hsGUNyWCPfGoAs2tniDaIL8foWA9ge287dh6CmvPfLmJQKaaPCgtDZfgc8cA==}
+    engines: {node: '>=14.0.0'}
     cpu: [arm64]
     os: [linux]
 
-  '@oxc-parser/binding-linux-arm64-musl@0.56.0':
-    resolution: {integrity: sha512-A65owfUOV1i46FAxzHdytEPe0spMZBqEBdsxDJ/qbQNuX0I9DMCk41I6XVWR+04n8UI5x7haQK52ZYtGHIIGzg==}
+  '@oxc-parser/binding-linux-arm64-musl@0.56.3':
+    resolution: {integrity: sha512-q79AmNImjT8/F8ifdutMnEoWHavj/3MNpjIn2Hxz9fvqDVWx2JZrvUNIQjqWm6UhCOisfZzjZowx3WMkfAaphA==}
+    engines: {node: '>=14.0.0'}
     cpu: [arm64]
     os: [linux]
 
-  '@oxc-parser/binding-linux-x64-gnu@0.56.0':
-    resolution: {integrity: sha512-pa7GYqflMdv2sF9fXdwIjwIatGc3ueUAMvEdEpQnK9Bs2iRhio1oX5poSZH+IvI6xaFkY1G6R3FJMXk5yVYFqw==}
+  '@oxc-parser/binding-linux-x64-gnu@0.56.3':
+    resolution: {integrity: sha512-jAsYQ9eAoJN9dSV8NLYD4V3mrL5nRRu2o984kgvJ52bNjdzsWx1pPypbJESjqM3LbayOM80hQB0f0v18rtEDJA==}
+    engines: {node: '>=14.0.0'}
     cpu: [x64]
     os: [linux]
 
-  '@oxc-parser/binding-linux-x64-musl@0.56.0':
-    resolution: {integrity: sha512-lN8ixFe1PrVlFn8y+4NRO1FrRRaelwB3X73VAQA/aJSsMnJULPojUP8SS0M+4/DWyrG3n0Vo6j3VgpeDHt6dOw==}
+  '@oxc-parser/binding-linux-x64-musl@0.56.3':
+    resolution: {integrity: sha512-6CGOySAosLBX+wEd4KoFj9yV7sjgFeRUrmjhhX7E/LqkTMwi+54RgNRUZwiqIzLig2RQAQWt9dHdF4HYk1+Mug==}
+    engines: {node: '>=14.0.0'}
     cpu: [x64]
     os: [linux]
 
-  '@oxc-parser/binding-win32-arm64-msvc@0.56.0':
-    resolution: {integrity: sha512-ftyp6zjFCTu/y8errflyX1dqWQoUuEH+12gWs2mY7h+dbXqYJqPCw675pHKWDG8cXOU854myQnXKYJioDjxQww==}
+  '@oxc-parser/binding-wasm32-wasi@0.56.3':
+    resolution: {integrity: sha512-BWMszfol6WQ8emi+EYDrGC0q9WSMB9cNee8DVOcU1kgtLlFyoStP9m3zTLRdFiq3i4qkVzm+bl/tvNrpHIyBGA==}
+    engines: {node: '>=14.0.0'}
+    cpu: [wasm32]
+
+  '@oxc-parser/binding-win32-arm64-msvc@0.56.3':
+    resolution: {integrity: sha512-7sFY0ePAMfDSuUuw1aYq6SVjUpjIy9SRPR6jsPADvi/Rtu4yJB136vcpXEu2PyROlAs4SBhSqddKcJjzlVDv3g==}
+    engines: {node: '>=14.0.0'}
     cpu: [arm64]
     os: [win32]
 
-  '@oxc-parser/binding-win32-x64-msvc@0.56.0':
-    resolution: {integrity: sha512-K4XFrfGneClqTef1gYjl/OcfauMV1xNp/BA4wRr7zok9DjCO7O6eRHlsuQok6jTlHjXC6hYPvw5rlOi2o6jANg==}
+  '@oxc-parser/binding-win32-x64-msvc@0.56.3':
+    resolution: {integrity: sha512-DrqbiasFNN4TCGD/84uu5eDtXzfregiy1IBxjU8KehsXMyGRIpyGslIXn/RK71sDCNA+XEGYUGD1FNM7uZA6wA==}
+    engines: {node: '>=14.0.0'}
     cpu: [x64]
     os: [win32]
 
-  '@oxc-project/types@0.56.0':
-    resolution: {integrity: sha512-PIm+VHA+/im2oeXJnwbGARlRQyUm9RR61wx2XBn43+a03OtqwBLQglGwkFWTVjOPFFbXqZW67sviPU42hVf4LA==}
+  '@oxc-parser/wasm@0.56.3':
+    resolution: {integrity: sha512-YzVMeTDrZjTTD1DjQ1RjUOBPkCZO9U1VcF6O/t7Ldw+/xwFPLWvFUTxMlDsaUVi86rHsjzpsDqB/WfKfXJIi8g==}
+
+  '@oxc-project/types@0.56.3':
+    resolution: {integrity: sha512-zYw7js4CgLSQZ9bfPJjqc5AMS3mM98ur18OA7smCUZe9gpv6agHBLsC5NsXerZLVS7L5r06i8olPvymiymhWyw==}
 
   '@parcel/watcher-android-arm64@2.5.1':
     resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==}
@@ -2753,6 +2790,9 @@ packages:
     resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
     engines: {node: '>=10.13.0'}
 
+  '@tybys/wasm-util@0.9.0':
+    resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==}
+
   '@types/aria-query@5.0.4':
     resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
 
@@ -5380,10 +5420,6 @@ packages:
     resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==}
     engines: {node: '>=8.9.0'}
 
-  local-pkg@1.1.0:
-    resolution: {integrity: sha512-xbZBuX6gYIWrlLmZG43aAVer4ocntYO09vPy9lxd6Ns8DnR4U7N+IIeDkubinqFOHHzoMlPxTxwo0jhE7oYjAw==}
-    engines: {node: '>=14'}
-
   local-pkg@1.1.1:
     resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==}
     engines: {node: '>=14'}
@@ -5940,8 +5976,9 @@ packages:
     resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
     engines: {node: '>= 0.8.0'}
 
-  oxc-parser@0.56.0:
-    resolution: {integrity: sha512-ukAB0QSM4/a1hVYFwWTW3GtJzmhjMCksSkXE28+rpcz/t1sYN7ZIpoW+Sz2oMsISVj14ew/nikCtg3Zci1n6vg==}
+  oxc-parser@0.56.3:
+    resolution: {integrity: sha512-++yMR2fMk1GxDtGm7xwifIzWfJ1WhzMK73fSrzF2iY/+aYMl68HiE1kI2xGGMmeZB7Rfg4WlBRuqigGFRq4nMg==}
+    engines: {node: '>=14.0.0'}
 
   p-limit@3.1.0:
     resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
@@ -6473,9 +6510,6 @@ packages:
     resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
     engines: {node: '>=6'}
 
-  quansync@0.2.4:
-    resolution: {integrity: sha512-1p13bC37Po/fOAixPZkZOLttIc51bU0oPYPdL7EDLmMxJ1p3lCryAtgMmVxmI3k3g0OZRKN+Cf1etcFLOwD3Vg==}
-
   quansync@0.2.8:
     resolution: {integrity: sha512-4+saucphJMazjt7iOM27mbFCk+D9dd/zmgMDCzRZ8MEoBfYp7lAvoN38et/phRQF6wOPMy/OROBGgoWeSKyluA==}
 
@@ -8226,6 +8260,22 @@ snapshots:
 
   '@discoveryjs/json-ext@0.5.7': {}
 
+  '@emnapi/core@1.3.1':
+    dependencies:
+      '@emnapi/wasi-threads': 1.0.1
+      tslib: 2.7.0
+    optional: true
+
+  '@emnapi/runtime@1.3.1':
+    dependencies:
+      tslib: 2.7.0
+    optional: true
+
+  '@emnapi/wasi-threads@1.0.1':
+    dependencies:
+      tslib: 2.7.0
+    optional: true
+
   '@es-joy/jsdoccomment@0.49.0':
     dependencies:
       comment-parser: 1.4.1
@@ -8537,7 +8587,7 @@ snapshots:
       debug: 4.4.0(supports-color@9.4.0)
       globals: 15.15.0
       kolorist: 1.8.0
-      local-pkg: 1.1.0
+      local-pkg: 1.1.1
       mlly: 1.7.4
     transitivePeerDependencies:
       - supports-color
@@ -8665,6 +8715,13 @@ snapshots:
       '@module-federation/runtime': 0.8.4
       '@module-federation/sdk': 0.8.4
 
+  '@napi-rs/wasm-runtime@0.2.7':
+    dependencies:
+      '@emnapi/core': 1.3.1
+      '@emnapi/runtime': 1.3.1
+      '@tybys/wasm-util': 0.9.0
+    optional: true
+
   '@netlify/functions@3.0.0':
     dependencies:
       '@netlify/serverless-functions-api': 1.30.1
@@ -8818,7 +8875,7 @@ snapshots:
       eslint-plugin-vue: 9.32.0(eslint@9.21.0(jiti@2.4.2))
       eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.21.0(jiti@2.4.2))
       globals: 15.15.0
-      local-pkg: 1.1.0
+      local-pkg: 1.1.1
       pathe: 2.0.3
       vue-eslint-parser: 9.4.3(eslint@9.21.0(jiti@2.4.2))
     transitivePeerDependencies:
@@ -8916,7 +8973,7 @@ snapshots:
       fake-indexeddb: 6.0.0
       get-port-please: 3.1.2
       h3: 1.15.1
-      local-pkg: 1.1.0
+      local-pkg: 1.1.1
       magic-string: 0.30.17
       node-fetch-native: 1.6.6
       ofetch: 1.4.1
@@ -9074,31 +9131,43 @@ snapshots:
 
   '@one-ini/wasm@0.1.1': {}
 
-  '@oxc-parser/binding-darwin-arm64@0.56.0':
+  '@oxc-parser/binding-darwin-arm64@0.56.3':
+    optional: true
+
+  '@oxc-parser/binding-darwin-x64@0.56.3':
     optional: true
 
-  '@oxc-parser/binding-darwin-x64@0.56.0':
+  '@oxc-parser/binding-linux-arm-gnueabihf@0.56.3':
     optional: true
 
-  '@oxc-parser/binding-linux-arm64-gnu@0.56.0':
+  '@oxc-parser/binding-linux-arm64-gnu@0.56.3':
     optional: true
 
-  '@oxc-parser/binding-linux-arm64-musl@0.56.0':
+  '@oxc-parser/binding-linux-arm64-musl@0.56.3':
     optional: true
 
-  '@oxc-parser/binding-linux-x64-gnu@0.56.0':
+  '@oxc-parser/binding-linux-x64-gnu@0.56.3':
     optional: true
 
-  '@oxc-parser/binding-linux-x64-musl@0.56.0':
+  '@oxc-parser/binding-linux-x64-musl@0.56.3':
     optional: true
 
-  '@oxc-parser/binding-win32-arm64-msvc@0.56.0':
+  '@oxc-parser/binding-wasm32-wasi@0.56.3':
+    dependencies:
+      '@napi-rs/wasm-runtime': 0.2.7
+    optional: true
+
+  '@oxc-parser/binding-win32-arm64-msvc@0.56.3':
     optional: true
 
-  '@oxc-parser/binding-win32-x64-msvc@0.56.0':
+  '@oxc-parser/binding-win32-x64-msvc@0.56.3':
     optional: true
 
-  '@oxc-project/types@0.56.0': {}
+  '@oxc-parser/wasm@0.56.3':
+    dependencies:
+      '@oxc-project/types': 0.56.3
+
+  '@oxc-project/types@0.56.3': {}
 
   '@parcel/watcher-android-arm64@2.5.1':
     optional: true
@@ -9540,6 +9609,11 @@ snapshots:
 
   '@trysound/sax@0.2.0': {}
 
+  '@tybys/wasm-util@0.9.0':
+    dependencies:
+      tslib: 2.7.0
+    optional: true
+
   '@types/aria-query@5.0.4': {}
 
   '@types/babel__core@7.20.5':
@@ -10099,7 +10173,7 @@ snapshots:
     dependencies:
       '@vue/compiler-sfc': 3.5.13
       ast-kit: 1.4.0
-      local-pkg: 1.1.0
+      local-pkg: 1.1.1
       magic-string-ast: 0.7.0
       pathe: 2.0.3
       picomatch: 4.0.2
@@ -12656,12 +12730,6 @@ snapshots:
       emojis-list: 3.0.0
       json5: 2.2.3
 
-  local-pkg@1.1.0:
-    dependencies:
-      mlly: 1.7.4
-      pkg-types: 1.3.1
-      quansync: 0.2.4
-
   local-pkg@1.1.1:
     dependencies:
       mlly: 1.7.4
@@ -13525,18 +13593,20 @@ snapshots:
       type-check: 0.4.0
       word-wrap: 1.2.5
 
-  oxc-parser@0.56.0:
+  oxc-parser@0.56.3:
     dependencies:
-      '@oxc-project/types': 0.56.0
+      '@oxc-project/types': 0.56.3
     optionalDependencies:
-      '@oxc-parser/binding-darwin-arm64': 0.56.0
-      '@oxc-parser/binding-darwin-x64': 0.56.0
-      '@oxc-parser/binding-linux-arm64-gnu': 0.56.0
-      '@oxc-parser/binding-linux-arm64-musl': 0.56.0
-      '@oxc-parser/binding-linux-x64-gnu': 0.56.0
-      '@oxc-parser/binding-linux-x64-musl': 0.56.0
-      '@oxc-parser/binding-win32-arm64-msvc': 0.56.0
-      '@oxc-parser/binding-win32-x64-msvc': 0.56.0
+      '@oxc-parser/binding-darwin-arm64': 0.56.3
+      '@oxc-parser/binding-darwin-x64': 0.56.3
+      '@oxc-parser/binding-linux-arm-gnueabihf': 0.56.3
+      '@oxc-parser/binding-linux-arm64-gnu': 0.56.3
+      '@oxc-parser/binding-linux-arm64-musl': 0.56.3
+      '@oxc-parser/binding-linux-x64-gnu': 0.56.3
+      '@oxc-parser/binding-linux-x64-musl': 0.56.3
+      '@oxc-parser/binding-wasm32-wasi': 0.56.3
+      '@oxc-parser/binding-win32-arm64-msvc': 0.56.3
+      '@oxc-parser/binding-win32-x64-msvc': 0.56.3
 
   p-limit@3.1.0:
     dependencies:
@@ -14058,8 +14128,6 @@ snapshots:
 
   punycode@2.3.1: {}
 
-  quansync@0.2.4: {}
-
   quansync@0.2.8: {}
 
   query-registry@3.0.1:
@@ -15039,7 +15107,7 @@ snapshots:
       acorn: 8.14.1
       escape-string-regexp: 5.0.0
       estree-walker: 3.0.3
-      local-pkg: 1.1.0
+      local-pkg: 1.1.1
       magic-string: 0.30.17
       mlly: 1.7.4
       pathe: 2.0.3
@@ -15127,7 +15195,7 @@ snapshots:
       chokidar: 4.0.3
       fast-glob: 3.3.3
       json5: 2.2.3
-      local-pkg: 1.1.0
+      local-pkg: 1.1.1
       magic-string: 0.30.17
       micromatch: 4.0.8
       mlly: 1.7.4
@@ -15391,7 +15459,7 @@ snapshots:
     dependencies:
       '@vitest/expect': 3.0.7
       '@vitest/mocker': 3.0.7(vite@6.2.0(@types/node@22.13.9)(jiti@2.4.2)(terser@5.32.0)(tsx@4.19.2)(yaml@2.7.0))
-      '@vitest/pretty-format': 3.0.7
+      '@vitest/pretty-format': 3.0.8
       '@vitest/runner': 3.0.7
       '@vitest/snapshot': 3.0.7
       '@vitest/spy': 3.0.7
diff --git a/test/setup-env.ts b/test/setup-env.ts
index 873b2632bfb3..b331b2eba79b 100644
--- a/test/setup-env.ts
+++ b/test/setup-env.ts
@@ -1,6 +1,7 @@
 import { consola } from 'consola'
 import { vi } from 'vitest'
 import { logger } from '../packages/kit'
+import { initParser } from '../packages/nuxt/src/core/utils/parse'
 
 consola.mockTypes(() => vi.fn())
 logger.mockTypes(() => vi.fn())
@@ -20,6 +21,8 @@ console.warn = (arg0: any, ...args: any[]) => {
   _warn(...args)
 }
 
+await initParser()
+
 // for (const t of ['uncaughtException', 'unhandledRejection'] as const) {
 //   process.on(t, (err) => {
 //     console.error(`[nuxt test suite] [${t}]`, err)


Reviews:
user: login: BobbieGoede
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-07T11:34:23Z
user: login: danielroe
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-07T11:35:59Z
user: login: BobbieGoede
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-07T11:38:17Z
user: login: danielroe
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-07T11:40:15Z

Review comments:
diff_hunk: @@ -38,14 +37,22 @@ export function walk (ast: Program | Node, callback: Partial<WalkOptions>) {
 let parseSync: typeof import('oxc-parser').parseSync
 
 export async function initParser () {
-  parseSync = await (provider === 'stackblitz' ? import('@oxc-parser/wasm') as unknown as Promise<typeof import('oxc-parser')> : import('oxc-parser'))
-    .then(r => r.parseSync)
+  try {
+    parseSync = await import('oxc-parser').then(r => r.parseSync)
+  } catch {
+    // this can fail on stackblitz so we fall back to wasm build
+    const { parseSync: wasmParse } = await import('@oxc-parser/wasm')
+    parseSync = (sourceFilename, code, options) => wasmParse(code, {
+      sourceFilename: sourceFilename.replace(/\?.*$/, '') + `.${options?.lang || 'ts'}`,
path: packages/nuxt/src/core/utils/parse.ts
user: login: BobbieGoede
body: Was about to share something like this, but I see we found the same workaround 😂
created_at: 2025-03-07T11:34:23Z
author_association: MEMBER
diff_hunk: @@ -38,14 +37,22 @@ export function walk (ast: Program | Node, callback: Partial<WalkOptions>) {
 let parseSync: typeof import('oxc-parser').parseSync
 
 export async function initParser () {
-  parseSync = await (provider === 'stackblitz' ? import('@oxc-parser/wasm') as unknown as Promise<typeof import('oxc-parser')> : import('oxc-parser'))
-    .then(r => r.parseSync)
+  try {
+    parseSync = await import('oxc-parser').then(r => r.parseSync)
+  } catch {
+    // this can fail on stackblitz so we fall back to wasm build
+    const { parseSync: wasmParse } = await import('@oxc-parser/wasm')
+    parseSync = (sourceFilename, code, options) => wasmParse(code, {
+      sourceFilename: sourceFilename.replace(/\?.*$/, '') + `.${options?.lang || 'ts'}`,
path: packages/nuxt/src/core/utils/parse.ts
user: login: danielroe
body: and it does work! though hope the signatures are aligned in a future minor bump ...
created_at: 2025-03-07T11:35:59Z
author_association: MEMBER
diff_hunk: @@ -38,14 +37,22 @@ export function walk (ast: Program | Node, callback: Partial<WalkOptions>) {
 let parseSync: typeof import('oxc-parser').parseSync
 
 export async function initParser () {
-  parseSync = await (provider === 'stackblitz' ? import('@oxc-parser/wasm') as unknown as Promise<typeof import('oxc-parser')> : import('oxc-parser'))
-    .then(r => r.parseSync)
+  try {
+    parseSync = await import('oxc-parser').then(r => r.parseSync)
+  } catch {
+    // this can fail on stackblitz so we fall back to wasm build
+    const { parseSync: wasmParse } = await import('@oxc-parser/wasm')
+    parseSync = (sourceFilename, code, options) => wasmParse(code, {
+      sourceFilename: sourceFilename.replace(/\?.*$/, '') + `.${options?.lang || 'ts'}`,
path: packages/nuxt/src/core/utils/parse.ts
user: login: BobbieGoede
body: that would be nice, I initially thought the signatures were the same.

btw, you're not passing `options` to `wasmParse`, might be unintended?
created_at: 2025-03-07T11:38:17Z
author_association: MEMBER
diff_hunk: @@ -38,14 +37,22 @@ export function walk (ast: Program | Node, callback: Partial<WalkOptions>) {
 let parseSync: typeof import('oxc-parser').parseSync
 
 export async function initParser () {
-  parseSync = await (provider === 'stackblitz' ? import('@oxc-parser/wasm') as unknown as Promise<typeof import('oxc-parser')> : import('oxc-parser'))
-    .then(r => r.parseSync)
+  try {
+    parseSync = await import('oxc-parser').then(r => r.parseSync)
+  } catch {
+    // this can fail on stackblitz so we fall back to wasm build
+    const { parseSync: wasmParse } = await import('@oxc-parser/wasm')
+    parseSync = (sourceFilename, code, options) => wasmParse(code, {
+      sourceFilename: sourceFilename.replace(/\?.*$/, '') + `.${options?.lang || 'ts'}`,
path: packages/nuxt/src/core/utils/parse.ts
user: login: danielroe
body: it doesn't take any more options if the type signature can be trusted, and we only use it in the function below
created_at: 2025-03-07T11:40:15Z
author_association: MEMBER

PR comments:
user: login: bolt-new-by-stackblitz[bot]
created_at: 2025-03-03T10:42:15Z
body: <a href="https://stackblitz.com/~/github.com/nuxt/nuxt/pull/31190"><img src="https://developer.stackblitz.com/img/review_pr_small.svg" alt="Review PR in StackBlitz Codeflow" align="left" width="103" height="20"></a> _Run & review this pull request in [StackBlitz Codeflow](https://stackblitz.com/~/github.com/nuxt/nuxt/pull/31190)._

author_association: NONE
user: login: socket-security[bot]
created_at: 2025-03-03T10:42:45Z
body: <!-- overview-comment -->
**New, updated, and removed dependencies detected.** Learn more about [Socket for GitHub ↗︎](https://socket.dev?utm_medium=gh)


| Package | New capabilities | Transitives | Size | Publisher |
|:--- |:--- |:--- |:--- |:--- |
| [npm/@oxc-parser/wasm@0.56.3](https://socket.dev/npm/package/@oxc-parser/wasm/overview/0.56.3) | <a href="https://socket.dev/npm/package/@oxc-parser/wasm/alerts/0.56.3?alert_name=filesystemAccess">filesystem</a> | <a href="https://socket.dev/npm/package/@oxc-parser/wasm/dependencies/0.56.3">`+1`</a> | 1.58 MB | <a href="https://socket.dev/npm/user/boshen">boshen</a> |


**🚮 Removed packages:** [npm/magic-string@0.30.17](https://socket.dev/npm/package/magic-string/overview/0.30.17)



[**View full report↗︎**](https://socket.dev/dashboard/org/nuxt/diff/dede0b5c-9843-4e55-96c5-72708a5b3979/ce16e64a-968d-4de3-92f9-1f1c8695cb17)
author_association: NONE
user: login: pkg-pr-new[bot]
created_at: 2025-03-03T10:57:47Z
body: 
[Open in Stackblitz](https://pkg.pr.new/template/b295e97b-05d1-47a8-bc54-c06063d5c442)


<details><summary><b>@nuxt/kit</b></summary><p>

```
npm i https://pkg.pr.new/@nuxt/kit@31190
```

</p></details>
      
    

<details><summary><b>nuxt</b></summary><p>

```
npm i https://pkg.pr.new/nuxt@31190
```

</p></details>
      
    

<details><summary><b>@nuxt/rspack-builder</b></summary><p>

```
npm i https://pkg.pr.new/@nuxt/rspack-builder@31190
```

</p></details>
      
    

<details><summary><b>@nuxt/schema</b></summary><p>

```
npm i https://pkg.pr.new/@nuxt/schema@31190
```

</p></details>
      
    

<details><summary><b>@nuxt/vite-builder</b></summary><p>

```
npm i https://pkg.pr.new/@nuxt/vite-builder@31190
```

</p></details>
      
    

<details><summary><b>@nuxt/webpack-builder</b></summary><p>

```
npm i https://pkg.pr.new/@nuxt/webpack-builder@31190
```

</p></details>
      
    

_commit: <a href="https://github.com/nuxt/nuxt/runs/38372582595"><code>6d85c15</code></a>_

author_association: NONE
user: login: codspeed-hq[bot]
created_at: 2025-03-03T11:06:32Z
body: <!-- __CODSPEED_PERFORMANCE_REPORT_COMMENT__ -->
<!-- __CODSPEED_INSTRUMENTATION_PERFORMANCE_REPORT_COMMENT__ -->

## [CodSpeed Performance Report](https://codspeed.io/nuxt/nuxt/branches/fix%2Fsb-oxc)

### Merging #31190 will **not alter performance**

<sub>Comparing <code>fix/sb-oxc</code> (6d85c15) with <code>3.x</code> (1a6db8c)</sub>



### Summary

`✅ 10` untouched benchmarks  




author_association: NONE