diff --git a/packages/next/build/webpack/loaders/next-edge-function-loader.ts b/packages/next/build/webpack/loaders/next-edge-function-loader.ts index e66d06f270da2..fb382d50ac03b 100644 --- a/packages/next/build/webpack/loaders/next-edge-function-loader.ts +++ b/packages/next/build/webpack/loaders/next-edge-function-loader.ts @@ -16,14 +16,9 @@ export default function middlewareLoader(this: any) { } return ` - import { adapter } from 'next/dist/server/web/adapter' + import { adapter, enhanceGlobals } 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; - } + enhanceGlobals() var mod = require(${stringifiedPagePath}) var handler = mod.middleware || mod.default; diff --git a/packages/next/build/webpack/loaders/next-middleware-loader.ts b/packages/next/build/webpack/loaders/next-middleware-loader.ts index 5acb878bcf768..d6f0b2389c1f5 100644 --- a/packages/next/build/webpack/loaders/next-middleware-loader.ts +++ b/packages/next/build/webpack/loaders/next-middleware-loader.ts @@ -27,14 +27,9 @@ export default function middlewareLoader(this: any) { } return ` - import { adapter, blockUnallowedResponse } from 'next/dist/server/web/adapter' + import { adapter, blockUnallowedResponse, enhanceGlobals } 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; - } + enhanceGlobals() var mod = require(${stringifiedPagePath}) var handler = mod.middleware || mod.default; diff --git a/packages/next/build/webpack/plugins/middleware-plugin.ts b/packages/next/build/webpack/plugins/middleware-plugin.ts index 56f672f019230..eedd8d31b1c34 100644 --- a/packages/next/build/webpack/plugins/middleware-plugin.ts +++ b/packages/next/build/webpack/plugins/middleware-plugin.ts @@ -109,7 +109,7 @@ export async function handleWebpackExtenalForEdgeRuntime({ contextInfo: any }) { if (contextInfo.issuerLayer === 'middleware' && isNodeJsModule(request)) { - return `root __import_unsupported('${request}')` + return `root globalThis.__import_unsupported('${request}')` } } diff --git a/packages/next/server/dev/next-dev-server.ts b/packages/next/server/dev/next-dev-server.ts index 9aa929b1285e8..f190a610ec411 100644 --- a/packages/next/server/dev/next-dev-server.ts +++ b/packages/next/server/dev/next-dev-server.ts @@ -797,7 +797,7 @@ export default class DevServer extends Server { const frames = parseStack(err.stack!) const frame = frames.find( ({ file }) => - !file?.startsWith('eval') && !file?.includes('sandbox/context') + !file?.startsWith('eval') && !file?.includes('web/adapter') )! if (frame.lineNumber && frame?.file) { diff --git a/packages/next/server/web/adapter.ts b/packages/next/server/web/adapter.ts index c92afe3b29c03..b73ec6628bd25 100644 --- a/packages/next/server/web/adapter.ts +++ b/packages/next/server/web/adapter.ts @@ -162,6 +162,50 @@ export function blockUnallowedResponse( }) } +export function enhanceGlobals() { + // 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 + } + + // to allow building code that import but does not use node.js modules, + // webpack will expect this function to exist in global scope + Object.defineProperty(globalThis, '__import_unsupported', { + value: __import_unsupported, + enumerable: false, + configurable: false, + }) +} + +function __import_unsupported(moduleName: string) { + const proxy: any = new Proxy(function () {}, { + get(_obj, prop) { + if (prop === 'then') { + return {} + } + throw new Error(getUnsupportedModuleErrorMessage(moduleName)) + }, + construct() { + throw new Error(getUnsupportedModuleErrorMessage(moduleName)) + }, + apply(_target, _this, args) { + if (typeof args[0] === 'function') { + return args[0](proxy) + } + throw new Error(getUnsupportedModuleErrorMessage(moduleName)) + }, + }) + return new Proxy({}, { get: () => proxy }) +} + +function getUnsupportedModuleErrorMessage(module: string) { + // warning: if you change these messages, you must adjust how react-dev-overlay's middleware detects modules not found + return `The edge runtime does not support Node.js '${module}' module. +Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime` +} + class NextRequestHint extends NextRequest { sourcePage: string diff --git a/packages/next/server/web/sandbox/context.ts b/packages/next/server/web/sandbox/context.ts index 23f663b270b2d..f166fe7a3f96e 100644 --- a/packages/next/server/web/sandbox/context.ts +++ b/packages/next/server/web/sandbox/context.ts @@ -132,29 +132,6 @@ async function createModuleContext(options: ModuleContextOptions) { return fn() } - context.__import_unsupported = function __import_unsupported( - moduleName: string - ) { - const proxy: any = new Proxy(function () {}, { - get(_obj, prop) { - if (prop === 'then') { - return {} - } - throw new Error(getUnsupportedModuleErrorMessage(moduleName)) - }, - construct() { - throw new Error(getUnsupportedModuleErrorMessage(moduleName)) - }, - apply(_target, _this, args) { - if (args[0] instanceof Function) { - return args[0](proxy) - } - throw new Error(getUnsupportedModuleErrorMessage(moduleName)) - }, - }) - return new Proxy({}, { get: () => proxy }) - } - context.__next_webassembly_compile__ = function __next_webassembly_compile__(fn: Function) { const key = fn.toString() @@ -367,9 +344,3 @@ function decorateUnhandledError(error: any) { decorateServerError(error, 'edge-server') } } - -function getUnsupportedModuleErrorMessage(module: string) { - // warning: if you change these messages, you must adjust how react-dev-overlay's middleware detects modules not found - return `The edge runtime does not support Node.js '${module}' module. -Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime` -}