securityos/node_modules/next/dist/build/handle-externals.js

281 lines
14 KiB
JavaScript

"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