You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			276 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
		
		
			
		
	
	
			276 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
| 
											9 months ago
										 | "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"); | ||
|  | const _normalizepathsep = require("../shared/lib/page-path/normalize-path-sep"); | ||
|  | 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}`); | ||
|  | const nodeModulesRegex = /node_modules[/\\].*\.[mc]?js$/; | ||
|  | function isResourceInPackages(resource, packageNames, packageDirMapping) { | ||
|  |     if (!packageNames) return false; | ||
|  |     return 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, optOutBundlingPackages, 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; | ||
|  |     const preferEsmOptions = esmExternals && isEsmRequested && // For package that marked as externals that should be not bundled,
 | ||
|  |     // we don't resolve them as ESM since it could be resolved as async module,
 | ||
|  |     // such as `import(external package)` in the bundle, valued as a `Promise`.
 | ||
|  |     !optOutBundlingPackages.some((optOut)=>request.startsWith(optOut)) ? [ | ||
|  |         true, | ||
|  |         false | ||
|  |     ] : [ | ||
|  |         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, optOutBundlingPackages, optOutBundlingPackageRegex, dir }) { | ||
|  |     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-server-reference$)/; | ||
|  |             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 ${(0, _normalizepathsep.normalizePathSep)(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.
 | ||
|  |         // Make sure @vercel/og is loaded as ESM for Node.js runtime
 | ||
|  |         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 ? (0, _normalizepathsep.normalizePathSep)(_path.default.join(context, request)) : 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, optOutBundlingPackages, 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 && !isLocal) { | ||
|  |             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", isEsmRequested, optOutBundlingPackages, getResolve, isLocal ? resolveNextExternal : undefined); | ||
|  |                 if (pkgRes.res) { | ||
|  |                     resolvedExternalPackageDirs.set(pkg, _path.default.dirname(pkgRes.res)); | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |         const shouldBeBundled = isResourceInPackages(res, config.transpilePackages, resolvedExternalPackageDirs) || isEsm && isAppLayer || !isAppLayer && config.experimental.bundlePagesExternals; | ||
|  |         if (nodeModulesRegex.test(res)) { | ||
|  |             if ((0, _worker.isWebpackServerLayer)(layer)) { | ||
|  |                 if (!optOutBundlingPackageRegex.test(res)) { | ||
|  |                     return; // Bundle for server layer
 | ||
|  |                 } | ||
|  |                 return `${externalType} ${request}` // Externalize if opted out
 | ||
|  |                 ; | ||
|  |             } | ||
|  |             if (!shouldBeBundled || optOutBundlingPackageRegex.test(res)) { | ||
|  |                 return `${externalType} ${request}` // Externalize if not bundled or opted out
 | ||
|  |                 ; | ||
|  |             } | ||
|  |         } | ||
|  |     // if here, we default to bundling the file
 | ||
|  |     }; | ||
|  | } | ||
|  | 
 | ||
|  | //# sourceMappingURL=handle-externals.js.map
 |