UNPKG

next

Version:

The React Framework

891 lines • 168 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); 0 && (module.exports = { createStaticWorker: null, default: null }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { createStaticWorker: function() { return createStaticWorker; }, default: function() { return build; } }); require("../lib/setup-exception-listeners"); const _env = require("@next/env"); const _picocolors = require("../lib/picocolors"); const _picomatch = require("next/dist/compiled/picomatch"); const _fs = require("fs"); const _os = /*#__PURE__*/ _interop_require_default(require("os")); const _worker = require("../lib/worker"); const _configshared = require("../server/config-shared"); const _devalue = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/devalue")); const _findup = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/find-up")); const _indexcjs = require("next/dist/compiled/nanoid/index.cjs"); const _path = /*#__PURE__*/ _interop_require_default(require("path")); const _constants = require("../lib/constants"); const _fileexists = require("../lib/file-exists"); const _findpagesdir = require("../lib/find-pages-dir"); const _loadcustomroutes = /*#__PURE__*/ _interop_require_wildcard(require("../lib/load-custom-routes")); const _nonnullable = require("../lib/non-nullable"); const _recursivedelete = require("../lib/recursive-delete"); const _verifypartytownsetup = require("../lib/verify-partytown-setup"); const _constants1 = require("../shared/lib/constants"); const _entryconstants = require("../shared/lib/entry-constants"); const _utils = require("../shared/lib/router/utils"); const _bundler = require("../lib/bundler"); const _config = /*#__PURE__*/ _interop_require_default(require("../server/config")); const _normalizepagepath = require("../shared/lib/page-path/normalize-page-path"); const _require = require("../server/require"); const _ciinfo = /*#__PURE__*/ _interop_require_wildcard(require("../server/ci-info")); const _turborepoaccesstrace = require("./turborepo-access-trace"); const _events = require("../telemetry/events"); const _storage = require("../telemetry/storage"); const _routediscovery = require("./route-discovery"); const _sortbypageexts = require("./sort-by-page-exts"); const _getstaticinfoincludinglayouts = require("./get-static-info-including-layouts"); const _pagetypes = require("../lib/page-types"); const _generatebuildid = require("./generate-build-id"); const _iswriteable = require("./is-writeable"); const _log = /*#__PURE__*/ _interop_require_wildcard(require("./output/log")); const _spinner = /*#__PURE__*/ _interop_require_default(require("./spinner")); const _trace = require("../trace"); const _routebundlestats = require("./route-bundle-stats"); const _utils1 = require("./utils"); const _writebuildid = require("./write-build-id"); const _normalizelocalepath = require("../shared/lib/i18n/normalize-locale-path"); const _iserror = /*#__PURE__*/ _interop_require_default(require("../lib/is-error")); const _isedgeruntime = require("../lib/is-edge-runtime"); const _recursivecopy = require("../lib/recursive-copy"); const _swc = require("./swc"); const _installbindings = require("./swc/install-bindings"); const _routeregex = require("../shared/lib/router/utils/route-regex"); const _getfilesindir = require("../lib/get-files-in-dir"); const _swcplugins = require("../telemetry/events/swc-plugins"); const _apppaths = require("../shared/lib/router/utils/app-paths"); const _approuterheaders = require("../client/components/app-router-headers"); const _webpackbuild = require("./webpack-build"); const _buildcontext = require("./build-context"); const _normalizepathsep = require("../shared/lib/page-path/normalize-path-sep"); const _isapprouteroute = require("../lib/is-app-route-route"); const _createclientrouterfilter = require("../lib/create-client-router-filter"); const _typecheck = require("./type-check"); const _generateinterceptionroutesrewrites = require("../lib/generate-interception-routes-rewrites"); const _builddataroute = require("../server/lib/router-utils/build-data-route"); const _formatmanifest = require("./manifests/formatter/format-manifest"); const _builddiagnostics = require("../diagnostics/build-diagnostics"); const _appinfolog = require("../server/lib/app-info-log"); const _utils2 = require("../export/utils"); const _trace1 = require("../lib/memory/trace"); const _encryptionutilsserver = require("../server/app-render/encryption-utils-server"); const _uploadtrace = /*#__PURE__*/ _interop_require_default(require("../trace/upload-trace")); const _ppr = require("../server/lib/experimental/ppr"); const _fallback = require("../lib/fallback"); const _renderingmode = require("./rendering-mode"); const _invarianterror = require("../shared/lib/invariant-error"); const _isbot = require("../shared/lib/router/utils/is-bot"); const _turbopackbuild = require("./turbopack-build"); const _inlinestaticenv = require("../lib/inline-static-env"); const _staticenv = require("../lib/static-env"); const _durationtostring = require("./duration-to-string"); const _shared = require("../trace/shared"); const _errortelemetryutils = require("../lib/error-telemetry-utils"); const _afterproductioncompile = require("./after-production-compile"); const _previewkeyutils = require("./preview-key-utils"); const _buildcomplete = require("./adapter/build-complete"); const _sortableroutes = require("../shared/lib/router/utils/sortable-routes"); const _promises = require("fs/promises"); const _routetypesutils = require("../server/lib/router-utils/route-types-utils"); const _lockfile = require("./lockfile"); const _buildprefetchsegmentdataroute = require("../server/lib/router-utils/build-prefetch-segment-data-route"); const _generateroutesmanifest = require("./generate-routes-manifest"); const _validateapppaths = require("./validate-app-paths"); function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interop_require_wildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = { __proto__: null }; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for(var key in obj){ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * The headers that are allowed to be used when revalidating routes. Currently * this includes both headers used by the pages and app routers. */ const ALLOWED_HEADERS = [ 'host', _constants.MATCHED_PATH_HEADER, _constants.PRERENDER_REVALIDATE_HEADER, _constants.PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, _constants.NEXT_CACHE_REVALIDATED_TAGS_HEADER, _constants.NEXT_CACHE_REVALIDATE_TAG_TOKEN_HEADER ]; function getCacheDir(distDir) { const cacheDir = _path.default.join(distDir, 'cache'); if (_ciinfo.isCI && !_ciinfo.hasNextSupport) { const hasCache = (0, _fs.existsSync)(cacheDir); if (!hasCache) { // Intentionally not piping to stderr which is what `Log.warn` does in case people fail in CI when // stderr is detected. console.log(`${_log.prefixes.warn} No build cache found. Please configure build caching for faster rebuilds. Read more: https://nextjs.org/docs/messages/no-cache`); } } return cacheDir; } async function writeFileUtf8(filePath, content) { await _fs.promises.writeFile(filePath, content, 'utf-8'); } function readFileUtf8(filePath) { return _fs.promises.readFile(filePath, 'utf8'); } async function writeManifest(filePath, manifest) { await writeFileUtf8(filePath, (0, _formatmanifest.formatManifest)(manifest)); } async function readManifest(filePath) { return JSON.parse(await readFileUtf8(filePath)); } async function writePrerenderManifest(distDir, manifest) { // Sort for deterministic outputs manifest.routes = (0, _sortableroutes.sortPagesObject)(manifest.routes); manifest.dynamicRoutes = (0, _sortableroutes.sortPagesObject)(manifest.dynamicRoutes); await writeManifest(_path.default.join(distDir, _constants1.PRERENDER_MANIFEST), manifest); } async function writeClientSsgManifest(prerenderManifest, { buildId, distDir, locales }) { const ssgPages = new Set([ ...Object.entries(prerenderManifest.routes)// Filter out dynamic routes .filter(([, { srcRoute }])=>srcRoute == null).map(([route])=>(0, _normalizelocalepath.normalizeLocalePath)(route, locales).pathname), ...Object.keys(prerenderManifest.dynamicRoutes) ].sort()); const clientSsgManifestContent = `self.__SSG_MANIFEST=${(0, _devalue.default)(ssgPages)};self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB()`; let ssgManifestPath = _path.default.join(_constants1.CLIENT_STATIC_FILES_PATH, buildId, '_ssgManifest.js'); await writeFileUtf8(_path.default.join(distDir, ssgManifestPath), clientSsgManifestContent); } async function writeFunctionsConfigManifest(distDir, manifest) { let sortedManifest = { version: manifest.version, functions: Object.fromEntries(Object.entries(manifest.functions).sort(([a], [b])=>a.localeCompare(b))) }; await writeManifest(_path.default.join(distDir, _constants1.SERVER_DIRECTORY, _constants1.FUNCTIONS_CONFIG_MANIFEST), sortedManifest); } async function writeRequiredServerFilesManifest(distDir, requiredServerFiles) { await writeManifest(_path.default.join(distDir, _constants1.SERVER_FILES_MANIFEST + '.json'), requiredServerFiles); await writeFileUtf8(_path.default.join(distDir, _constants1.SERVER_FILES_MANIFEST + '.js'), `self.__SERVER_FILES_MANIFEST=${(0, _formatmanifest.formatManifest)(requiredServerFiles)}`); } async function writeImagesManifest(distDir, config) { var _config_images, _config_images1; const images = { ...config.images }; const { deviceSizes, imageSizes } = images; images.sizes = [ ...deviceSizes, ...imageSizes ]; // By default, remotePatterns will allow no remote images ([]) images.remotePatterns = ((config == null ? void 0 : (_config_images = config.images) == null ? void 0 : _config_images.remotePatterns) || []).map((p)=>{ var _p_protocol; return { // Modifying the manifest should also modify matchRemotePattern() protocol: (_p_protocol = p.protocol) == null ? void 0 : _p_protocol.replace(/:$/, ''), hostname: (0, _picomatch.makeRe)(p.hostname).source, port: p.port, pathname: (0, _picomatch.makeRe)(p.pathname ?? '**', { dot: true }).source, search: p.search }; }); // By default, localPatterns will allow all local images (undefined) if (config == null ? void 0 : (_config_images1 = config.images) == null ? void 0 : _config_images1.localPatterns) { images.localPatterns = config.images.localPatterns.map((p)=>({ // Modifying the manifest should also modify matchLocalPattern() pathname: (0, _picomatch.makeRe)(p.pathname ?? '**', { dot: true }).source, search: p.search })); } await writeManifest(_path.default.join(distDir, _constants1.IMAGES_MANIFEST), { version: 1, images }); } const STANDALONE_DIRECTORY = 'standalone'; async function writeStandaloneDirectory(nextBuildSpan, distDir, pageKeys, denormalizedAppPages, outputFileTracingRoot, requiredServerFiles, middlewareManifest, hasNodeMiddleware, hasInstrumentationHook, staticPages, loadedEnvFiles, appDir) { await nextBuildSpan.traceChild('write-standalone-directory').traceAsyncFn(async ()=>{ await (0, _utils1.copyTracedFiles)(// requiredServerFiles.appDir Refers to the application directory, not App Router. requiredServerFiles.appDir, distDir, pageKeys.pages, denormalizedAppPages, outputFileTracingRoot, requiredServerFiles.config, middlewareManifest, hasNodeMiddleware, hasInstrumentationHook, staticPages); for (const file of [ ...requiredServerFiles.files, _path.default.join(requiredServerFiles.config.distDir, _constants1.SERVER_FILES_MANIFEST + '.json'), ...loadedEnvFiles.reduce((acc, envFile)=>{ if ([ '.env', '.env.production' ].includes(envFile.path)) { acc.push(envFile.path); } return acc; }, []) ]){ // requiredServerFiles.appDir Refers to the application directory, not App Router. const filePath = _path.default.join(requiredServerFiles.appDir, file); const outputPath = _path.default.join(distDir, STANDALONE_DIRECTORY, _path.default.relative(outputFileTracingRoot, filePath)); await _fs.promises.mkdir(_path.default.dirname(outputPath), { recursive: true }); await _fs.promises.copyFile(filePath, outputPath); } if (hasNodeMiddleware) { const middlewareOutput = _path.default.join(distDir, STANDALONE_DIRECTORY, _path.default.relative(outputFileTracingRoot, distDir), _constants1.SERVER_DIRECTORY, 'middleware.js'); await _fs.promises.mkdir(_path.default.dirname(middlewareOutput), { recursive: true }); await _fs.promises.copyFile(_path.default.join(distDir, _constants1.SERVER_DIRECTORY, 'middleware.js'), middlewareOutput); } const originalPagesDir = _path.default.join(distDir, _constants1.SERVER_DIRECTORY, 'pages'); if ((0, _fs.existsSync)(originalPagesDir)) { await (0, _recursivecopy.recursiveCopy)(originalPagesDir, _path.default.join(distDir, STANDALONE_DIRECTORY, _path.default.relative(outputFileTracingRoot, distDir), _constants1.SERVER_DIRECTORY, 'pages'), { overwrite: true }); } if (appDir) { const originalServerApp = _path.default.join(distDir, _constants1.SERVER_DIRECTORY, 'app'); if ((0, _fs.existsSync)(originalServerApp)) { await (0, _recursivecopy.recursiveCopy)(originalServerApp, _path.default.join(distDir, STANDALONE_DIRECTORY, _path.default.relative(outputFileTracingRoot, distDir), _constants1.SERVER_DIRECTORY, 'app'), { overwrite: true }); } } }); } function getNumberOfWorkers(config, maxTasks) { let workers; if (config.experimental.cpus && config.experimental.cpus !== _configshared.defaultConfig.experimental.cpus) { // If it's not set to the default, it's a user override workers = config.experimental.cpus; } else if (config.experimental.memoryBasedWorkersCount) { workers = Math.max(Math.min(config.experimental.cpus || 1, Math.floor(_os.default.freemem() / 1e9)), // enforce a minimum of 4 workers 4); } else if (config.experimental.cpus) { workers = config.experimental.cpus; } else { // Fall back to 4 workers if a count is not specified workers = 4; } // Cap workers to one more than the number of tasks. // Tasks can be passed to avoid over-allocating workers. if (maxTasks !== undefined && maxTasks > 0) { workers = Math.min(workers, maxTasks + 1); } return Math.max(workers, 1); } const staticWorkerPath = require.resolve('./worker'); const staticWorkerExposedMethods = [ 'hasCustomGetInitialProps', 'isPageStatic', 'getDefinedNamedExports', 'exportPages' ]; function createStaticWorker(config, options) { const { numberOfWorkers, debuggerPortOffset, progress } = options; return new _worker.Worker(staticWorkerPath, { logger: _log, numWorkers: numberOfWorkers, onActivity: ()=>{ progress == null ? void 0 : progress.run(); }, onActivityAbort: ()=>{ progress == null ? void 0 : progress.clear(); }, debuggerPortOffset, enableSourceMaps: config.enablePrerenderSourceMaps, // remove --max-old-space-size flag as it can cause memory issues. isolatedMemory: true, enableWorkerThreads: config.experimental.workerThreads, exposedMethods: staticWorkerExposedMethods, forkOptions: { env: { ...process.env.NEXT_CPU_PROF ? { NEXT_CPU_PROF: '1', NEXT_CPU_PROF_DIR: process.env.NEXT_CPU_PROF_DIR, __NEXT_PRIVATE_CPU_PROFILE: 'build-static-worker' } : undefined, // worker.ts copies this value into globalThis.NEXT_CLIENT_ASSET_SUFFIX __NEXT_PRERENDER_CLIENT_ASSET_SUFFIX: config.experimental.immutableAssetToken || config.deploymentId ? `?dpl=${config.experimental.immutableAssetToken || config.deploymentId}` : '' } } }); } async function writeFullyStaticExport(config, dir, enabledDirectories, configOutDir, nextBuildSpan, appDirOnly) { const exportApp = require('../export').default; await exportApp(dir, { buildExport: false, nextConfig: config, enabledDirectories, silent: true, outdir: _path.default.join(dir, configOutDir), numWorkers: getNumberOfWorkers(config), appDirOnly }, nextBuildSpan); } async function getBuildId(isGenerateMode, distDir, nextBuildSpan, config) { if (isGenerateMode) { return await _fs.promises.readFile(_path.default.join(distDir, _constants1.BUILD_ID_FILE), 'utf8'); } if (config.deploymentId) { // Skew protection is enabled and NEXT_NAV_DEPLOYMENT_ID_HEADER will be used instead. Set a // constant but "random" string because various tools perform `.replace(escapedBuildId, ....)` // which would fail if this were something like "build-id" instead. return 'build-TfctsWXpff2fKS'; } else { return await nextBuildSpan.traceChild('generate-buildid').traceAsyncFn(()=>(0, _generatebuildid.generateBuildId)(config.generateBuildId, _indexcjs.nanoid)); } } async function build(dir, experimentalAnalyze = false, reactProductionProfiling = false, debugOutput = false, debugPrerender = false, noMangling = false, appDirOnly = false, bundler = _bundler.Bundler.Turbopack, experimentalBuildMode, traceUploadUrl, debugBuildPaths, enabledFeatures = {}) { const isCompileMode = experimentalBuildMode === 'compile'; const isGenerateMode = experimentalBuildMode === 'generate'; _buildcontext.NextBuildContext.isCompileMode = isCompileMode; _buildcontext.NextBuildContext.analyze = experimentalAnalyze; const buildStartTime = Date.now(); let appType; let loadedConfig; let staticWorker; try { const nextBuildSpan = (0, _trace.trace)('next-build', undefined, { buildMode: experimentalBuildMode, version: "16.2.1", ...enabledFeatures }); _buildcontext.NextBuildContext.nextBuildSpan = nextBuildSpan; _buildcontext.NextBuildContext.dir = dir; _buildcontext.NextBuildContext.appDirOnly = appDirOnly; _buildcontext.NextBuildContext.reactProductionProfiling = reactProductionProfiling; _buildcontext.NextBuildContext.noMangling = noMangling; _buildcontext.NextBuildContext.debugPrerender = debugPrerender; _buildcontext.NextBuildContext.debugBuildPaths = debugBuildPaths; await nextBuildSpan.traceAsyncFn(async ()=>{ var _config_experimental, _mappedPages_404, _mappedPages__error, _pageKeys_app, _config_experimental1; // attempt to load global env values so they are available in next.config.js const { loadedEnvFiles } = nextBuildSpan.traceChild('load-dotenv').traceFn(()=>(0, _env.loadEnvConfig)(dir, false, _log)); _buildcontext.NextBuildContext.loadedEnvFiles = loadedEnvFiles; const turborepoAccessTraceResult = new _turborepoaccesstrace.TurborepoAccessTraceResult(); let experimentalFeatures = []; const config = await nextBuildSpan.traceChild('load-next-config').traceAsyncFn(()=>(0, _turborepoaccesstrace.turborepoTraceAccess)(()=>(0, _config.default)(_constants1.PHASE_PRODUCTION_BUILD, dir, { // Log for next.config loading process silent: false, reactProductionProfiling, debugPrerender, reportExperimentalFeatures (features) { experimentalFeatures = features.toSorted(({ key: a }, { key: b })=>a.localeCompare(b)); }, bundler }), turborepoAccessTraceResult)); loadedConfig = config; // Validate deploymentId if provided if (config.deploymentId !== undefined) { if (typeof config.deploymentId !== 'string') { throw Object.defineProperty(new Error(`Invalid \`deploymentId\` configuration: must be a string. See https://nextjs.org/docs/messages/deploymentid-not-a-string`), "__NEXT_ERROR_CODE", { value: "E987", enumerable: false, configurable: true }); } if (!/^[a-zA-Z0-9_-]*$/.test(config.deploymentId)) { throw Object.defineProperty(new Error(`Invalid \`deploymentId\` configuration: contains invalid characters. Only alphanumeric characters, hyphens, and underscores are allowed. See https://nextjs.org/docs/messages/deploymentid-invalid-characters`), "__NEXT_ERROR_CODE", { value: "E988", enumerable: false, configurable: true }); } } // Reading the config can modify environment variables that influence the bundler selection. bundler = (0, _bundler.finalizeBundlerFromConfig)(bundler); nextBuildSpan.setAttribute('bundler', getBundlerForTelemetry(bundler)); let configOutDir = 'out'; if ((0, _utils2.hasCustomExportOutput)(config)) { configOutDir = config.distDir; config.distDir = '.next'; } const distDir = _path.default.join(dir, config.distDir); _buildcontext.NextBuildContext.distDir = distDir; (0, _trace.setGlobal)('phase', _constants1.PHASE_PRODUCTION_BUILD); (0, _trace.setGlobal)('distDir', distDir); // Check for build cache before initializing telemetry, because the // Telemetry constructor creates the cache directory in CI environments. const cacheDir = getCacheDir(distDir); // Initialize telemetry before installBindings so that SWC load failure // events are captured if native bindings fail to load. const telemetry = new _storage.Telemetry({ distDir }); (0, _trace.setGlobal)('telemetry', telemetry); // Install the native bindings early so we can have synchronous access later. await (0, _installbindings.installBindings)((_config_experimental = config.experimental) == null ? void 0 : _config_experimental.useWasmBinary); // Set up code frame renderer for error formatting const { installCodeFrameSupport } = require('../server/lib/install-code-frame'); installCodeFrameSupport(); process.env.NEXT_DEPLOYMENT_ID = config.deploymentId || ''; _buildcontext.NextBuildContext.config = config; const buildId = await getBuildId(isGenerateMode, distDir, nextBuildSpan, config); _buildcontext.NextBuildContext.buildId = buildId; if (experimentalBuildMode === 'generate-env') { if (bundler === _bundler.Bundler.Turbopack) { _log.warn('generate-env is not needed with turbopack'); process.exit(0); } _log.info('Inlining static env ...'); await nextBuildSpan.traceChild('inline-static-env').traceAsyncFn(async ()=>{ await (0, _inlinestaticenv.inlineStaticEnv)({ distDir, config }); }); _log.info('Complete'); await (0, _trace.flushAllTraces)(); (0, _swc.teardownTraceSubscriber)(); process.exit(0); } // when using compile mode static env isn't inlined so we // need to populate in normal runtime env if (isCompileMode || isGenerateMode) { (0, _staticenv.populateStaticEnv)(config, config.deploymentId); } const customRoutes = await nextBuildSpan.traceChild('load-custom-routes').traceAsyncFn(()=>(0, _loadcustomroutes.default)(config)); const { headers, onMatchHeaders, rewrites, redirects } = customRoutes; const combinedRewrites = [ ...rewrites.beforeFiles, ...rewrites.afterFiles, ...rewrites.fallback ]; const hasRewrites = combinedRewrites.length > 0; _buildcontext.NextBuildContext.hasRewrites = hasRewrites; _buildcontext.NextBuildContext.originalRewrites = config._originalRewrites; _buildcontext.NextBuildContext.originalRedirects = config._originalRedirects; const distDirCreated = await nextBuildSpan.traceChild('create-dist-dir').traceAsyncFn(async ()=>{ try { await _fs.promises.mkdir(distDir, { recursive: true }); return true; } catch (err) { if ((0, _iserror.default)(err) && err.code === 'EPERM') { return false; } throw err; } }); if (!distDirCreated || !await (0, _iswriteable.isWriteable)(distDir)) { throw Object.defineProperty(new Error('> Build directory is not writeable. https://nextjs.org/docs/messages/build-dir-not-writeable'), "__NEXT_ERROR_CODE", { value: "E202", enumerable: false, configurable: true }); } if (config.experimental.lockDistDir) { // This leaks the lock file descriptor. That's okay, it'll be cleaned up by the OS upon // process exit. await _lockfile.Lockfile.acquireWithRetriesOrExit(_path.default.join(distDir, 'lock'), 'next build'); } if (config.cleanDistDir && !isGenerateMode) { await nextBuildSpan.traceChild('clean').traceAsyncFn(()=>(0, _recursivedelete.recursiveDeleteSyncWithAsyncRetries)(distDir, /^(cache|dev|lock)/)); } const publicDir = _path.default.join(dir, 'public'); const { pagesDir, appDir } = (0, _findpagesdir.findPagesDir)(dir); if (pagesDir && appDir) { appType = 'hybrid'; } else if (pagesDir) { appType = 'pages'; } else if (appDir) { appType = 'app'; } if (!appDirOnly && !pagesDir) { appDirOnly = true; } _buildcontext.NextBuildContext.pagesDir = pagesDir; _buildcontext.NextBuildContext.appDir = appDir; const enabledDirectories = { app: typeof appDir === 'string', pages: typeof pagesDir === 'string' }; // Generate a random encryption key for this build. // This key is used to encrypt cross boundary values and can be used to generate hashes. const encryptionKey = await (0, _encryptionutilsserver.generateEncryptionKeyBase64)({ isBuild: true, distDir }); _buildcontext.NextBuildContext.encryptionKey = encryptionKey; const isSrcDir = _path.default.relative(dir, pagesDir || appDir || '').startsWith('src'); const hasPublicDir = (0, _fs.existsSync)(publicDir); telemetry.record((0, _events.eventCliSession)(config, { webpackVersion: 5, cliCommand: 'build', isSrcDir, hasNowJson: !!await (0, _findup.default)('now.json', { cwd: dir }), isCustomServer: null, turboFlag: false, pagesDir: !!pagesDir, appDir: !!appDir })); (0, _events.eventNextPlugins)(_path.default.resolve(dir)).then((events)=>telemetry.record(events)); (0, _swcplugins.eventSwcPlugins)(_path.default.resolve(dir), config).then((events)=>telemetry.record(events)); // Always log next version first then start rest jobs const envInfo = (0, _appinfolog.getEnvInfo)(dir); (0, _appinfolog.logStartInfo)({ networkUrl: null, appUrl: null, envInfo, logBundler: true }); (0, _appinfolog.logExperimentalInfo)({ experimentalFeatures, cacheComponents: !!config.cacheComponents }); const typeCheckingOptions = { dir, appDir, pagesDir, telemetry, nextBuildSpan, config, cacheDir, debugBuildPaths }; if (appDir && 'exportPathMap' in config) { const errorMessage = 'The "exportPathMap" configuration cannot be used with the "app" directory. Please use generateStaticParams() instead.'; _log.error(errorMessage); await telemetry.flush(); throw Object.defineProperty(new Error(errorMessage), "__NEXT_ERROR_CODE", { value: "E998", enumerable: false, configurable: true }); } const middlewareDetectionRegExp = new RegExp(`^${_constants.MIDDLEWARE_FILENAME}\\.(?:${config.pageExtensions.join('|')})$`); const proxyDetectionRegExp = new RegExp(`^${_constants.PROXY_FILENAME}\\.(?:${config.pageExtensions.join('|')})$`); const instrumentationHookDetectionRegExp = new RegExp(`^${_constants.INSTRUMENTATION_HOOK_FILENAME}\\.(?:${config.pageExtensions.join('|')})$`); const rootDir = _path.default.join(pagesDir || appDir, '..'); const includes = [ middlewareDetectionRegExp, proxyDetectionRegExp, instrumentationHookDetectionRegExp ]; const rootPaths = Array.from(await (0, _getfilesindir.getFilesInDir)(rootDir)).filter((file)=>includes.some((include)=>include.test(file))).sort((0, _sortbypageexts.sortByPageExts)(config.pageExtensions)).map((file)=>_path.default.join(rootDir, file).replace(dir, '')); let instrumentationHookFilePath; let proxyFilePath; let middlewareFilePath; for (const rootPath of rootPaths){ const { name: fileBaseName, dir: fileDir } = _path.default.parse(rootPath); const normalizedFileDir = (0, _normalizepathsep.normalizePathSep)(fileDir); const isAtConventionLevel = normalizedFileDir === '/' || normalizedFileDir === '/src'; if (isAtConventionLevel && fileBaseName === _constants.MIDDLEWARE_FILENAME) { middlewareFilePath = rootPath; } if (isAtConventionLevel && fileBaseName === _constants.PROXY_FILENAME) { proxyFilePath = rootPath; } if (isAtConventionLevel && fileBaseName === _constants.INSTRUMENTATION_HOOK_FILENAME) { instrumentationHookFilePath = rootPath; } } if (middlewareFilePath) { if (proxyFilePath) { const cwd = process.cwd(); const absoluteProxyPath = _path.default.join(rootDir, proxyFilePath); const absoluteMiddlewarePath = _path.default.join(rootDir, middlewareFilePath); throw Object.defineProperty(new Error(`Both ${_constants.MIDDLEWARE_FILENAME} file "./${_path.default.relative(cwd, absoluteMiddlewarePath)}" and ${_constants.PROXY_FILENAME} file "./${_path.default.relative(cwd, absoluteProxyPath)}" are detected. Please use "./${_path.default.relative(cwd, absoluteProxyPath)}" only. Learn more: https://nextjs.org/docs/messages/middleware-to-proxy`), "__NEXT_ERROR_CODE", { value: "E900", enumerable: false, configurable: true }); } _log.warnOnce(`The "${_constants.MIDDLEWARE_FILENAME}" file convention is deprecated. Please use "${_constants.PROXY_FILENAME}" instead. Learn more: https://nextjs.org/docs/messages/middleware-to-proxy`); } const hasInstrumentationHook = Boolean(instrumentationHookFilePath); const hasMiddlewareFile = Boolean(middlewareFilePath); const hasProxyFile = Boolean(proxyFilePath); _buildcontext.NextBuildContext.hasInstrumentationHook = hasInstrumentationHook; const previewProps = await (0, _previewkeyutils.generatePreviewKeys)({ isBuild: true, distDir }); _buildcontext.NextBuildContext.previewProps = previewProps; const discovery = await nextBuildSpan.traceChild('discover-routes').traceAsyncFn(()=>(0, _routediscovery.discoverRoutes)({ appDir, pagesDir, pageExtensions: config.pageExtensions, isDev: false, baseDir: dir, isSrcDir, appDirOnly, debugBuildPaths })); // Update appDirOnly from discovery (may have changed if no pages found) appDirOnly = discovery.appDirOnly; _buildcontext.NextBuildContext.appDirOnly = appDirOnly; const pagesPaths = discovery.pagesPaths; _buildcontext.NextBuildContext.mappedPages = discovery.mappedPages || {}; _buildcontext.NextBuildContext.mappedAppPages = discovery.mappedAppPages; _buildcontext.NextBuildContext.mappedRootPaths = await nextBuildSpan.traceChild('create-root-mapping').traceAsyncFn(()=>(0, _routediscovery.createPagesMapping)({ isDev: false, pageExtensions: config.pageExtensions, pagePaths: rootPaths, pagesType: _pagetypes.PAGE_TYPES.ROOT, pagesDir, appDir, appDirOnly })); const { pageRoutes, pageApiRoutes, appRoutes, appRouteHandlers, layoutRoutes, slots } = discovery; const pagesPageKeys = Object.keys(_buildcontext.NextBuildContext.mappedPages); const conflictingAppPagePaths = []; const appPageKeys = new Set(); let denormalizedAppPages; if (discovery.mappedAppPages) { denormalizedAppPages = Object.keys(discovery.mappedAppPages); for (const appKey of denormalizedAppPages){ const normalizedAppPageKey = (0, _apppaths.normalizeAppPath)(appKey); const pagePath = _buildcontext.NextBuildContext.mappedPages[normalizedAppPageKey]; if (pagePath) { const appPath = discovery.mappedAppPages[appKey]; conflictingAppPagePaths.push([ pagePath.replace(/^private-next-pages/, 'pages'), appPath.replace(/^private-next-app-dir/, 'app') ]); } appPageKeys.add(normalizedAppPageKey); } } const appPaths = Array.from(appPageKeys); const totalAppPagesCount = appPaths.length; const mappedPages = _buildcontext.NextBuildContext.mappedPages; const mappedAppPages = _buildcontext.NextBuildContext.mappedAppPages; // Validate that the app paths are valid. This is currently duplicating // the logic from packages/next/src/shared/lib/router/utils/sorted-routes.ts // but is instead specifically focused on code that can be shared // eventually with the development code. (0, _validateapppaths.validateAppPaths)(appPaths); // Interception routes are modelled as beforeFiles rewrites rewrites.beforeFiles.push(...(0, _generateinterceptionroutesrewrites.generateInterceptionRoutesRewrites)(appPaths, config.basePath)); _buildcontext.NextBuildContext.rewrites = rewrites; const pageKeys = { pages: pagesPageKeys, app: appPaths.length > 0 ? appPaths : undefined }; await nextBuildSpan.traceChild('generate-route-types').traceAsyncFn(async ()=>{ const routeTypesFilePath = _path.default.join(distDir, 'types', 'routes.d.ts'); const validatorFilePath = _path.default.join(distDir, 'types', 'validator.ts'); await (0, _promises.mkdir)(_path.default.dirname(routeTypesFilePath), { recursive: true }); const routeTypesManifest = await (0, _routetypesutils.createRouteTypesManifest)({ dir, pageRoutes, appRoutes, appRouteHandlers, pageApiRoutes, layoutRoutes, slots, redirects: config.redirects, rewrites: config.rewrites, validatorFilePath }); await (0, _routetypesutils.writeRouteTypesManifest)(routeTypesManifest, routeTypesFilePath, config); await (0, _routetypesutils.writeValidatorFile)(routeTypesManifest, validatorFilePath, Boolean(config.experimental.strictRouteTypes)); }); // Turbopack already handles conflicting app and page routes. if (bundler !== _bundler.Bundler.Turbopack) { const numConflictingAppPaths = conflictingAppPagePaths.length; if (mappedAppPages && numConflictingAppPaths > 0) { const errorMessage = `Conflicting app and page file${numConflictingAppPaths === 1 ? ' was' : 's were'} found, please remove the conflicting files to continue:`; _log.error(errorMessage); for (const [pagePath, appPath] of conflictingAppPagePaths){ _log.error(` "${pagePath}" - "${appPath}"`); } await telemetry.flush(); throw Object.defineProperty(new Error(errorMessage), "__NEXT_ERROR_CODE", { value: "E1042", enumerable: false, configurable: true }); } } const conflictingPublicFiles = []; const hasPages404 = (_mappedPages_404 = mappedPages['/404']) == null ? void 0 : _mappedPages_404.startsWith(_constants.PAGES_DIR_ALIAS); const hasApp404 = !!(mappedAppPages == null ? void 0 : mappedAppPages[_entryconstants.UNDERSCORE_NOT_FOUND_ROUTE_ENTRY]); const hasAppGlobalError = !!(mappedAppPages == null ? void 0 : mappedAppPages[_entryconstants.UNDERSCORE_GLOBAL_ERROR_ROUTE_ENTRY]); const hasCustomErrorPage = (_mappedPages__error = mappedPages['/_error']) == null ? void 0 : _mappedPages__error.startsWith(_constants.PAGES_DIR_ALIAS); // Check if there are any user pages (non-reserved pages) in the pages router const hasUserPagesRoutes = Object.keys(mappedPages).some((route)=>!(0, _utils1.isReservedPage)(route)); if (hasPublicDir) { const hasPublicUnderScoreNextDir = (0, _fs.existsSync)(_path.default.join(publicDir, '_next')); if (hasPublicUnderScoreNextDir) { throw Object.defineProperty(new Error(_constants.PUBLIC_DIR_MIDDLEWARE_CONFLICT), "__NEXT_ERROR_CODE", { value: "E394", enumerable: false, configurable: true }); } } await nextBuildSpan.traceChild('public-dir-conflict-check').traceAsyncFn(async ()=>{ // Check if pages conflict with files in `public` // Only a page of public file can be served, not both. for(const page in mappedPages){ const hasPublicPageFile = await (0, _fileexists.fileExists)(_path.default.join(publicDir, page === '/' ? '/index' : page), _fileexists.FileType.File); if (hasPublicPageFile) { conflictingPublicFiles.push(page); } } const numConflicting = conflictingPublicFiles.length; if (numConflicting) { throw Object.defineProperty(new Error(`Conflicting public and page file${numConflicting === 1 ? ' was' : 's were'} found. https://nextjs.org/docs/messages/conflicting-public-file-page\n${conflictingPublicFiles.join('\n')}`), "__NEXT_ERROR_CODE", { value: "E270", enumerable: false, configurable: true }); } }); const nestedReservedPages = pageKeys.pages.filter((page)=>{ return page.match(/\/(_app|_document|_error)$/) && _path.default.dirname(page) !== '/'; }); if (nestedReservedPages.length) { _log.warn(`The following reserved Next.js pages were detected not directly under the pages directory:\n` + nestedReservedPages.join('\n') + `\nSee more info here: https://nextjs.org/docs/messages/nested-reserved-page\n`); } const restrictedRedirectPaths = [ '/_next' ].map((p)=>config.basePath ? `${config.basePath}${p}` : p); const isAppCacheComponentsEnabled = Boolean(config.cacheComponents); const isAuthInterruptsEnabled = Boolean(config.experimental.authInterrupts); const isAppPPREnabled = (0, _ppr.checkIsAppPPREnabled)(config.experimental.ppr); const routesManifestPath = _path.default.join(distDir, _constants1.ROUTES_MANIFEST); // Generate the routes manifest using the extracted helper const { routesManifest, dynamicRoutes, sourcePages } = nextBuildSpan.traceChild('generate-routes-manifest').traceFn(()=>(0, _generateroutesmanifest.generateRoutesManifest)({ appType, pageKeys, config, redirects, headers, onMatchHeaders, rewrites, restrictedRedirectPaths, isAppPPREnabled, deploymentId: config.deploymentId })); // For pages directory, we run type checking after route collection but before build. if (!appDir && !isCompileMode) { await (0, _typecheck.startTypeChecking)(typeCheckingOptions); } let clientRouterFilters; if (config.experimental.clientRouterFilter) { const nonInternalRedirects = (config._originalRedirects || []).filter((r)=>!r.internal); clientRouterFilters = (0, _createclientrouterfilter.createClientRouterFilter)([ ...appPaths ], config.experimental.clientRouterFilterRedirects ? nonInternalRedirects : [], config.experimental.clientRouterFilterAllowedRate); _buildcontext.NextBuildContext.clientRouterFilters = clientRouterFilters; } // Ensure commonjs handling is used for files in the distDir (generally .next) // Files outside of the distDir can be "type": "module" await writeFileUtf8(_path.default.join(distDir, 'package.json'), '{"type": "commonjs"}'); // These are written to distDir, so they need to come after creating and cleaning distDr. await (0, _builddiagnostics.recordFrameworkVersion)("16.2.1"); await (0, _builddiagnostics.updateBuildDiagnostics)({ buildStage: 'start' }); const outputFileTracingRoot = config.outputFileTracingRoot || dir; const pagesManifestPath = _path.default.join(distDir, _constants1.SERVER_DIRECTORY, _constants1.PAGES_MANIFEST); let buildTraceContext; let buildTracesPromise = undefined; // If there's has a custom webpack config and disable the build worker. // Otherwise respect the option if it's set. const useBuildWorker = config.experimental.webpackBuildWorker || config.experimental.webpackBuildWorker === undefined && !config.webpack; const runServerAndEdgeInParallel = config.experimental.parallelServerCompiles; const collectServerBuildTracesInParallel = config.experimental.parallelServerBuildTraces || config.experimental.parallelServerBuildTraces === undefined && isCompileMode; nextBuildSpan.setAttribute('has-custom-webpack-config', String(!!config.webpack)); nextBuildSpan.setAttribute('use-build-worker', String(useBuildWorker)); if (!useBuildWorker && (runServerAndEdgeInParallel || collectServerBuildTracesInParallel)) { throw Object.defineProperty(new Error('The "parallelServerBuildTraces" and "parallelServerCompiles" options may only be used when build workers can be used. Read more: https://nextjs.org/docs/messages/parallel-build-without-worker'), "__NEXT_ERROR_CODE", { value: "E101", enumerable: false, configurable: true }); } // #region Compile _log.info('Creating an optimized production build ...'); (0, _trace1.traceMemoryUsage)('Starting build', nextBuildSpan); await (0, _builddiagnostics.updateBuildDiagnostics)({ buildStage: 'compile', buildOptions: { useBuildWorker: String(useBuildWorker) } }); let shutdownPromise = Promise.resolve(); if (!isGenerateMode) { if (bundler === _bundler.Bundler.Turbopack) { const { duration: compilerDuration, shutdownPromise: p, ...rest } = await (0, _turbopackbuild.turbopackBuild)(process.env.NEXT_TURBOPACK_USE_WORKER === undefined || process.env.NEXT_TURBOPACK_USE_WORKER !== '0'); shutdownPromise = p; (0, _trace1.traceMemoryUsage)('Finished build', nextBuildSpan); buildTraceContext = rest.buildTraceContext; const durationString = (0, _durationtostring.durationToString)(compilerDuration); _log.event(`Compiled successfully in ${durationString}`); telemetry.record((0, _events.eventBuildCompleted)(pagesPaths, { bundler: 'turbopack', durationInSeconds: Math.round(compilerDuration), totalAppPagesCount })); } else { if (runServerAndEdgeInParallel || collectServerBuildTracesInParallel) { let durationInSeconds = 0; await (0, _builddiagnostics.updateBuildDiagnostics)({ buildStage: 'compile-server' }); const serverBuildPromise = (0, _webpackbuild.webpackBuild)(useBuildWorker, [ 'server' ]).then((res)=>{ (0, _trace1.traceMemoryUsage)('Finished server