diff --git a/docs/api-reference/edge-runtime.md b/docs/api-reference/edge-runtime.md index ee58486080765..a7d712689766a 100644 --- a/docs/api-reference/edge-runtime.md +++ b/docs/api-reference/edge-runtime.md @@ -130,15 +130,6 @@ The Edge Runtime supports the following web standard APIs: You can use `process.env` to access [Environment Variables](/docs/basic-features/environment-variables.md) for both `next dev` and `next build`. -Running `console.log` on `process.env` **will not** show all your Environment Variables. You have to access the variables directly as shown below: - -```javascript -console.log(process.env) -// { NEXT_RUNTIME: 'edge' } -console.log(process.env.TEST_VARIABLE) -// value -``` - ## Compatible Node.js Modules The following modules can be imported with and without the `node:` prefix when using the `import` statement: diff --git a/docs/basic-features/environment-variables.md b/docs/basic-features/environment-variables.md index a2ed7a0f0b345..acf28266607a6 100644 --- a/docs/basic-features/environment-variables.md +++ b/docs/basic-features/environment-variables.md @@ -44,10 +44,6 @@ export async function getStaticProps() { } ``` -> **Note**: In order to keep server-only secrets safe, environment variables are evaluated at build time, so only environment variables _actually_ used will be included. This means that `process.env` is not a standard JavaScript object, so you’re not able to -> use [object destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment). -> Environment variables must be referenced as e.g. `process.env.PUBLISHABLE_KEY`, _not_ `const { PUBLISHABLE_KEY } = process.env`. - > **Note**: Next.js will automatically expand variables (`$VAR`) inside of your `.env*` files. > This allows you to reference other secrets, like so: > diff --git a/packages/next/src/build/utils.ts b/packages/next/src/build/utils.ts index 11cb72b26b166..07b3f0f4915c6 100644 --- a/packages/next/src/build/utils.ts +++ b/packages/next/src/build/utils.ts @@ -1389,7 +1389,6 @@ export async function isPageStatic({ if (pathIsEdgeRuntime) { const runtime = await getRuntimeContext({ paths: edgeInfo.files.map((file: string) => path.join(distDir, file)), - env: edgeInfo.env, edgeFunctionEntry: { ...edgeInfo, wasm: (edgeInfo.wasm ?? []).map((binding: AssetBinding) => ({ diff --git a/packages/next/src/build/webpack/loaders/get-module-build-info.ts b/packages/next/src/build/webpack/loaders/get-module-build-info.ts index 1527bc8f1f9dc..c99994d29409f 100644 --- a/packages/next/src/build/webpack/loaders/get-module-build-info.ts +++ b/packages/next/src/build/webpack/loaders/get-module-build-info.ts @@ -33,7 +33,6 @@ export function getModuleBuildInfo(webpackModule: webpack.Module) { nextEdgeMiddleware?: EdgeMiddlewareMeta nextEdgeApiFunction?: EdgeMiddlewareMeta nextEdgeSSR?: EdgeSSRMeta - nextUsedEnvVars?: Set nextWasmMiddlewareBinding?: AssetBinding nextAssetMiddlewareBinding?: AssetBinding usingIndirectEval?: boolean | Set diff --git a/packages/next/src/build/webpack/plugins/middleware-plugin.ts b/packages/next/src/build/webpack/plugins/middleware-plugin.ts index 66803d1245e5b..a06c388fe40af 100644 --- a/packages/next/src/build/webpack/plugins/middleware-plugin.ts +++ b/packages/next/src/build/webpack/plugins/middleware-plugin.ts @@ -34,7 +34,6 @@ import { INSTRUMENTATION_HOOK_FILENAME } from '../../../lib/constants' import { NextBuildContext } from '../../build-context' export interface EdgeFunctionDefinition { - env: string[] files: string[] name: string page: string @@ -55,7 +54,6 @@ interface EntryMetadata { edgeMiddleware?: EdgeMiddlewareMeta edgeApiFunction?: EdgeMiddlewareMeta edgeSSR?: EdgeSSRMeta - env: Set wasmBindings: Map assetBindings: Map regions?: string[] | string @@ -188,7 +186,6 @@ function getCreateAssets(params: { ] const edgeFunctionDefinition: EdgeFunctionDefinition = { - env: Array.from(metadata.env), files: getEntryFiles(entrypoint.getFiles(), metadata, opts), name: entrypoint.name, page: page, @@ -248,17 +245,6 @@ function isInMiddlewareLayer(parser: webpack.javascript.JavascriptParser) { return parser.state.module?.layer === 'middleware' } -function isProcessEnvMemberExpression(memberExpression: any): boolean { - return ( - memberExpression.object?.type === 'Identifier' && - memberExpression.object.name === 'process' && - ((memberExpression.property?.type === 'Literal' && - memberExpression.property.value === 'env') || - (memberExpression.property?.type === 'Identifier' && - memberExpression.property.name === 'env')) - ) -} - function isNodeJsModule(moduleName: string) { return require('module').builtinModules.includes(moduleName) } @@ -461,32 +447,6 @@ function getCodeAnalyzer(params: { } } - /** - * Declares an environment variable that is being used in this module - * through this static analysis. - */ - const addUsedEnvVar = (envVarName: string) => { - const buildInfo = getModuleBuildInfo(parser.state.module) - if (buildInfo.nextUsedEnvVars === undefined) { - buildInfo.nextUsedEnvVars = new Set() - } - - buildInfo.nextUsedEnvVars.add(envVarName) - } - - /** - * A handler for calls to `process.env` where we identify the name of the - * ENV variable being assigned and store it in the module info. - */ - const handleCallMemberChain = (_: unknown, members: string[]) => { - if (members.length >= 2 && members[0] === 'env') { - addUsedEnvVar(members[1]) - if (!isInMiddlewareLayer(parser)) { - return true - } - } - } - /** * Handler to store original source location of static and dynamic imports into module's buildInfo. */ @@ -541,41 +501,9 @@ Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime`, .tap(NAME, handleWrapWasmInstantiateExpression) } - hooks.callMemberChain.for('process').tap(NAME, handleCallMemberChain) - hooks.expressionMemberChain.for('process').tap(NAME, handleCallMemberChain) hooks.importCall.tap(NAME, handleImport) hooks.import.tap(NAME, handleImport) - /** - * Support static analyzing environment variables through - * destructuring `process.env` or `process["env"]`: - * - * const { MY_ENV, "MY-ENV": myEnv } = process.env - * ^^^^^^ ^^^^^^ - */ - hooks.declarator.tap(NAME, (declarator) => { - if ( - declarator.init?.type === 'MemberExpression' && - isProcessEnvMemberExpression(declarator.init) && - declarator.id?.type === 'ObjectPattern' - ) { - for (const property of declarator.id.properties) { - if (property.type === 'RestElement') continue - if ( - property.key.type === 'Literal' && - typeof property.key.value === 'string' - ) { - addUsedEnvVar(property.key.value) - } else if (property.key.type === 'Identifier') { - addUsedEnvVar(property.key.name) - } - } - - if (!isInMiddlewareLayer(parser)) { - return true - } - } - }) if (!dev) { // do not issue compilation warning on dev: invoking code will provide details registerUnsupportedApiHooks(parser, compilation) @@ -653,7 +581,6 @@ function getExtractMetadata(params: { entry.includeDependencies.forEach(addEntriesFromDependency) const entryMetadata: EntryMetadata = { - env: new Set(), wasmBindings: new Map(), assetBindings: new Map(), } @@ -760,16 +687,6 @@ function getExtractMetadata(params: { entryMetadata.edgeApiFunction = buildInfo.nextEdgeApiFunction } - /** - * If there are env vars found in the module, append them to the set - * of env vars for the entry. - */ - if (buildInfo?.nextUsedEnvVars !== undefined) { - for (const envName of buildInfo.nextUsedEnvVars) { - entryMetadata.env.add(envName) - } - } - /** * If the module is a WASM module we read the binding information and * append it to the entry wasm bindings. diff --git a/packages/next/src/server/lib/route-resolver.ts b/packages/next/src/server/lib/route-resolver.ts index 2c75ca175789c..e83aeac49728c 100644 --- a/packages/next/src/server/lib/route-resolver.ts +++ b/packages/next/src/server/lib/route-resolver.ts @@ -165,7 +165,6 @@ export async function makeResolver( return { name: 'middleware', paths: middleware.files.map((file) => join(process.cwd(), file)), - env: Object.keys(process.env), wasm: [], assets: [], } diff --git a/packages/next/src/server/next-server.ts b/packages/next/src/server/next-server.ts index 3e5658d89cc58..364c5f4118771 100644 --- a/packages/next/src/server/next-server.ts +++ b/packages/next/src/server/next-server.ts @@ -2183,7 +2183,6 @@ export default class NextNodeServer extends BaseServer { }): { name: string paths: string[] - env: string[] wasm: { filePath: string; name: string }[] assets: { filePath: string; name: string }[] } | null { @@ -2214,7 +2213,6 @@ export default class NextNodeServer extends BaseServer { return { name: pageInfo.name, paths: pageInfo.files.map((file) => join(this.distDir, file)), - env: pageInfo.env ?? [], wasm: (pageInfo.wasm ?? []).map((binding) => ({ ...binding, filePath: join(this.distDir, binding.filePath), @@ -2322,7 +2320,6 @@ export default class NextNodeServer extends BaseServer { distDir: this.distDir, name: middlewareInfo.name, paths: middlewareInfo.paths, - env: middlewareInfo.env, edgeFunctionEntry: middlewareInfo, request: { headers: params.request.headers, @@ -2825,7 +2822,6 @@ export default class NextNodeServer extends BaseServer { distDir: this.distDir, name: edgeInfo.name, paths: edgeInfo.paths, - env: edgeInfo.env, edgeFunctionEntry: edgeInfo, request: { headers: params.req.headers, diff --git a/packages/next/src/server/web/sandbox/context.ts b/packages/next/src/server/web/sandbox/context.ts index 96d788a31e0a5..bcb5dba9d9fc4 100644 --- a/packages/next/src/server/web/sandbox/context.ts +++ b/packages/next/src/server/web/sandbox/context.ts @@ -91,10 +91,8 @@ async function loadWasm( return modules } -function buildEnvironmentVariablesFrom( - keys: string[] -): Record { - const pairs = keys.map((key) => [key, process.env[key]]) +function buildEnvironmentVariablesFrom(): Record { + const pairs = Object.keys(process.env).map((key) => [key, process.env[key]]) const env = Object.fromEntries(pairs) env.NEXT_RUNTIME = 'edge' return env @@ -108,10 +106,8 @@ Learn more: https://nextjs.org/docs/api-reference/edge-runtime`) throw error } -function createProcessPolyfill(options: Pick) { - const env = buildEnvironmentVariablesFrom(options.env) - - const processPolyfill = { env } +function createProcessPolyfill() { + const processPolyfill = { env: buildEnvironmentVariablesFrom() } const overridenValue: Record = {} for (const key of Object.keys(process)) { if (key === 'env') continue @@ -236,7 +232,7 @@ async function createModuleContext(options: ModuleContextOptions) { : undefined, extend: (context) => { context.WebSocket = require('next/dist/compiled/ws').WebSocket - context.process = createProcessPolyfill(options) + context.process = createProcessPolyfill() Object.defineProperty(context, 'require', { enumerable: false, @@ -416,7 +412,6 @@ interface ModuleContextOptions { moduleName: string onWarning: (warn: Error) => void useCache: boolean - env: string[] distDir: string edgeFunctionEntry: Pick } diff --git a/packages/next/src/server/web/sandbox/sandbox.ts b/packages/next/src/server/web/sandbox/sandbox.ts index 2398275b05802..c88d2cb063e8c 100644 --- a/packages/next/src/server/web/sandbox/sandbox.ts +++ b/packages/next/src/server/web/sandbox/sandbox.ts @@ -15,7 +15,6 @@ const FORBIDDEN_HEADERS = [ type RunnerFn = (params: { name: string - env: string[] onWarning?: (warn: Error) => void paths: string[] request: NodejsRequestData @@ -49,7 +48,6 @@ export const getRuntimeContext = async (params: { name: string onWarning?: any useCache: boolean - env: string[] edgeFunctionEntry: any distDir: string paths: string[] @@ -59,7 +57,6 @@ export const getRuntimeContext = async (params: { moduleName: params.name, onWarning: params.onWarning ?? (() => {}), useCache: params.useCache !== false, - env: params.env, edgeFunctionEntry: params.edgeFunctionEntry, distDir: params.distDir, }) diff --git a/test/e2e/middleware-general/app/middleware.js b/test/e2e/middleware-general/app/middleware.js index c45eb5f9cbcc9..e4ab975f5a939 100644 --- a/test/e2e/middleware-general/app/middleware.js +++ b/test/e2e/middleware-general/app/middleware.js @@ -116,22 +116,6 @@ export async function middleware(request) { } if (url.pathname === '/global') { - // The next line is required to allow to find the env variable - // eslint-disable-next-line no-unused-expressions - process.env.MIDDLEWARE_TEST - - // The next line is required to allow to find the env variable - // eslint-disable-next-line no-unused-expressions - const { ANOTHER_MIDDLEWARE_TEST } = process.env - if (!ANOTHER_MIDDLEWARE_TEST) { - console.log('missing ANOTHER_MIDDLEWARE_TEST') - } - - const { STRING_ENV_VAR: stringEnvVar } = process['env'] - if (!stringEnvVar) { - console.log('missing STRING_ENV_VAR') - } - return serializeData(JSON.stringify({ process: { env: process.env } })) } diff --git a/test/e2e/middleware-general/test/index.test.ts b/test/e2e/middleware-general/test/index.test.ts index 01ecfe8d73633..43bf6a5d1f081 100644 --- a/test/e2e/middleware-general/test/index.test.ts +++ b/test/e2e/middleware-general/test/index.test.ts @@ -138,11 +138,6 @@ describe('Middleware Runtime', () => { ) expect(manifest.middleware).toEqual({ '/': { - env: expect.arrayContaining([ - 'MIDDLEWARE_TEST', - 'ANOTHER_MIDDLEWARE_TEST', - 'STRING_ENV_VAR', - ]), files: expect.arrayContaining([ 'server/edge-runtime-webpack.js', 'server/middleware.js', @@ -481,7 +476,7 @@ describe('Middleware Runtime', () => { }) } - it('should contain process polyfill', async () => { + it('allows to access env variables', async () => { const res = await fetchViaHTTP(next.url, `/global`) const json = readMiddlewareJSON(res) diff --git a/test/e2e/middleware-trailing-slash/test/index.test.ts b/test/e2e/middleware-trailing-slash/test/index.test.ts index 750ce4187a8a0..5947edd61b910 100644 --- a/test/e2e/middleware-trailing-slash/test/index.test.ts +++ b/test/e2e/middleware-trailing-slash/test/index.test.ts @@ -113,7 +113,6 @@ describe('Middleware Runtime trailing slash', () => { '/': { files: ['server/edge-runtime-webpack.js', 'server/middleware.js'], name: 'middleware', - env: expect.arrayContaining([]), page: '/', matchers: [{ regexp: '^/.*$', originalSource: '/:path*' }], wasm: [], diff --git a/test/e2e/switchable-runtime/index.test.ts b/test/e2e/switchable-runtime/index.test.ts index 8366b4332eaa6..72e5b34cb6aa6 100644 --- a/test/e2e/switchable-runtime/index.test.ts +++ b/test/e2e/switchable-runtime/index.test.ts @@ -187,7 +187,6 @@ describe('Switchable runtime', () => { expect(manifest).toMatchObject({ functions: { '/api/hello': { - env: expect.arrayContaining([]), files: [ 'server/edge-runtime-webpack.js', 'server/pages/api/hello.js', @@ -200,7 +199,6 @@ describe('Switchable runtime', () => { wasm: [], }, '/api/edge': { - env: expect.arrayContaining([]), files: [ 'server/edge-runtime-webpack.js', 'server/pages/api/edge.js', @@ -623,7 +621,6 @@ describe('Switchable runtime', () => { expect(manifest).toMatchObject({ functions: { '/api/hello': { - env: expect.arrayContaining([]), files: [ 'server/edge-runtime-webpack.js', 'server/pages/api/hello.js', @@ -636,7 +633,6 @@ describe('Switchable runtime', () => { wasm: [], }, '/api/edge': { - env: expect.arrayContaining([]), files: [ 'server/edge-runtime-webpack.js', 'server/pages/api/edge.js', diff --git a/test/production/dependencies-can-use-env-vars-in-middlewares/index.test.ts b/test/production/dependencies-can-use-env-vars-in-middlewares/index.test.ts index c2c200a75ad76..bca3bfd82424b 100644 --- a/test/production/dependencies-can-use-env-vars-in-middlewares/index.test.ts +++ b/test/production/dependencies-can-use-env-vars-in-middlewares/index.test.ts @@ -1,8 +1,6 @@ import { createNext } from 'e2e-utils' import { NextInstance } from 'test/lib/next-modes/base' import { fetchViaHTTP } from 'next-test-utils' -import { readJson } from 'fs-extra' -import path from 'path' describe('dependencies can use env vars in middlewares', () => { let next: NextInstance @@ -55,19 +53,6 @@ describe('dependencies can use env vars in middlewares', () => { expect(next.cliOutput).not.toContain('patch-incorrect-lockfile') }) - it('parses the env vars correctly', async () => { - const testDir = next.testDir - const manifestPath = path.join( - testDir, - '.next/server/middleware-manifest.json' - ) - const manifest = await readJson(manifestPath) - const envVars = manifest?.middleware?.['/']?.env - - expect(envVars).toContain('ENV_VAR_USED_IN_MIDDLEWARE') - expect(envVars).toContain('MY_CUSTOM_PACKAGE_ENV_VAR') - }) - it('uses the environment variables', async () => { const response = await fetchViaHTTP(next.url, '/api') expect(JSON.parse(response.headers.get('data'))).toEqual({ diff --git a/test/production/middleware-environment-variables-in-node-server-reflect-the-usage-inference/index.test.ts b/test/production/middleware-environment-variables-in-node-server-reflect-the-usage-inference/index.test.ts deleted file mode 100644 index 7a92988615a11..0000000000000 --- a/test/production/middleware-environment-variables-in-node-server-reflect-the-usage-inference/index.test.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { createNext } from 'e2e-utils' -import { NextInstance } from 'test/lib/next-modes/base' -import { fetchViaHTTP } from 'next-test-utils' - -describe('middleware environment variables in node server reflect the usage inference', () => { - let next: NextInstance - - beforeAll(() => { - process.env.CAN_BE_INFERRED = 'can-be-inferred' - process.env.X_CUSTOM_HEADER = 'x-custom-header' - process.env.IGNORED_ENV_VAR = 'ignored-env-var' - }) - - beforeAll(async () => { - next = await createNext({ - files: { - 'pages/index.js': ` - export default function () { return
Hello, world!
} - `, - 'middleware.js': ` - export default function middleware() { - return new Response(null, { - headers: { - data: JSON.stringify({ - canBeInferred: process.env.CAN_BE_INFERRED, - rest: process.env - }), - 'X-Custom-Header': process.env.X_CUSTOM_HEADER, - } - }) - } - `, - }, - dependencies: {}, - }) - }) - afterAll(() => next.destroy()) - - it('limits process.env to only contain env vars that are inferred from usage', async () => { - const response = await fetchViaHTTP(next.url, '/test') - expect(JSON.parse(response.headers.get('data'))).toEqual({ - canBeInferred: 'can-be-inferred', - rest: { - CAN_BE_INFERRED: 'can-be-inferred', - X_CUSTOM_HEADER: 'x-custom-header', - NEXT_RUNTIME: 'edge', - }, - }) - }) -})