"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); 0 && (module.exports = { isResourceInPackages: null, resolveExternal: null, makeExternalHandler: null }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { isResourceInPackages: function() { return isResourceInPackages; }, resolveExternal: function() { return resolveExternal; }, makeExternalHandler: function() { return makeExternalHandler; } }); const _constants = require("../lib/constants"); const _requirehook = require("../server/require-hook"); const _constants1 = require("../shared/lib/constants"); const _path = /*#__PURE__*/ _interop_require_default(require("../shared/lib/isomorphic/path")); const _webpackconfig = require("./webpack-config"); const _worker = require("./worker"); function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const reactPackagesRegex = /^(react|react-dom|react-server-dom-webpack)($|\/)/; const pathSeparators = "[/\\\\]"; const optionalEsmPart = `((${pathSeparators}esm)?${pathSeparators})`; const externalFileEnd = "(\\.external(\\.js)?)$"; const nextDist = `next${pathSeparators}dist`; const externalPattern = new RegExp(`${nextDist}${optionalEsmPart}.*${externalFileEnd}`); function isResourceInPackages(resource, packageNames, packageDirMapping) { return packageNames == null ? void 0 : packageNames.some((p)=>packageDirMapping && packageDirMapping.has(p) ? resource.startsWith(packageDirMapping.get(p) + _path.default.sep) : resource.includes(_path.default.sep + _path.default.join("node_modules", p.replace(/\//g, _path.default.sep)) + _path.default.sep)); } async function resolveExternal(dir, esmExternalsConfig, context, request, isEsmRequested, hasAppDir, getResolve, isLocalCallback, baseResolveCheck = true, esmResolveOptions = _webpackconfig.NODE_ESM_RESOLVE_OPTIONS, nodeResolveOptions = _webpackconfig.NODE_RESOLVE_OPTIONS, baseEsmResolveOptions = _webpackconfig.NODE_BASE_ESM_RESOLVE_OPTIONS, baseResolveOptions = _webpackconfig.NODE_BASE_RESOLVE_OPTIONS) { const esmExternals = !!esmExternalsConfig; const looseEsmExternals = esmExternalsConfig === "loose"; let res = null; let isEsm = false; let preferEsmOptions = esmExternals && isEsmRequested ? [ true, false ] : [ false ]; // Disable esm resolving for app/ and pages/ so for esm package using under pages/ // won't load react through esm loader if (hasAppDir) { preferEsmOptions = [ false ]; } for (const preferEsm of preferEsmOptions){ const resolve = getResolve(preferEsm ? esmResolveOptions : nodeResolveOptions); // Resolve the import with the webpack provided context, this // ensures we're resolving the correct version when multiple // exist. try { [res, isEsm] = await resolve(context, request); } catch (err) { res = null; } if (!res) { continue; } // ESM externals can only be imported (and not required). // Make an exception in loose mode. if (!isEsmRequested && isEsm && !looseEsmExternals) { continue; } if (isLocalCallback) { return { localRes: isLocalCallback(res) }; } // Bundled Node.js code is relocated without its node_modules tree. // This means we need to make sure its request resolves to the same // package that'll be available at runtime. If it's not identical, // we need to bundle the code (even if it _should_ be external). if (baseResolveCheck) { let baseRes; let baseIsEsm; try { const baseResolve = getResolve(isEsm ? baseEsmResolveOptions : baseResolveOptions); [baseRes, baseIsEsm] = await baseResolve(dir, request); } catch (err) { baseRes = null; baseIsEsm = false; } // Same as above: if the package, when required from the root, // would be different from what the real resolution would use, we // cannot externalize it. // if request is pointing to a symlink it could point to the the same file, // the resolver will resolve symlinks so this is handled if (baseRes !== res || isEsm !== baseIsEsm) { res = null; continue; } } break; } return { res, isEsm }; } function makeExternalHandler({ config, optOutBundlingPackageRegex, dir, hasAppDir }) { var _config_experimental; let resolvedExternalPackageDirs; const looseEsmExternals = ((_config_experimental = config.experimental) == null ? void 0 : _config_experimental.esmExternals) === "loose"; return async function handleExternals(context, request, dependencyType, layer, getResolve) { // We need to externalize internal requests for files intended to // not be bundled. const isLocal = request.startsWith(".") || // Always check for unix-style path, as webpack sometimes // normalizes as posix. _path.default.posix.isAbsolute(request) || // When on Windows, we also want to check for Windows-specific // absolute paths. process.platform === "win32" && _path.default.win32.isAbsolute(request); // make sure import "next" shows a warning when imported // in pages/components if (request === "next") { return `commonjs next/dist/lib/import-next-warning`; } const isAppLayer = (0, _worker.isWebpackAppLayer)(layer); // Relative requires don't need custom resolution, because they // are relative to requests we've already resolved here. // Absolute requires (require('/foo')) are extremely uncommon, but // also have no need for customization as they're already resolved. if (!isLocal) { if (/^(?:next$)/.test(request)) { return `commonjs ${request}`; } if (reactPackagesRegex.test(request) && !isAppLayer) { return `commonjs ${request}`; } const notExternalModules = /^(?:private-next-pages\/|next\/(?:dist\/pages\/|(?:app|document|link|image|legacy\/image|constants|dynamic|script|navigation|headers|router)$)|string-hash|private-next-rsc-action-validate|private-next-rsc-action-client-wrapper|private-next-rsc-action-proxy$)/; if (notExternalModules.test(request)) { return; } } // @swc/helpers should not be external as it would // require hoisting the package which we can't rely on if (request.includes("@swc/helpers")) { return; } // BARREL_OPTIMIZATION_PREFIX is a special marker that tells Next.js to // optimize the import by removing unused exports. This has to be compiled. if (request.startsWith(_constants1.BARREL_OPTIMIZATION_PREFIX)) { return; } // When in esm externals mode, and using import, we resolve with // ESM resolving options. // Also disable esm request when appDir is enabled const isEsmRequested = dependencyType === "esm"; /** * @param localRes the full path to the file * @returns the externalized path * @description returns an externalized path if the file is a Next.js file and ends with either `.shared-runtime.js` or `.external.js` * This is used to ensure that files used across the rendering runtime(s) and the user code are one and the same. The logic in this function * will rewrite the require to the correct bundle location depending on the layer at which the file is being used. */ const resolveNextExternal = (localRes)=>{ const isExternal = externalPattern.test(localRes); // if the file ends with .external, we need to make it a commonjs require in all cases // this is used mainly to share the async local storage across the routing, rendering and user layers. if (isExternal) { // it's important we return the path that starts with `next/dist/` here instead of the absolute path // otherwise NFT will get tripped up return `commonjs ${localRes.replace(/.*?next[/\\]dist/, "next/dist")}`; } }; // Don't bundle @vercel/og nodejs bundle for nodejs runtime. // TODO-APP: bundle route.js with different layer that externals common node_module deps. if ((0, _worker.isWebpackServerLayer)(layer) && request === "next/dist/compiled/@vercel/og/index.node.js") { return `module ${request}`; } // Specific Next.js imports that should remain external // TODO-APP: Investigate if we can remove this. if (request.startsWith("next/dist/")) { // Non external that needs to be transpiled // Image loader needs to be transpiled if (/^next[\\/]dist[\\/]shared[\\/]lib[\\/]image-loader/.test(request)) { return; } if (/^next[\\/]dist[\\/]compiled[\\/]next-server/.test(request)) { return `commonjs ${request}`; } if (/^next[\\/]dist[\\/]shared[\\/](?!lib[\\/]router[\\/]router)/.test(request) || /^next[\\/]dist[\\/]compiled[\\/].*\.c?js$/.test(request)) { return `commonjs ${request}`; } if (/^next[\\/]dist[\\/]esm[\\/]shared[\\/](?!lib[\\/]router[\\/]router)/.test(request) || /^next[\\/]dist[\\/]compiled[\\/].*\.mjs$/.test(request)) { return `module ${request}`; } return resolveNextExternal(request); } // Early return if the request needs to be bundled, such as in the client layer. // Treat react packages and next internals as external for SSR layer, // also map react to builtin ones with require-hook. if (layer === _constants.WEBPACK_LAYERS.serverSideRendering) { const isRelative = request.startsWith("."); const fullRequest = isRelative ? _path.default.join(context, request).replace(/\\/g, "/") : request; return resolveNextExternal(fullRequest); } // TODO-APP: Let's avoid this resolve call as much as possible, and eventually get rid of it. const resolveResult = await resolveExternal(dir, config.experimental.esmExternals, context, request, isEsmRequested, hasAppDir, getResolve, isLocal ? resolveNextExternal : undefined); if ("localRes" in resolveResult) { return resolveResult.localRes; } // Forcedly resolve the styled-jsx installed by next.js, // since `resolveExternal` cannot find the styled-jsx dep with pnpm if (request === "styled-jsx/style") { resolveResult.res = _requirehook.defaultOverrides["styled-jsx/style"]; } const { res, isEsm } = resolveResult; // If the request cannot be resolved we need to have // webpack "bundle" it so it surfaces the not found error. if (!res) { return; } // ESM externals can only be imported (and not required). // Make an exception in loose mode. if (!isEsmRequested && isEsm && !looseEsmExternals) { throw new Error(`ESM packages (${request}) need to be imported. Use 'import' to reference the package instead. https://nextjs.org/docs/messages/import-esm-externals`); } const externalType = isEsm ? "module" : "commonjs"; // Default pages have to be transpiled if (// This is the @babel/plugin-transform-runtime "helpers: true" option /node_modules[/\\]@babel[/\\]runtime[/\\]/.test(res)) { return; } // Webpack itself has to be compiled because it doesn't always use module relative paths if (/node_modules[/\\]webpack/.test(res) || /node_modules[/\\]css-loader/.test(res)) { return; } // If a package should be transpiled by Next.js, we skip making it external. // It doesn't matter what the extension is, as we'll transpile it anyway. if (config.transpilePackages && !resolvedExternalPackageDirs) { resolvedExternalPackageDirs = new Map(); // We need to resolve all the external package dirs initially. for (const pkg of config.transpilePackages){ const pkgRes = await resolveExternal(dir, config.experimental.esmExternals, context, pkg + "/package.json", hasAppDir, isEsmRequested, getResolve, isLocal ? resolveNextExternal : undefined); if (pkgRes.res) { resolvedExternalPackageDirs.set(pkg, _path.default.dirname(pkgRes.res)); } } } // If a package is included in `transpilePackages`, we don't want to make it external. // And also, if that resource is an ES module, we bundle it too because we can't // rely on the require hook to alias `react` to our precompiled version. const shouldBeBundled = isResourceInPackages(res, config.transpilePackages, resolvedExternalPackageDirs) || isEsm && isAppLayer || !isAppLayer && config.experimental.bundlePagesExternals; if (/node_modules[/\\].*\.[mc]?js$/.test(res)) { if ((0, _worker.isWebpackServerLayer)(layer)) { // All packages should be bundled for the server layer if they're not opted out. // This option takes priority over the transpilePackages option. if (optOutBundlingPackageRegex.test(res)) { return `${externalType} ${request}`; } return; } if (shouldBeBundled) return; // Anything else that is standard JavaScript within `node_modules` // can be externalized. return `${externalType} ${request}`; } if (shouldBeBundled) return; // Default behavior: bundle the code! }; } //# sourceMappingURL=handle-externals.js.map