diff --git a/package.json b/package.json index ef90bc0349..2a9427f26c 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,6 @@ "dependencies": { "@cloudflare/kv-asset-handler": "^0.2.0", "@netlify/functions": "^1.0.0", - "@nuxt/devalue": "^2.0.0", "@rollup/plugin-alias": "^3.1.9", "@rollup/plugin-commonjs": "^22.0.0", "@rollup/plugin-inject": "^4.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 038d90fa59..e2679cf6d9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,7 +9,6 @@ importers: specifiers: '@cloudflare/kv-asset-handler': ^0.2.0 '@netlify/functions': ^1.0.0 - '@nuxt/devalue': ^2.0.0 '@nuxtjs/eslint-config-typescript': ^10.0.0 '@rollup/plugin-alias': ^3.1.9 '@rollup/plugin-commonjs': ^22.0.0 @@ -95,7 +94,6 @@ importers: dependencies: '@cloudflare/kv-asset-handler': 0.2.0 '@netlify/functions': 1.0.0 - '@nuxt/devalue': 2.0.0 '@rollup/plugin-alias': 3.1.9_rollup@2.71.1 '@rollup/plugin-commonjs': 22.0.0_rollup@2.71.1 '@rollup/plugin-inject': 4.0.4_rollup@2.71.1 @@ -831,10 +829,6 @@ packages: '@nodelib/fs.scandir': 2.1.5 fastq: 1.13.0 - /@nuxt/devalue/2.0.0: - resolution: {integrity: sha512-YBI/6o2EBz02tdEJRBK8xkt3zvOFOWlLBf7WKYGBsSYSRtjjgrqPe2skp6VLLmKx5WbHHDNcW+6oACaurxGzeA==} - dev: false - /@nuxtjs/eslint-config-typescript/10.0.0_t725usgvqspm5woeqpaxbfp2qu: resolution: {integrity: sha512-DaFjb0IPOq5MhdPs/5h0+kUmjQ6sVSMo3mrEuuAY3r2NUWmVSWEFrlUCqx0S0pHvjBXS4MfwBWS/oWPs41aQeA==} peerDependencies: diff --git a/src/options.ts b/src/options.ts index f8d15cd35b..36fcbf2d76 100644 --- a/src/options.ts +++ b/src/options.ts @@ -64,6 +64,7 @@ const NitroDefaults: NitroConfig = { analyze: false, moduleSideEffects: ['unenv/runtime/polyfill/'], replace: {}, + node: true, sourceMap: true, // Advanced diff --git a/src/rollup/config.ts b/src/rollup/config.ts index 4c3fe4edc0..1cfd1d9910 100644 --- a/src/rollup/config.ts +++ b/src/rollup/config.ts @@ -2,7 +2,6 @@ import { pathToFileURL } from 'url' import { dirname, join, normalize, relative, resolve } from 'pathe' import type { InputOptions, OutputOptions } from 'rollup' import defu from 'defu' -import devalue from '@nuxt/devalue' import { terser } from 'rollup-plugin-terser' import commonjs from '@rollup/plugin-commonjs' import { nodeResolve } from '@rollup/plugin-node-resolve' @@ -133,20 +132,42 @@ export const getRollupConfig = (nitro: Nitro) => { rollupConfig.plugins.push(wasmPlugin()) } + // Build-time environment variables + const buildEnvVars = { + NODE_ENV: nitro.options.dev ? 'development' : (nitro.options.preset === 'nitro-prerender' ? 'prerender' : 'production'), + server: true, + client: false, + dev: String(nitro.options.dev), + RUNTIME_CONFIG: nitro.options.runtimeConfig, + DEBUG: nitro.options.dev + } + + // Universal import.meta + rollupConfig.plugins.push({ + name: 'import-meta', + renderChunk (code, chunk) { + if (!chunk.isEntry) { + return + } + const url = nitro.options.node ? '_import_meta_url_' : '"file://_entry.js"' + const env = nitro.options.node ? 'process.env' : '{}' + return { + code: `globalThis._importMeta_={url:${url},env:${env}};` + code, + map: null + } + } + }) + // https://github.com/rollup/plugins/tree/master/packages/replace - let NODE_ENV: string = nitro.options.dev ? 'development' : 'production' - if (nitro.options.preset === 'nitro-prerender') { NODE_ENV = 'prerender' } rollupConfig.plugins.push(replace({ preventAssignment: true, values: { - 'process.env.NODE_ENV': JSON.stringify(NODE_ENV), 'typeof window': '"undefined"', + _import_meta_url_: 'import.meta.url', + ...Object.fromEntries(['.', ';', ')', '[', ']', '}', ' '].map(d => [`import.meta${d}`, `globalThis._importMeta_${d}`])), ...Object.fromEntries([';', '(', '{', '}', ' ', '\t', '\n'].map(d => [`${d}global.`, `${d}globalThis.`])), - 'process.server': 'true', - 'process.client': 'false', - 'process.dev': String(nitro.options.dev), - 'process.env.RUNTIME_CONFIG': devalue(nitro.options.runtimeConfig), - 'process.env.DEBUG': JSON.stringify(nitro.options.dev), + ...Object.fromEntries(Object.entries(buildEnvVars).map(([key, val]) => ([`process.env.${key}`, JSON.stringify(val)]))), + ...Object.fromEntries(Object.entries(buildEnvVars).map(([key, val]) => ([`import.meta.env.${key}`, JSON.stringify(val)]))), ...nitro.options.replace } })) @@ -175,17 +196,6 @@ export const getRollupConfig = (nitro: Nitro) => { rollupConfig.plugins.push(serverAssets(nitro)) // Public assets - if (nitro.options.serveStatic) { - rollupConfig.plugins.push({ - name: 'dirnames', - renderChunk (code, chunk) { - return { - code: (chunk.isEntry ? 'globalThis.entryURL = import.meta.url;' : '') + code, - map: null - } - } - }) - } rollupConfig.plugins.push(publicAssets(nitro)) // Storage diff --git a/src/rollup/plugins/public-assets.ts b/src/rollup/plugins/public-assets.ts index b0c0ac5574..c1ed3e9ef2 100644 --- a/src/rollup/plugins/public-assets.ts +++ b/src/rollup/plugins/public-assets.ts @@ -40,7 +40,7 @@ import { resolve } from 'pathe' import { dirname } from 'pathe' import { fileURLToPath } from 'url' import assets from '#internal/nitro/virtual/public-assets-data' -const mainDir = dirname(fileURLToPath(globalThis.entryURL)) +const mainDir = dirname(fileURLToPath(import.meta.url)) export function readAsset (id) { return fsp.readFile(resolve(mainDir, assets[id].path)).catch(() => {}) }`, diff --git a/test/fixture/api/import-meta.ts b/test/fixture/api/import-meta.ts new file mode 100644 index 0000000000..b9ae959a4f --- /dev/null +++ b/test/fixture/api/import-meta.ts @@ -0,0 +1,9 @@ +import { fileURLToPath } from 'url' + +export default () => { + return { + testFile: fileURLToPath(new URL('./test.txt', import.meta.url)), + // @ts-ignore + hasEnv: typeof import.meta.env === 'object' + } +} diff --git a/test/tests.ts b/test/tests.ts index 5f24e73f02..1218f819c6 100644 --- a/test/tests.ts +++ b/test/tests.ts @@ -105,6 +105,13 @@ export function testNitro (ctx: Context, getHandler: () => TestHandler | Promise expect(heyData).to.have.string('Hey API') }) + it('universal import.meta', async () => { + const { status, data } = await callHandler({ url: '/api/import-meta' }) + expect(status).toBe(200) + expect(data.testFile).toMatch(/\/test.txt$/) + expect(data.hasEnv).toBe(true) + }) + if (ctx.nitro!.options.serveStatic) { it('serve static asset /favicon.ico', async () => { const { status, headers } = await callHandler({ url: '/favicon.ico' })