Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow dependencies to use environment variables in middlewares (#33141)
After discussing with @sokra, seems that the proposed solution is split in two: * We need to make sure that the `process` polyfill uses `global.process` if available. This is because middlewares are bundled using `browser` target and therefore `process.env.MY_ENV` gets shimmed into `require('process').env.MY_ENV`. * Allow `process.env` to be statically analyzed for dependencies so they will be exported to the manifest. Related issues: * should fix #33043.
- Loading branch information
Showing
4 changed files
with
76 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = global.process || require('../../compiled/process') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
test/production/dependencies-can-use-env-vars-in-middlewares/index.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { createNext } from 'e2e-utils' | ||
import { NextInstance } from 'test/lib/next-modes/base' | ||
import { renderViaHTTP } from 'next-test-utils' | ||
import { readJson } from 'fs-extra' | ||
import path from 'path' | ||
|
||
describe('dependencies can use env vars in middlewares', () => { | ||
let next: NextInstance | ||
|
||
beforeAll(() => { | ||
process.env.MY_CUSTOM_PACKAGE_ENV_VAR = 'my-custom-package-env-var' | ||
process.env.ENV_VAR_USED_IN_MIDDLEWARE = 'env-var-used-in-middleware' | ||
}) | ||
|
||
beforeAll(async () => { | ||
next = await createNext({ | ||
files: { | ||
// A 3rd party dependency | ||
'node_modules/my-custom-package/package.json': JSON.stringify({ | ||
name: 'my-custom-package', | ||
version: '1.0.0', | ||
browser: 'index.js', | ||
}), | ||
'node_modules/my-custom-package/index.js': ` | ||
module.exports = () => process.env.MY_CUSTOM_PACKAGE_ENV_VAR; | ||
`, | ||
|
||
// The actual middleware code | ||
'pages/api/_middleware.js': ` | ||
import customPackage from 'my-custom-package'; | ||
export default function middleware(_req) { | ||
return new Response(JSON.stringify({ | ||
string: "a constant string", | ||
hello: process.env.ENV_VAR_USED_IN_MIDDLEWARE, | ||
customPackage: customPackage(), | ||
}), { | ||
headers: { | ||
'Content-Type': 'application/json' | ||
} | ||
}) | ||
} | ||
`, | ||
}, | ||
dependencies: {}, | ||
}) | ||
}) | ||
afterAll(() => next.destroy()) | ||
|
||
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?.['/api']?.env | ||
|
||
expect(envVars).toHaveLength(2) | ||
expect(envVars).toContain('ENV_VAR_USED_IN_MIDDLEWARE') | ||
expect(envVars).toContain('MY_CUSTOM_PACKAGE_ENV_VAR') | ||
}) | ||
|
||
it('uses the environment variables', async () => { | ||
const html = await renderViaHTTP(next.url, '/api') | ||
expect(html).toContain( | ||
JSON.stringify({ | ||
string: 'a constant string', | ||
hello: 'env-var-used-in-middleware', | ||
customPackage: 'my-custom-package-env-var', | ||
}) | ||
) | ||
}) | ||
}) |