UNPKG

next

Version:

The React Framework

1,105 lines • 74 kB
"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