From 7c103fac7d96f7ebadf03620044f3b2c02c4df48 Mon Sep 17 00:00:00 2001 From: Naoyuki Kanezawa Date: Fri, 18 Feb 2022 15:39:30 +0700 Subject: [PATCH] fix process polyfill on middleware (#34426) Fixes the problem that global `process` variable has only the `env` field. Also fixed the issue that the `env` field is empty when the `process` module is used as the value of the variable (which happens when the module is contained in a dependency of application). ## Bug - [ ] Related issues linked using `fixes #number` - [x] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` --- .../webpack/loaders/next-middleware-loader.ts | 7 ++++++ packages/next/server/web/sandbox/context.ts | 1 + packages/next/server/web/sandbox/polyfills.ts | 3 ++- packages/next/types/misc.d.ts | 5 ++++ .../core/pages/global/_middleware.js | 12 ++++++++++ .../middleware/core/test/index.test.js | 24 +++++++++++++++++++ 6 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 test/integration/middleware/core/pages/global/_middleware.js diff --git a/packages/next/build/webpack/loaders/next-middleware-loader.ts b/packages/next/build/webpack/loaders/next-middleware-loader.ts index 3ccdc57c01f1563..3beab89b7f4a05a 100644 --- a/packages/next/build/webpack/loaders/next-middleware-loader.ts +++ b/packages/next/build/webpack/loaders/next-middleware-loader.ts @@ -12,6 +12,13 @@ export default function middlewareLoader(this: any) { return ` import { adapter } from 'next/dist/server/web/adapter' + // The condition is true when the "process" module is provided + if (process !== global.process) { + // prefer local process but global.process has correct "env" + process.env = global.process.env; + global.process = process; + } + var mod = require(${stringifiedPagePath}) var handler = mod.middleware || mod.default; diff --git a/packages/next/server/web/sandbox/context.ts b/packages/next/server/web/sandbox/context.ts index de3876ffae9480f..42f480bb6a31510 100644 --- a/packages/next/server/web/sandbox/context.ts +++ b/packages/next/server/web/sandbox/context.ts @@ -202,6 +202,7 @@ function createContext(options: { File, FormData, process: { + ...polyfills.process, env: buildEnvironmentVariablesFrom(options.env), }, ReadableStream: polyfills.ReadableStream, diff --git a/packages/next/server/web/sandbox/polyfills.ts b/packages/next/server/web/sandbox/polyfills.ts index 3b47e18af6cf36a..ce083474526504d 100644 --- a/packages/next/server/web/sandbox/polyfills.ts +++ b/packages/next/server/web/sandbox/polyfills.ts @@ -1,6 +1,7 @@ import { Crypto as WebCrypto } from 'next/dist/compiled/@peculiar/webcrypto' import { CryptoKey } from 'next/dist/compiled/@peculiar/webcrypto' import { v4 as uuid } from 'next/dist/compiled/uuid' +import processPolyfill from 'next/dist/compiled/process' import { ReadableStream } from './readable-stream' import crypto from 'crypto' @@ -13,7 +14,7 @@ export function btoa(str: string) { return Buffer.from(str, 'binary').toString('base64') } -export { CryptoKey, ReadableStream } +export { CryptoKey, ReadableStream, processPolyfill as process } export class Crypto extends WebCrypto { // @ts-ignore Remove once types are updated and we deprecate node 12 diff --git a/packages/next/types/misc.d.ts b/packages/next/types/misc.d.ts index 555d3ad83d6e763..cbbc83ee852e354 100644 --- a/packages/next/types/misc.d.ts +++ b/packages/next/types/misc.d.ts @@ -331,6 +331,11 @@ declare module 'next/dist/compiled/comment-json' { export = m } +declare module 'next/dist/compiled/process' { + import m from 'process' + export = m +} + declare module 'pnp-webpack-plugin' { import webpack from 'webpack4' diff --git a/test/integration/middleware/core/pages/global/_middleware.js b/test/integration/middleware/core/pages/global/_middleware.js new file mode 100644 index 000000000000000..7e3020009875aa8 --- /dev/null +++ b/test/integration/middleware/core/pages/global/_middleware.js @@ -0,0 +1,12 @@ +import { NextResponse } from 'next/server' + +export async function middleware(request, ev) { + console.log(process.env.MIDDLEWARE_TEST) + + return NextResponse.json({ + process: { + env: process.env, + nextTick: typeof process.nextTick, + }, + }) +} diff --git a/test/integration/middleware/core/test/index.test.js b/test/integration/middleware/core/test/index.test.js index 805cf48fd3954c4..6cc789bc76d9664 100644 --- a/test/integration/middleware/core/test/index.test.js +++ b/test/integration/middleware/core/test/index.test.js @@ -108,6 +108,30 @@ describe('Middleware base tests', () => { } }) }) + + describe('global', () => { + beforeAll(async () => { + context.appPort = await findPort() + context.app = await launchApp(context.appDir, context.appPort, { + env: { + MIDDLEWARE_TEST: 'asdf', + }, + }) + }) + + it('should contains process polyfill', async () => { + const res = await fetchViaHTTP(context.appPort, `/global`) + const json = await res.json() + expect(json).toEqual({ + process: { + env: { + MIDDLEWARE_TEST: 'asdf', + }, + nextTick: 'function', + }, + }) + }) + }) }) function urlTests(_log, locale = '') {