diff --git a/packages/bridge/src/module.ts b/packages/bridge/src/module.ts index 0ba9b565..a031c911 100644 --- a/packages/bridge/src/module.ts +++ b/packages/bridge/src/module.ts @@ -1,4 +1,4 @@ -import { defineNuxtModule, installModule, checkNuxtCompatibility, logger, writeTypes, addTemplate } from '@nuxt/kit' +import { defineNuxtModule, installModule, checkNuxtCompatibility, logger, writeTypes, addTemplate, addWebpackPlugin } from '@nuxt/kit' import type { NuxtModule, NuxtCompatibility } from '@nuxt/schema' import type { NodeMiddleware } from 'h3' import { fromNodeMiddleware } from 'h3' @@ -13,6 +13,7 @@ import { setupMeta } from './meta' import { setupTranspile } from './transpile' import { generateWebpackBuildManifest } from './webpack/manifest' import pageMetaModule from './page-meta/module' +import { ImportMetaPlugin } from './webpack/import-meta' export default defineNuxtModule({ meta: { @@ -173,5 +174,7 @@ export default defineNuxtModule({ getContents: () => 'export default false' }) } + + addWebpackPlugin(ImportMetaPlugin.webpack) } }) diff --git a/packages/bridge/src/webpack/import-meta.ts b/packages/bridge/src/webpack/import-meta.ts new file mode 100644 index 00000000..745ea5f6 --- /dev/null +++ b/packages/bridge/src/webpack/import-meta.ts @@ -0,0 +1,45 @@ +import { pathToFileURL } from 'node:url' +import { createUnplugin } from 'unplugin' +import { parseURL } from 'ufo' +import { normalize } from 'pathe' +import MagicString from 'magic-string' + +const NODE_MODULES_RE = /[\\/]node_modules[\\/]/ + +// support for `import.meta` in webpack 4 +export const ImportMetaPlugin = createUnplugin(() => { + return { + name: 'nuxt:import-meta-transform', + enforce: 'post', + transformInclude (id) { + const { pathname } = parseURL( + decodeURIComponent(pathToFileURL(id).href) + ) + if (pathname.endsWith('.js') || pathname.endsWith('.vue')) { + return true + } + }, + transform (code, id) { + id = normalize(id) + const isNodeModule = NODE_MODULES_RE.test(id) + + if (isNodeModule) { + return + } + + const s = new MagicString(code) + s.replace(/import\.meta\.client/g, 'process.client') + .replace(/import\.meta\.server/g, 'process.server') + .replace(/import\.meta\.browser/g, 'process.browser') + .replace(/import\.meta\.nitro/g, 'process.nitro') + .replace(/import\.meta\.prerender/g, 'process.prerender') + + if (s.hasChanged()) { + return { + code: s.toString(), + map: s.generateMap({ hires: true }) + } + } + } + } +}) diff --git a/playground/pages/with-layout.vue b/playground/pages/with-layout.vue index bb9680cd..6e1f77c6 100644 --- a/playground/pages/with-layout.vue +++ b/playground/pages/with-layout.vue @@ -1,8 +1,8 @@