next
Version:
The React Framework
1,105 lines • 74 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.attachReactRefresh = attachReactRefresh;
exports.resolveExternal = resolveExternal;
exports.default = getBaseWebpackConfig;
exports.nextImageLoaderRegex = exports.NODE_BASE_ESM_RESOLVE_OPTIONS = exports.NODE_ESM_RESOLVE_OPTIONS = exports.NODE_BASE_RESOLVE_OPTIONS = exports.NODE_RESOLVE_OPTIONS = void 0;
var _reactRefreshWebpackPlugin = _interopRequireDefault(require("@next/react-refresh-utils/ReactRefreshWebpackPlugin"));
var _chalk = _interopRequireDefault(require("chalk"));
var _crypto = _interopRequireDefault(require("crypto"));
var _fs = require("fs");
var _querystring = require("querystring");
var _codeFrame = require("next/dist/compiled/babel/code-frame");
var _semver = _interopRequireDefault(require("next/dist/compiled/semver"));
var _webpack = require("next/dist/compiled/webpack/webpack");
var _path = _interopRequireWildcard(require("path"));
var _escapeStringRegexp = _interopRequireDefault(require("next/dist/compiled/escape-string-regexp"));
var _constants = require("../lib/constants");
var _fileExists = require("../lib/file-exists");
var _getPackageVersion = require("../lib/get-package-version");
var _getTypeScriptConfiguration = require("../lib/typescript/getTypeScriptConfiguration");
var _constants1 = require("../shared/lib/constants");
var _utils = require("../shared/lib/utils");
var _entries = require("./entries");
var Log = _interopRequireWildcard(require("./output/log"));
var _config = require("./webpack/config");
var _overrideCssConfiguration = require("./webpack/config/blocks/css/overrideCssConfiguration");
var _middlewarePlugin = _interopRequireDefault(require("./webpack/plugins/middleware-plugin"));
var _buildManifestPlugin = _interopRequireDefault(require("./webpack/plugins/build-manifest-plugin"));
var _jsconfigPathsPlugin = require("./webpack/plugins/jsconfig-paths-plugin");
var _nextDropClientPagePlugin = require("./webpack/plugins/next-drop-client-page-plugin");
var _nextTraceEntrypointsPlugin = require("./webpack/plugins/next-trace-entrypoints-plugin");
var _nextjsSsrImport = _interopRequireDefault(require("./webpack/plugins/nextjs-ssr-import"));
var _pagesManifestPlugin = _interopRequireDefault(require("./webpack/plugins/pages-manifest-plugin"));
var _profilingPlugin = require("./webpack/plugins/profiling-plugin");
var _reactLoadablePlugin = require("./webpack/plugins/react-loadable-plugin");
var _serverlessPlugin = require("./webpack/plugins/serverless-plugin");
var _wellknownErrorsPlugin = require("./webpack/plugins/wellknown-errors-plugin");
var _css = require("./webpack/config/blocks/css");
var _copyFilePlugin = require("./webpack/plugins/copy-file-plugin");
var _flightManifestPlugin = require("./webpack/plugins/flight-manifest-plugin");
var _telemetryPlugin = require("./webpack/plugins/telemetry-plugin");
var _isError = _interopRequireDefault(require("../lib/is-error"));
var _utils1 = require("./utils");
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _interopRequireWildcard(obj) {
if (obj && obj.__esModule) {
return obj;
} else {
var newObj = {
};
if (obj != null) {
for(var key in obj){
if (Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {
};
if (desc.get || desc.set) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
}
newObj.default = obj;
return newObj;
}
}
const devtoolRevertWarning = (0, _utils).execOnce((devtool)=>{
console.warn(_chalk.default.yellow.bold('Warning: ') + _chalk.default.bold(`Reverting webpack devtool to '${devtool}'.\n`) + 'Changing the webpack devtool in development mode will cause severe performance regressions.\n' + 'Read more: https://nextjs.org/docs/messages/improper-devtool');
});
let loggedSwcDisabled = false;
function parseJsonFile(filePath) {
const JSON5 = require('next/dist/compiled/json5');
const contents = (0, _fs).readFileSync(filePath, 'utf8');
// Special case an empty file
if (contents.trim() === '') {
return {
};
}
try {
return JSON5.parse(contents);
} catch (err) {
if (!(0, _isError).default(err)) throw err;
const codeFrame = (0, _codeFrame).codeFrameColumns(String(contents), {
start: {
line: err.lineNumber || 0,
column: err.columnNumber || 0
}
}, {
message: err.message,
highlightCode: true
});
throw new Error(`Failed to parse "${filePath}":\n${codeFrame}`);
}
}
function getOptimizedAliases() {
const stubWindowFetch = _path.default.join(__dirname, 'polyfills', 'fetch', 'index.js');
const stubObjectAssign = _path.default.join(__dirname, 'polyfills', 'object-assign.js');
const shimAssign = _path.default.join(__dirname, 'polyfills', 'object.assign');
return Object.assign({
}, {
unfetch$: stubWindowFetch,
'isomorphic-unfetch$': stubWindowFetch,
'whatwg-fetch$': _path.default.join(__dirname, 'polyfills', 'fetch', 'whatwg-fetch.js')
}, {
'object-assign$': stubObjectAssign,
// Stub Package: object.assign
'object.assign/auto': _path.default.join(shimAssign, 'auto.js'),
'object.assign/implementation': _path.default.join(shimAssign, 'implementation.js'),
'object.assign$': _path.default.join(shimAssign, 'index.js'),
'object.assign/polyfill': _path.default.join(shimAssign, 'polyfill.js'),
'object.assign/shim': _path.default.join(shimAssign, 'shim.js'),
// Replace: full URL polyfill with platform-based polyfill
url: require.resolve('next/dist/compiled/native-url')
});
}
function attachReactRefresh(webpackConfig, targetLoader) {
var ref;
let injections = 0;
const reactRefreshLoaderName = '@next/react-refresh-utils/loader';
const reactRefreshLoader = require.resolve(reactRefreshLoaderName);
(ref = webpackConfig.module) === null || ref === void 0 ? void 0 : ref.rules.forEach((rule)=>{
const curr = rule.use;
// When the user has configured `defaultLoaders.babel` for a input file:
if (curr === targetLoader) {
++injections;
rule.use = [
reactRefreshLoader,
curr
];
} else if (Array.isArray(curr) && curr.some((r)=>r === targetLoader
) && // Check if loader already exists:
!curr.some((r)=>r === reactRefreshLoader || r === reactRefreshLoaderName
)) {
++injections;
const idx = curr.findIndex((r)=>r === targetLoader
);
// Clone to not mutate user input
rule.use = [
...curr
];
// inject / input: [other, babel] output: [other, refresh, babel]:
rule.use.splice(idx, 0, reactRefreshLoader);
}
});
if (injections) {
Log.info(`automatically enabled Fast Refresh for ${injections} custom loader${injections > 1 ? 's' : ''}`);
}
}
const NODE_RESOLVE_OPTIONS = {
dependencyType: 'commonjs',
modules: [
'node_modules'
],
fallback: false,
exportsFields: [
'exports'
],
importsFields: [
'imports'
],
conditionNames: [
'node',
'require'
],
descriptionFiles: [
'package.json'
],
extensions: [
'.js',
'.json',
'.node'
],
enforceExtensions: false,
symlinks: true,
mainFields: [
'main'
],
mainFiles: [
'index'
],
roots: [],
fullySpecified: false,
preferRelative: false,
preferAbsolute: false,
restrictions: []
};
exports.NODE_RESOLVE_OPTIONS = NODE_RESOLVE_OPTIONS;
const NODE_BASE_RESOLVE_OPTIONS = {
...NODE_RESOLVE_OPTIONS,
alias: false
};
exports.NODE_BASE_RESOLVE_OPTIONS = NODE_BASE_RESOLVE_OPTIONS;
const NODE_ESM_RESOLVE_OPTIONS = {
...NODE_RESOLVE_OPTIONS,
alias: false,
dependencyType: 'esm',
conditionNames: [
'node',
'import'
],
fullySpecified: true
};
exports.NODE_ESM_RESOLVE_OPTIONS = NODE_ESM_RESOLVE_OPTIONS;
const NODE_BASE_ESM_RESOLVE_OPTIONS = {
...NODE_ESM_RESOLVE_OPTIONS,
alias: false
};
exports.NODE_BASE_ESM_RESOLVE_OPTIONS = NODE_BASE_ESM_RESOLVE_OPTIONS;
let TSCONFIG_WARNED = false;
const nextImageLoaderRegex = /\.(png|jpg|jpeg|gif|webp|avif|ico|bmp|svg)$/i;
exports.nextImageLoaderRegex = nextImageLoaderRegex;
async function resolveExternal(appDir, esmExternalsConfig, context, request, isEsmRequested, getResolve, isLocalCallback, baseResolveCheck = true, esmResolveOptions = NODE_ESM_RESOLVE_OPTIONS, nodeResolveOptions = NODE_RESOLVE_OPTIONS, baseEsmResolveOptions = NODE_BASE_ESM_RESOLVE_OPTIONS, baseResolveOptions = NODE_BASE_RESOLVE_OPTIONS) {
const esmExternals = !!esmExternalsConfig;
const looseEsmExternals = esmExternalsConfig === 'loose';
let res = null;
let isEsm = false;
let preferEsmOptions = esmExternals && isEsmRequested ? [
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(appDir, 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
};
}
async function getBaseWebpackConfig(dir, { buildId , config , dev =false , isServer =false , webServerRuntime =false , pagesDir , target ='server' , reactProductionProfiling =false , entrypoints , rewrites , isDevFallback =false , runWebpackSpan }) {
var ref27, ref1, ref2, ref3, ref4, ref5, ref6;
const hasRewrites = rewrites.beforeFiles.length > 0 || rewrites.afterFiles.length > 0 || rewrites.fallback.length > 0;
const hasReactRefresh = dev && !isServer;
const reactDomVersion = await (0, _getPackageVersion).getPackageVersion({
cwd: dir,
name: 'react-dom'
});
const isReactExperimental = Boolean(reactDomVersion && /0\.0\.0-experimental/.test(reactDomVersion));
const hasReact18 = Boolean(reactDomVersion) && (_semver.default.gte(reactDomVersion, '18.0.0') || ((ref27 = _semver.default.coerce(reactDomVersion)) === null || ref27 === void 0 ? void 0 : ref27.version) === '18.0.0');
const hasReactPrerelease = Boolean(reactDomVersion) && _semver.default.prerelease(reactDomVersion) != null || isReactExperimental;
const hasReactRoot = config.experimental.reactRoot || hasReact18 || isReactExperimental;
if (config.experimental.reactRoot && !(hasReact18 || isReactExperimental)) {
// It's fine to only mention React 18 here as we don't recommend people to try experimental.
Log.warn('You have to use React 18 to use `experimental.reactRoot`.');
}
if (config.experimental.concurrentFeatures && !hasReactRoot) {
throw new Error('`experimental.concurrentFeatures` requires `experimental.reactRoot` to be enabled along with React 18.');
}
if (config.experimental.serverComponents && !config.experimental.concurrentFeatures) {
throw new Error('`experimental.concurrentFeatures` is required to be enabled along with `experimental.serverComponents`.');
}
const hasConcurrentFeatures = config.experimental.concurrentFeatures && hasReactRoot;
const hasServerComponents = hasConcurrentFeatures && !!config.experimental.serverComponents;
const targetWeb = webServerRuntime || !isServer;
// Only inform during one of the builds
if (!isServer) {
if (hasReactRoot) {
Log.info('Using the createRoot API for React');
}
if (hasReactPrerelease) {
Log.warn(`You are using an unsupported prerelease of 'react-dom' which may cause ` + `unexpected or broken application behavior. Continue at your own risk.`);
}
}
if (webServerRuntime) {
Log.info('Using the experimental web runtime.');
if (hasServerComponents) {
Log.info('You have experimental React Server Components enabled.');
}
}
const babelConfigFile = await [
'.babelrc',
'.babelrc.json',
'.babelrc.js',
'.babelrc.mjs',
'.babelrc.cjs',
'babel.config.js',
'babel.config.json',
'babel.config.mjs',
'babel.config.cjs',
].reduce(async (memo, filename)=>{
const configFilePath = _path.default.join(dir, filename);
return await memo || (await (0, _fileExists).fileExists(configFilePath) ? configFilePath : undefined);
}, Promise.resolve(undefined));
const distDir = _path.default.join(dir, config.distDir);
let useSWCLoader = !babelConfigFile;
if (!loggedSwcDisabled && !useSWCLoader && babelConfigFile) {
Log.warn(`Disabled SWC as replacement for Babel because of custom Babel configuration "${_path.default.relative(dir, babelConfigFile)}" https://nextjs.org/docs/messages/swc-disabled`);
loggedSwcDisabled = true;
}
const getBabelOrSwcLoader = (isMiddleware)=>{
return useSWCLoader ? {
loader: 'next-swc-loader',
options: {
isServer: isMiddleware || isServer,
pagesDir,
hasReactRefresh: !isMiddleware && hasReactRefresh
}
} : {
loader: require.resolve('./babel/loader/index'),
options: {
configFile: babelConfigFile,
isServer: isMiddleware ? true : isServer,
distDir,
pagesDir,
cwd: dir,
development: dev,
hasReactRefresh: isMiddleware ? false : hasReactRefresh,
hasJsxRuntime: true
}
};
};
const defaultLoaders = {
babel: getBabelOrSwcLoader(false)
};
const rawPageExtensions = hasServerComponents ? (0, _utils1).getRawPageExtensions(config.pageExtensions) : config.pageExtensions;
const serverComponentsRegex = new RegExp(`\\.server\\.(${rawPageExtensions.join('|')})$`);
const clientComponentsRegex = new RegExp(`\\.client\\.(${rawPageExtensions.join('|')})$`);
const babelIncludeRegexes = [
/next[\\/]dist[\\/]shared[\\/]lib/,
/next[\\/]dist[\\/]client/,
/next[\\/]dist[\\/]pages/,
/[\\/](strip-ansi|ansi-regex)[\\/]/,
];
// Support for NODE_PATH
const nodePathList = (process.env.NODE_PATH || '').split(process.platform === 'win32' ? ';' : ':').filter((p)=>!!p
);
const isServerless = target === 'serverless';
const isServerlessTrace = target === 'experimental-serverless-trace';
// Intentionally not using isTargetLikeServerless helper
const isLikeServerless = isServerless || isServerlessTrace;
const outputDir = isLikeServerless ? _constants1.SERVERLESS_DIRECTORY : _constants1.SERVER_DIRECTORY;
const outputPath = _path.default.join(distDir, isServer ? outputDir : '');
const totalPages = Object.keys(entrypoints).length;
const clientEntries = !isServer ? {
// Backwards compatibility
'main.js': [],
...dev ? {
[_constants1.CLIENT_STATIC_FILES_RUNTIME_REACT_REFRESH]: require.resolve(`@next/react-refresh-utils/runtime`),
[_constants1.CLIENT_STATIC_FILES_RUNTIME_AMP]: `./` + (0, _path).relative(dir, (0, _path).join(_constants.NEXT_PROJECT_ROOT_DIST_CLIENT, 'dev', 'amp-dev')).replace(/\\/g, '/')
} : {
},
[_constants1.CLIENT_STATIC_FILES_RUNTIME_MAIN]: `./` + _path.default.relative(dir, _path.default.join(_constants.NEXT_PROJECT_ROOT_DIST_CLIENT, dev ? `next-dev.js` : 'next.js')).replace(/\\/g, '/')
} : undefined;
let typeScriptPath;
try {
typeScriptPath = require.resolve('typescript', {
paths: [
dir
]
});
} catch (_) {
}
const tsConfigPath = _path.default.join(dir, config.typescript.tsconfigPath);
const useTypeScript = Boolean(typeScriptPath && await (0, _fileExists).fileExists(tsConfigPath));
let jsConfig;
// jsconfig is a subset of tsconfig
if (useTypeScript) {
if (config.typescript.tsconfigPath !== 'tsconfig.json' && TSCONFIG_WARNED === false) {
TSCONFIG_WARNED = true;
Log.info(`Using tsconfig file: ${config.typescript.tsconfigPath}`);
}
const ts = await Promise.resolve(require(typeScriptPath));
const tsConfig = await (0, _getTypeScriptConfiguration).getTypeScriptConfiguration(ts, tsConfigPath, true);
jsConfig = {
compilerOptions: tsConfig.options
};
}
const jsConfigPath = _path.default.join(dir, 'jsconfig.json');
if (!useTypeScript && await (0, _fileExists).fileExists(jsConfigPath)) {
jsConfig = parseJsonFile(jsConfigPath);
}
let resolvedBaseUrl;
if (jsConfig === null || jsConfig === void 0 ? void 0 : (ref1 = jsConfig.compilerOptions) === null || ref1 === void 0 ? void 0 : ref1.baseUrl) {
resolvedBaseUrl = _path.default.resolve(dir, jsConfig.compilerOptions.baseUrl);
}
function getReactProfilingInProduction() {
if (reactProductionProfiling) {
return {
'react-dom$': 'react-dom/profiling',
'scheduler/tracing': 'scheduler/tracing-profiling'
};
}
}
// tell webpack where to look for _app and _document
// using aliases to allow falling back to the default
// version when removed or not present
const clientResolveRewrites = require.resolve('../shared/lib/router/utils/resolve-rewrites');
const customAppAliases = {
};
const customErrorAlias = {
};
const customDocumentAliases = {
};
if (dev) {
customAppAliases[`${_constants.PAGES_DIR_ALIAS}/_app`] = [
...config.pageExtensions.reduce((prev, ext)=>{
prev.push(_path.default.join(pagesDir, `_app.${ext}`));
return prev;
}, []),
'next/dist/pages/_app.js',
];
customAppAliases[`${_constants.PAGES_DIR_ALIAS}/_error`] = [
...config.pageExtensions.reduce((prev, ext)=>{
prev.push(_path.default.join(pagesDir, `_error.${ext}`));
return prev;
}, []),
'next/dist/pages/_error.js',
];
customDocumentAliases[`${_constants.PAGES_DIR_ALIAS}/_document`] = [
...config.pageExtensions.reduce((prev, ext)=>{
prev.push(_path.default.join(pagesDir, `_document.${ext}`));
return prev;
}, []),
'next/dist/pages/_document.js',
];
}
const resolveConfig = {
// Disable .mjs for node_modules bundling
extensions: !targetWeb ? [
'.js',
'.mjs',
...useTypeScript ? [
'.tsx',
'.ts'
] : [],
'.jsx',
'.json',
'.wasm',
] : [
'.mjs',
'.js',
...useTypeScript ? [
'.tsx',
'.ts'
] : [],
'.jsx',
'.json',
'.wasm',
],
modules: [
'node_modules',
...nodePathList
],
alias: {
next: _constants.NEXT_PROJECT_ROOT,
...customAppAliases,
...customErrorAlias,
...customDocumentAliases,
[_constants.PAGES_DIR_ALIAS]: pagesDir,
[_constants.DOT_NEXT_ALIAS]: distDir,
...targetWeb ? getOptimizedAliases() : {
},
...getReactProfilingInProduction(),
...targetWeb ? {
[clientResolveRewrites]: hasRewrites ? clientResolveRewrites : false
} : {
}
},
...targetWeb ? {
// Full list of old polyfills is accessible here:
// https://github.com/webpack/webpack/blob/2a0536cf510768111a3a6dceeb14cb79b9f59273/lib/ModuleNotFoundError.js#L13-L42
fallback: {
assert: require.resolve('assert/'),
buffer: require.resolve('buffer/'),
constants: require.resolve('constants-browserify'),
crypto: require.resolve('crypto-browserify'),
domain: require.resolve('domain-browser'),
http: require.resolve('stream-http'),
https: require.resolve('https-browserify'),
os: require.resolve('os-browserify/browser'),
path: require.resolve('path-browserify'),
punycode: require.resolve('punycode'),
process: require.resolve('process/browser'),
// Handled in separate alias
querystring: require.resolve('querystring-es3'),
stream: require.resolve('stream-browserify'),
string_decoder: require.resolve('string_decoder'),
sys: require.resolve('util/'),
timers: require.resolve('timers-browserify'),
tty: require.resolve('tty-browserify'),
// Handled in separate alias
// url: require.resolve('url/'),
util: require.resolve('util/'),
vm: require.resolve('vm-browserify'),
zlib: require.resolve('browserify-zlib'),
events: require.resolve('events')
}
} : undefined,
mainFields: !targetWeb ? [
'main',
'module'
] : [
'browser',
'module',
'main'
],
plugins: []
};
const terserOptions = {
parse: {
ecma: 8
},
compress: {
ecma: 5,
warnings: false,
// The following two options are known to break valid JavaScript code
comparisons: false,
inline: 2
},
mangle: {
safari10: true
},
output: {
ecma: 5,
safari10: true,
comments: false,
// Fixes usage of Emoji and certain Regex
ascii_only: true
}
};
const isModuleCSS = (module)=>{
return(// mini-css-extract-plugin
module.type === `css/mini-extract` || // extract-css-chunks-webpack-plugin (old)
module.type === `css/extract-chunks` || // extract-css-chunks-webpack-plugin (new)
module.type === `css/extract-css-chunks`);
};
// Select appropriate SplitChunksPlugin config for this build
const splitChunksConfig = dev ? false : {
// Keep main and _app chunks unsplitted in webpack 5
// as we don't need a separate vendor chunk from that
// and all other chunk depend on them so there is no
// duplication that need to be pulled out.
chunks: (chunk)=>!/^(polyfills|main|pages\/_app)$/.test(chunk.name) && !_constants.MIDDLEWARE_ROUTE.test(chunk.name)
,
cacheGroups: {
framework: {
chunks: (chunk)=>{
var ref;
return !((ref = chunk.name) === null || ref === void 0 ? void 0 : ref.match(_constants.MIDDLEWARE_ROUTE));
},
name: 'framework',
// This regex ignores nested copies of framework libraries so they're
// bundled with their issuer.
// https://github.com/vercel/next.js/pull/9012
test: /(?<!node_modules.*)[\\/]node_modules[\\/](react|react-dom|scheduler|prop-types|use-subscription)[\\/]/,
priority: 40,
// Don't let webpack eliminate this chunk (prevents this chunk from
// becoming a part of the commons chunk)
enforce: true
},
lib: {
test (module) {
return module.size() > 160000 && /node_modules[/\\]/.test(module.nameForCondition() || '');
},
name (module) {
const hash = _crypto.default.createHash('sha1');
if (isModuleCSS(module)) {
module.updateHash(hash);
} else {
if (!module.libIdent) {
throw new Error(`Encountered unknown module type: ${module.type}. Please open an issue.`);
}
hash.update(module.libIdent({
context: dir
}));
}
return hash.digest('hex').substring(0, 8);
},
priority: 30,
minChunks: 1,
reuseExistingChunk: true
},
commons: {
name: 'commons',
minChunks: totalPages,
priority: 20
},
middleware: {
chunks: (chunk)=>{
var ref;
return (ref = chunk.name) === null || ref === void 0 ? void 0 : ref.match(_constants.MIDDLEWARE_ROUTE);
},
filename: 'server/middleware-chunks/[name].js',
minChunks: 2,
enforce: true
}
},
maxInitialRequests: 25,
minSize: 20000
};
const crossOrigin = config.crossOrigin;
const looseEsmExternals = ((ref2 = config.experimental) === null || ref2 === void 0 ? void 0 : ref2.esmExternals) === 'loose';
async function handleExternals(context, request, dependencyType, 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));
// 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$|react(?:$|\/))/.test(request)) {
return `commonjs ${request}`;
}
const notExternalModules = /^(?:private-next-pages\/|next\/(?:dist\/pages\/|(?:app|document|link|image|constants|dynamic)$)|string-hash$)/;
if (notExternalModules.test(request)) {
return;
}
}
// When in esm externals mode, and using import, we resolve with
// ESM resolving options.
const isEsmRequested = dependencyType === 'esm';
const isLocalCallback = (localRes)=>{
// Makes sure dist/shared and dist/server are not bundled
// we need to process shared `router/router` and `dynamic`,
// so that the DefinePlugin can inject process.env values
const isNextExternal = /next[/\\]dist[/\\](shared|server)[/\\](?!lib[/\\](router[/\\]router|dynamic))/.test(localRes);
if (isNextExternal) {
// Generate Next.js external import
const externalRequest = _path.default.posix.join('next', 'dist', _path.default.relative(// Root of Next.js package:
_path.default.join(__dirname, '..'), localRes)// Windows path normalization
.replace(/\\/g, '/'));
return `commonjs ${externalRequest}`;
} else {
// We don't want to retry local requests
// with other preferEsm options
return;
}
};
const resolveResult = await resolveExternal(dir, config.experimental.esmExternals, context, request, isEsmRequested, getResolve, isLocal ? isLocalCallback : undefined);
if ('localRes' in resolveResult) {
return resolveResult.localRes;
}
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';
if (res.match(/next[/\\]dist[/\\]shared[/\\](?!lib[/\\]router[/\\]router)/)) {
return `${externalType} ${request}`;
}
// Default pages have to be transpiled
if (res.match(/[/\\]next[/\\]dist[/\\]/) || // This is the @babel/plugin-transform-runtime "helpers: true" option
res.match(/node_modules[/\\]@babel[/\\]runtime[/\\]/)) {
return;
}
// Webpack itself has to be compiled because it doesn't always use module relative paths
if (res.match(/node_modules[/\\]webpack/) || res.match(/node_modules[/\\]css-loader/)) {
return;
}
// Anything else that is standard JavaScript within `node_modules`
// can be externalized.
if (/node_modules[/\\].*\.[mc]?js$/.test(res)) {
return `${externalType} ${request}`;
}
// Default behavior: bundle the code!
}
const emacsLockfilePattern = '**/.#*';
const codeCondition = {
test: /\.(tsx|ts|js|cjs|mjs|jsx)$/,
...config.experimental.externalDir ? {
} : {
include: [
dir,
...babelIncludeRegexes
]
},
exclude: (excludePath)=>{
if (babelIncludeRegexes.some((r)=>r.test(excludePath)
)) {
return false;
}
return /node_modules/.test(excludePath);
}
};
let webpackConfig = {
parallelism: Number(process.env.NEXT_WEBPACK_PARALLELISM) || undefined,
externals: targetWeb ? // bundles in case a user imported types and it wasn't removed
// TODO: should we warn/error for this instead?
[
'next',
...webServerRuntime ? [
{
etag: '{}',
chalk: '{}'
}
] : []
] : !isServerless ? [
({ context , request , dependencyType , getResolve })=>{
return handleExternals(context, request, dependencyType, (options)=>{
const resolveFunction = getResolve(options);
return (resolveContext, requestToResolve)=>{
return new Promise((resolve, reject)=>{
resolveFunction(resolveContext, requestToResolve, (err, result, resolveData)=>{
var ref;
if (err) return reject(err);
if (!result) return resolve([
null,
false
]);
const isEsm = /\.js$/i.test(result) ? (resolveData === null || resolveData === void 0 ? void 0 : (ref = resolveData.descriptionFileData) === null || ref === void 0 ? void 0 : ref.type) === 'module' : /\.mjs$/i.test(result);
resolve([
result,
isEsm
]);
});
});
};
});
},
] : [
// When the 'serverless' target is used all node_modules will be compiled into the output bundles
// So that the 'serverless' bundles have 0 runtime dependencies
'next/dist/compiled/@ampproject/toolbox-optimizer',
// Mark this as external if not enabled so it doesn't cause a
// webpack error from being missing
...config.experimental.optimizeCss ? [] : [
'critters'
],
],
optimization: {
// @ts-ignore: TODO remove ts-ignore when webpack 4 is removed
emitOnErrors: !dev,
checkWasmTypes: false,
nodeEnv: false,
...hasServerComponents ? {
// We have to use the names here instead of hashes to ensure the consistency between builds.
moduleIds: 'named'
} : {
},
splitChunks: isServer ? dev || webServerRuntime ? false : {
filename: '[name].js',
// allow to split entrypoints
chunks: ({ name })=>{
return !(name === null || name === void 0 ? void 0 : name.match(_constants.MIDDLEWARE_ROUTE));
},
// size of files is not so relevant for server build
// we want to prefer deduplication to load less code
minSize: 1000
} : splitChunksConfig,
runtimeChunk: isServer ? undefined : {
name: _constants1.CLIENT_STATIC_FILES_RUNTIME_WEBPACK
},
minimize: !dev && targetWeb,
minimizer: [
// Minify JavaScript
(compiler)=>{
// @ts-ignore No typings yet
const { TerserPlugin , } = require('./webpack/plugins/terser-webpack-plugin/src/index.js');
new TerserPlugin({
cacheDir: _path.default.join(distDir, 'cache', 'next-minifier'),
parallel: config.experimental.cpus,
swcMinify: config.swcMinify,
terserOptions
}).apply(compiler);
},
// Minify CSS
(compiler)=>{
const { CssMinimizerPlugin , } = require('./webpack/plugins/css-minimizer-plugin');
new CssMinimizerPlugin({
postcssOptions: {
map: {
// `inline: false` generates the source map in a separate file.
// Otherwise, the CSS file is needlessly large.
inline: false,
// `annotation: false` skips appending the `sourceMappingURL`
// to the end of the CSS file. Webpack already handles this.
annotation: false
}
}
}).apply(compiler);
},
]
},
context: dir,
// Kept as function to be backwards compatible
// @ts-ignore TODO webpack 5 typings needed
entry: async ()=>{
return {
...clientEntries ? clientEntries : {
},
...entrypoints
};
},
watchOptions: {
aggregateTimeout: 5,
ignored: [
'**/.git/**',
'**/node_modules/**',
'**/.next/**',
// can be removed after https://github.com/paulmillr/chokidar/issues/955 is released
emacsLockfilePattern,
]
},
output: {
// we must set publicPath to an empty value to override the default of
// auto which doesn't work in IE11
publicPath: `${config.assetPrefix || ''}/_next/`,
path: isServer && !dev && !webServerRuntime ? _path.default.join(outputPath, 'chunks') : outputPath,
// On the server we don't use hashes
filename: isServer ? !dev && !webServerRuntime ? `../[name].js` : `[name].js` : `static/chunks/${isDevFallback ? 'fallback/' : ''}[name]${dev ? '' : '-[contenthash]'}.js`,
library: targetWeb ? '_N_E' : undefined,
libraryTarget: targetWeb ? 'assign' : 'commonjs2',
hotUpdateChunkFilename: 'static/webpack/[id].[fullhash].hot-update.js',
hotUpdateMainFilename: 'static/webpack/[fullhash].[runtime].hot-update.json',
// This saves chunks with the name given via `import()`
chunkFilename: isServer ? '[name].js' : `static/chunks/${isDevFallback ? 'fallback/' : ''}${dev ? '[name]' : '[name].[contenthash]'}.js`,
strictModuleExceptionHandling: true,
crossOriginLoading: crossOrigin,
webassemblyModuleFilename: 'static/wasm/[modulehash].wasm',
hashFunction: 'xxhash64',
hashDigestLength: 16
},
performance: false,
resolve: resolveConfig,
resolveLoader: {
// The loaders Next.js provides
alias: [
'error-loader',
'next-swc-loader',
'next-client-pages-loader',
'next-image-loader',
'next-serverless-loader',
'next-style-loader',
'next-flight-client-loader',
'next-flight-server-loader',
'noop-loader',
'next-middleware-loader',
'next-middleware-ssr-loader',
].reduce((alias, loader)=>{
// using multiple aliases to replace `resolveLoader.modules`
alias[loader] = _path.default.join(__dirname, 'webpack', 'loaders', loader);
return alias;
}, {
}),
modules: [
'node_modules',
...nodePathList
],
plugins: []
},
module: {
rules: [
// TODO: FIXME: do NOT webpack 5 support with this
// x-ref: https://github.com/webpack/webpack/issues/11467
...!config.experimental.fullySpecified ? [
{
test: /\.m?js/,
resolve: {
fullySpecified: false
}
},
] : [],
...hasServerComponents && !isServer ? [
{
...codeCondition,
test: serverComponentsRegex,
use: {
loader: `next-flight-server-loader?${(0, _querystring).stringify({
client: 1,
pageExtensions: JSON.stringify(rawPageExtensions)
})}`
}
},
] : [],
...webServerRuntime && hasServerComponents ? [
{
...codeCondition,
test: serverComponentsRegex,
use: {
loader: `next-flight-server-loader?${(0, _querystring).stringify({
pageExtensions: JSON.stringify(rawPageExtensions)
})}`
}
},
{
...codeCondition,
test: clientComponentsRegex,
use: {
loader: 'next-flight-client-loader'
}
},
{
test: /next[\\/](dist[\\/]client[\\/])?(link|image)/,
use: {
loader: 'next-flight-client-loader'
}
},
] : [],
{
test: /\.(js|cjs|mjs)$/,
issuerLayer: 'api',
parser: {
// Switch back to normal URL handling
url: true
}
},
{
oneOf: [
{
...codeCondition,
issuerLayer: 'api',
parser: {
// Switch back to normal URL handling
url: true
},
use: defaultLoaders.babel
},
{
...codeCondition,
issuerLayer: 'middleware',
use: getBabelOrSwcLoader(true)
},
{
...codeCondition,
use: hasReactRefresh ? [
require.resolve('@next/react-refresh-utils/loader'),
defaultLoaders.babel,
] : defaultLoaders.babel
},
]
},
...!config.images.disableStaticImages ? [
{
test: nextImageLoaderRegex,
loader: 'next-image-loader',
issuer: {
not: _css.regexLikeCss
},
dependency: {
not: [
'url'
]
},
options: {
isServer,
isDev: dev,
basePath: config.basePath,
assetPrefix: config.assetPrefix
}
},
] : [],
].filter(Boolean)
},
plugins: [
hasReactRefresh && new _reactRefreshWebpackPlugin.default(_webpack.webpack),
// Makes sure `Buffer` and `process` are polyfilled in client and flight bundles (same behavior as webpack 4)
targetWeb && new _webpack.webpack.ProvidePlugin({
Buffer: [
require.resolve('buffer'),
'Buffer'
],
process: [
require.resolve('process')
]
}),
new _webpack.webpack.DefinePlugin({
...Object.keys(process.env).reduce((prev, key)=>{
if (key.startsWith('NEXT_PUBLIC_')) {
prev[`process.env.${key}`] = JSON.stringify(process.env[key]);
}
return prev;
}, {
}),
...Object.keys(config.env).reduce((acc, key)=>{
if (/^(?:NODE_.+)|^(?:__.+)$/i.test(key)) {
throw new Error(`The key "${key}" under "env" in ${config.configFileName} is not allowed. https://nextjs.org/docs/messages/env-key-not-allowed`);
}
return {
...acc,
[`process.env.${key}`]: JSON.stringify(config.env[key])
};
}, {
}),
// TODO: enforce `NODE_ENV` on `process.env`, and add a test:
'process.env.NODE_ENV': JSON.stringify(dev ? 'development' : 'production'),
'process.env.__NEXT_CROSS_ORIGIN': JSON.stringify(crossOrigin),
'process.browser': JSON.stringify(targetWeb),
'process.env.__NEXT_TEST_MODE': JSON.stringify(process.env.__NEXT_TEST_MODE),
// This is used in client/dev-error-overlay/hot-dev-client.js to replace the dist directory
...dev && !isServer ? {
'process.env.__NEXT_DIST_DIR': JSON.stringify(distDir)
} : {
},
'process.env.__NEXT_TRAILING_SLASH': JSON.stringify(config.trailingSlash),
'process.env.__NEXT_BUILD_INDICATOR': JSON.stringify(config.devIndicators.buildActivity),
'process.env.__NEXT_PLUGINS': JSON.stringify(config.experimental.plugins),
'process.env.__NEXT_STRICT_MODE': JSON.stringify(config.reactStrictMode),
'process.env.__NEXT_REACT_ROOT': JSON.stringify(hasReactRoot),
'process.env.__NEXT_CONCURRENT_FEATURES': JSON.stringify(hasConcurrentFeatures),
'process.env.__NEXT_RSC': JSON.stringify(hasServerComponents),
'process.env.__NEXT_OPTIMIZE_FONTS': JSON.stringify(config.optimizeFonts && !dev),
'process.env.__NEXT_OPTIMIZE_IMAGES': JSON.stringify(config.experimental.optimizeImages),
'process.env.__NEXT_OPTIMIZE_CSS': JSON.stringify(config.experimental.optimizeCss && !dev),
'process.env.__NEXT_SCROLL_RESTORATION': JSON.stringify(config.experimental.scrollRestoration),
'process.env.__NEXT_IMAGE_OPTS': JSON.stringify({
deviceSizes: config.images.deviceSizes,
imageSizes: config.images.imageSizes,
path: config.images.path,
loader: config.images.loader,
...dev ? {
// pass domains in development to allow validating on the client
domains: config.images.domains
} : {
}
}),
'process.env.__NEXT_ROUTER_BASEPATH': JSON.stringify(config.basePath),
'process.env.__NEXT_HAS_REWRITES': JSON.stringify(hasRewrites),
'process.env.__NEXT_I18N_SUPPORT': JSON.stringify(!!config.i18n),
'process.env.__NEXT_I18N_DOMAINS': JSON.stringify((ref3 = config.i18n) === null || ref3 === void 0 ? void 0 : ref3.domains),
'process.env.__NEXT_ANALYTICS_ID': JSON.stringify(config.analyticsId),
...isServer ? {
// Fix bad-actors in the npm ecosystem (e.g. `node-formidable`)
// This is typically found in unmaintained modules from the
// pre-webpack era (common in server-side code)
'global.GENTLY': JSON.stringify(false)
} : undefined,
// stub process.env with proxy to warn a missing value is
// being accessed in development mode
...config.experimental.pageEnv && dev ? {
'process.env': `
new Proxy(${!targetWeb ? 'process.env' : '{}'}, {
get(target, prop) {
if (typeof target[prop] === 'undefined') {
console.warn(\`An environment variable (\${prop}) that was not provided in the environment was accessed.\nSee more info here: https://nextjs.org/docs/messages/missing-env-value\`)
}
return target[prop]
}
})
`
} : {
}
}),
!isServer && new _reactLoadablePlugin.ReactLoadablePlugin({
filename: _constants1.REACT_LOADABLE_MANIFEST,
pagesDir,
runtimeAsset: hasConcurrentFeatures ? `server/${_constants1.MIDDLEWARE_REACT_LOADABLE_MANIFEST}.js` : undefined
}),
targetWeb && new _nextDropClientPagePlugin.DropClientPage(),
config.outputFileTracing && !isLikeServerless && isServer && !dev && new _nextTraceE