next
Version:
The React Framework
829 lines • 129 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return build;
}
});
require("../lib/setup-exception-listeners");
const _env = require("@next/env");
const _chalk = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/chalk"));
const _crypto = /*#__PURE__*/ _interop_require_default(require("crypto"));
const _micromatch = require("next/dist/compiled/micromatch");
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 _pathtoregexp = require("next/dist/compiled/path-to-regexp");
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 _redirectstatus = require("../lib/redirect-status");
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 _utils = require("../shared/lib/router/utils");
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("../telemetry/ci-info"));
const _events = require("../telemetry/events");
const _storage = require("../telemetry/storage");
const _getpagestaticinfo = require("./analysis/get-page-static-info");
const _entries = require("./entries");
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 _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 _recursivereaddir = require("../lib/recursive-readdir");
const _swc = require("./swc");
const _routeregex = require("../shared/lib/router/utils/route-regex");
const _flatreaddir = require("../lib/flat-readdir");
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 _findpagefile = require("../server/lib/find-page-file");
const _typecheck = require("./type-check");
const _generateinterceptionroutesrewrites = require("../lib/generate-interception-routes-rewrites");
const _builddataroute = require("../server/lib/router-utils/build-data-route");
const _requirehook = require("../server/require-hook");
const _incrementalcacheserver = require("../server/lib/incremental-cache-server");
const _nodefsmethods = require("../server/lib/node-fs-methods");
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 = {};
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;
}
async function generateClientSsgManifest(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()`;
await _fs.promises.writeFile(_path.default.join(distDir, _constants1.CLIENT_STATIC_FILES_PATH, buildId, "_ssgManifest.js"), clientSsgManifestContent);
}
function pageToRoute(page) {
const routeRegex = (0, _routeregex.getNamedRouteRegex)(page, true);
return {
page,
regex: (0, _loadcustomroutes.normalizeRouteRegex)(routeRegex.re.source),
routeKeys: routeRegex.routeKeys,
namedRegex: routeRegex.namedRegex
};
}
async function build(dir, reactProductionProfiling = false, debugOutput = false, runLint = true, noMangling = false, appDirOnly = false, turboNextBuild = false, turboNextBuildRoot = null, buildMode) {
const isCompile = buildMode === "experimental-compile";
const isGenerate = buildMode === "experimental-generate";
let hasAppDir = false;
try {
const nextBuildSpan = (0, _trace.trace)("next-build", undefined, {
version: "13.4.13"
});
_buildcontext.NextBuildContext.nextBuildSpan = nextBuildSpan;
_buildcontext.NextBuildContext.dir = dir;
_buildcontext.NextBuildContext.appDirOnly = appDirOnly;
_buildcontext.NextBuildContext.reactProductionProfiling = reactProductionProfiling;
_buildcontext.NextBuildContext.noMangling = noMangling;
const buildResult = await nextBuildSpan.traceAsyncFn(async ()=>{
var _mappedPages_404, _config_images;
// 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 config = await nextBuildSpan.traceChild("load-next-config").traceAsyncFn(()=>(0, _config.default)(_constants1.PHASE_PRODUCTION_BUILD, dir));
_buildcontext.NextBuildContext.config = config;
let configOutDir = "out";
if (config.output === "export" && config.distDir !== ".next") {
// In the past, a user had to run "next build" to generate
// ".next" (or whatever the distDir) followed by "next export"
// to generate "out" (or whatever the outDir). However, when
// "output: export" is configured, "next build" does both steps.
// So the user-configured distDir is actually the outDir.
configOutDir = config.distDir;
config.distDir = ".next";
}
const distDir = _path.default.join(dir, config.distDir);
(0, _trace.setGlobal)("phase", _constants1.PHASE_PRODUCTION_BUILD);
(0, _trace.setGlobal)("distDir", distDir);
let buildId = "";
if (isGenerate) {
buildId = await _fs.promises.readFile(_path.default.join(distDir, "BUILD_ID"), "utf8");
} else {
buildId = await nextBuildSpan.traceChild("generate-buildid").traceAsyncFn(()=>(0, _generatebuildid.generateBuildId)(config.generateBuildId, _indexcjs.nanoid));
}
_buildcontext.NextBuildContext.buildId = buildId;
const customRoutes = await nextBuildSpan.traceChild("load-custom-routes").traceAsyncFn(()=>(0, _loadcustomroutes.default)(config));
const { headers , rewrites , redirects } = customRoutes;
_buildcontext.NextBuildContext.rewrites = rewrites;
_buildcontext.NextBuildContext.originalRewrites = config._originalRewrites;
_buildcontext.NextBuildContext.originalRedirects = config._originalRedirects;
const cacheDir = _path.default.join(distDir, "cache");
if (_ciinfo.isCI && !_ciinfo.hasNextSupport) {
const hasCache = await (0, _fileexists.fileExists)(cacheDir);
if (!hasCache) {
// Intentionally not piping to stderr 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`);
}
}
const telemetry = new _storage.Telemetry({
distDir
});
(0, _trace.setGlobal)("telemetry", telemetry);
const publicDir = _path.default.join(dir, "public");
const isAppDirEnabled = !!config.experimental.appDir;
const { pagesDir , appDir } = (0, _findpagesdir.findPagesDir)(dir, isAppDirEnabled);
_buildcontext.NextBuildContext.pagesDir = pagesDir;
_buildcontext.NextBuildContext.appDir = appDir;
hasAppDir = Boolean(appDir);
const isSrcDir = _path.default.relative(dir, pagesDir || appDir || "").startsWith("src");
const hasPublicDir = await (0, _fileexists.fileExists)(publicDir);
telemetry.record((0, _events.eventCliSession)(dir, 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));
const ignoreESLint = Boolean(config.eslint.ignoreDuringBuilds);
const shouldLint = !ignoreESLint && runLint;
const typeCheckingOptions = {
dir,
appDir,
pagesDir,
runLint,
shouldLint,
ignoreESLint,
telemetry,
nextBuildSpan,
config,
cacheDir
};
// For app directory, we run type checking after build. That's because
// we dynamically generate types for each layout and page in the app
// directory.
if (!appDir && !isCompile) await (0, _typecheck.startTypeChecking)(typeCheckingOptions);
if (appDir && "exportPathMap" in config) {
_log.error('The "exportPathMap" configuration cannot be used with the "app" directory. Please use generateStaticParams() instead.');
await telemetry.flush();
process.exit(1);
}
const buildLintEvent = {
featureName: "build-lint",
invocationCount: shouldLint ? 1 : 0
};
telemetry.record({
eventName: _events.EVENT_BUILD_FEATURE_USAGE,
payload: buildLintEvent
});
let buildSpinner = {
stopAndPersist () {
return this;
}
};
if (!isGenerate) {
buildSpinner = (0, _spinner.default)({
prefixText: `${_log.prefixes.info} Creating an optimized production build`
});
}
_buildcontext.NextBuildContext.buildSpinner = buildSpinner;
const validFileMatcher = (0, _findpagefile.createValidFileMatcher)(config.pageExtensions, appDir);
const pagesPaths = !appDirOnly && pagesDir ? await nextBuildSpan.traceChild("collect-pages").traceAsyncFn(()=>(0, _recursivereaddir.recursiveReadDir)(pagesDir, validFileMatcher.isPageFile)) : [];
const middlewareDetectionRegExp = new RegExp(`^${_constants.MIDDLEWARE_FILENAME}\\.(?:${config.pageExtensions.join("|")})$`);
const instrumentationHookDetectionRegExp = new RegExp(`^${_constants.INSTRUMENTATION_HOOK_FILENAME}\\.(?:${config.pageExtensions.join("|")})$`);
const rootDir = _path.default.join(pagesDir || appDir, "..");
const instrumentationHookEnabled = Boolean(config.experimental.instrumentationHook);
const rootPaths = (await (0, _flatreaddir.flatReaddir)(rootDir, [
middlewareDetectionRegExp,
...instrumentationHookEnabled ? [
instrumentationHookDetectionRegExp
] : []
])).map((absoluteFile)=>absoluteFile.replace(dir, ""));
const hasInstrumentationHook = rootPaths.some((p)=>p.includes(_constants.INSTRUMENTATION_HOOK_FILENAME));
_buildcontext.NextBuildContext.hasInstrumentationHook = hasInstrumentationHook;
const previewProps = {
previewModeId: _crypto.default.randomBytes(16).toString("hex"),
previewModeSigningKey: _crypto.default.randomBytes(32).toString("hex"),
previewModeEncryptionKey: _crypto.default.randomBytes(32).toString("hex")
};
_buildcontext.NextBuildContext.previewProps = previewProps;
const mappedPages = nextBuildSpan.traceChild("create-pages-mapping").traceFn(()=>(0, _entries.createPagesMapping)({
isDev: false,
pageExtensions: config.pageExtensions,
pagesType: "pages",
pagePaths: pagesPaths,
pagesDir
}));
_buildcontext.NextBuildContext.mappedPages = mappedPages;
let mappedAppPages;
let denormalizedAppPages;
if (appDir) {
const appPaths = await nextBuildSpan.traceChild("collect-app-paths").traceAsyncFn(()=>(0, _recursivereaddir.recursiveReadDir)(appDir, (absolutePath)=>validFileMatcher.isAppRouterPage(absolutePath) || // For now we only collect the root /not-found page in the app
// directory as the 404 fallback
validFileMatcher.isRootNotFound(absolutePath), undefined, (part)=>part.startsWith("_")));
mappedAppPages = nextBuildSpan.traceChild("create-app-mapping").traceFn(()=>(0, _entries.createPagesMapping)({
pagePaths: appPaths,
isDev: false,
pagesType: "app",
pageExtensions: config.pageExtensions,
pagesDir: pagesDir
}));
// If the metadata route doesn't contain generating dynamic exports,
// we can replace the dynamic catch-all route and use the static route instead.
for (const [pageKey, pagePath] of Object.entries(mappedAppPages)){
if (pageKey.includes("[[...__metadata_id__]]")) {
const pageFilePath = (0, _entries.getPageFilePath)({
absolutePagePath: pagePath,
pagesDir,
appDir,
rootDir
});
const isDynamic = await (0, _getpagestaticinfo.isDynamicMetadataRoute)(pageFilePath);
if (!isDynamic) {
delete mappedAppPages[pageKey];
mappedAppPages[pageKey.replace("[[...__metadata_id__]]/", "")] = pagePath;
}
if (pageKey.includes("sitemap.xml/[[...__metadata_id__]]") && isDynamic) {
delete mappedAppPages[pageKey];
mappedAppPages[pageKey.replace("sitemap.xml/[[...__metadata_id__]]", "sitemap/[__metadata_id__]")] = pagePath;
}
}
}
_buildcontext.NextBuildContext.mappedAppPages = mappedAppPages;
}
let mappedRootPaths = {};
if (rootPaths.length > 0) {
mappedRootPaths = (0, _entries.createPagesMapping)({
isDev: false,
pageExtensions: config.pageExtensions,
pagePaths: rootPaths,
pagesType: "root",
pagesDir: pagesDir
});
}
_buildcontext.NextBuildContext.mappedRootPaths = mappedRootPaths;
const pagesPageKeys = Object.keys(mappedPages);
const conflictingAppPagePaths = [];
const appPageKeys = [];
if (mappedAppPages) {
denormalizedAppPages = Object.keys(mappedAppPages);
for (const appKey of denormalizedAppPages){
const normalizedAppPageKey = (0, _apppaths.normalizeAppPath)(appKey);
const pagePath = mappedPages[normalizedAppPageKey];
if (pagePath) {
const appPath = mappedAppPages[appKey];
conflictingAppPagePaths.push([
pagePath.replace(/^private-next-pages/, "pages"),
appPath.replace(/^private-next-app-dir/, "app")
]);
}
appPageKeys.push(normalizedAppPageKey);
}
}
// Interception routes are modelled as beforeFiles rewrites
rewrites.beforeFiles.push(...(0, _generateinterceptionroutesrewrites.generateInterceptionRoutesRewrites)(appPageKeys));
const totalAppPagesCount = appPageKeys.length;
const pageKeys = {
pages: pagesPageKeys,
app: appPageKeys.length > 0 ? appPageKeys : undefined
};
if (turboNextBuild) {
// TODO(WEB-397) This is a temporary workaround to allow for filtering a
// subset of pages when building with --experimental-turbo, until we
// have complete support for all pages.
if (process.env.NEXT_TURBO_FILTER_PAGES) {
var _pageKeys_app;
const filterPages = process.env.NEXT_TURBO_FILTER_PAGES.split(",");
pageKeys.pages = pageKeys.pages.filter((page)=>{
return filterPages.some((filterPage)=>{
return (0, _micromatch.isMatch)(page, filterPage);
});
});
pageKeys.app = (_pageKeys_app = pageKeys.app) == null ? void 0 : _pageKeys_app.filter((page)=>{
return filterPages.some((filterPage)=>{
return (0, _micromatch.isMatch)(page, filterPage);
});
});
}
}
const numConflictingAppPaths = conflictingAppPagePaths.length;
if (mappedAppPages && numConflictingAppPaths > 0) {
_log.error(`Conflicting app and page file${numConflictingAppPaths === 1 ? " was" : "s were"} found, please remove the conflicting files to continue:`);
for (const [pagePath, appPath] of conflictingAppPagePaths){
_log.error(` "${pagePath}" - "${appPath}"`);
}
await telemetry.flush();
process.exit(1);
}
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["/_not-found"]);
const hasCustomErrorPage = mappedPages["/_error"].startsWith(_constants.PAGES_DIR_ALIAS);
if (hasPublicDir) {
const hasPublicUnderScoreNextDir = await (0, _fileexists.fileExists)(_path.default.join(publicDir, "_next"));
if (hasPublicUnderScoreNextDir) {
throw new Error(_constants.PUBLIC_DIR_MIDDLEWARE_CONFLICT);
}
}
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 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")}`);
}
});
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 buildCustomRoute = (r, type)=>{
const keys = [];
const routeRegex = (0, _pathtoregexp.pathToRegexp)(r.source, keys, {
strict: true,
sensitive: false,
delimiter: "/"
});
let regexSource = routeRegex.source;
if (!r.internal) {
regexSource = (0, _redirectstatus.modifyRouteRegex)(routeRegex.source, type === "redirect" ? restrictedRedirectPaths : undefined);
}
return {
...r,
...type === "redirect" ? {
statusCode: (0, _redirectstatus.getRedirectStatus)(r),
permanent: undefined
} : {},
regex: (0, _loadcustomroutes.normalizeRouteRegex)(regexSource)
};
};
const routesManifestPath = _path.default.join(distDir, _constants1.ROUTES_MANIFEST);
const routesManifest = nextBuildSpan.traceChild("generate-routes-manifest").traceFn(()=>{
const sortedRoutes = (0, _utils.getSortedRoutes)([
...pageKeys.pages,
...pageKeys.app ?? []
]);
const dynamicRoutes = [];
const staticRoutes = [];
for (const route of sortedRoutes){
if ((0, _utils.isDynamicRoute)(route)) {
dynamicRoutes.push(pageToRoute(route));
} else if (!(0, _utils1.isReservedPage)(route)) {
staticRoutes.push(pageToRoute(route));
}
}
return {
version: 3,
pages404: true,
caseSensitive: !!config.experimental.caseSensitiveRoutes,
basePath: config.basePath,
redirects: redirects.map((r)=>buildCustomRoute(r, "redirect")),
headers: headers.map((r)=>buildCustomRoute(r, "header")),
dynamicRoutes,
staticRoutes,
dataRoutes: [],
i18n: config.i18n || undefined,
rsc: {
header: _approuterheaders.RSC,
varyHeader: _approuterheaders.RSC_VARY_HEADER,
contentTypeHeader: _approuterheaders.RSC_CONTENT_TYPE_HEADER
},
skipMiddlewareUrlNormalize: config.skipMiddlewareUrlNormalize
};
});
if (rewrites.beforeFiles.length === 0 && rewrites.fallback.length === 0) {
routesManifest.rewrites = rewrites.afterFiles.map((r)=>buildCustomRoute(r, "rewrite"));
} else {
routesManifest.rewrites = {
beforeFiles: rewrites.beforeFiles.map((r)=>buildCustomRoute(r, "rewrite")),
afterFiles: rewrites.afterFiles.map((r)=>buildCustomRoute(r, "rewrite")),
fallback: rewrites.fallback.map((r)=>buildCustomRoute(r, "rewrite"))
};
}
const combinedRewrites = [
...rewrites.beforeFiles,
...rewrites.afterFiles,
...rewrites.fallback
];
if (config.experimental.clientRouterFilter) {
const nonInternalRedirects = (config._originalRedirects || []).filter((r)=>!r.internal);
const clientRouterFilters = (0, _createclientrouterfilter.createClientRouterFilter)(appPageKeys, config.experimental.clientRouterFilterRedirects ? nonInternalRedirects : [], config.experimental.clientRouterFilterAllowedRate);
_buildcontext.NextBuildContext.clientRouterFilters = clientRouterFilters;
}
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 new Error("> Build directory is not writeable. https://nextjs.org/docs/messages/build-dir-not-writeable");
}
if (config.cleanDistDir && !isGenerate) {
await (0, _recursivedelete.recursiveDelete)(distDir, /^cache/);
}
// Ensure commonjs handling is used for files in the distDir (generally .next)
// Files outside of the distDir can be "type": "module"
await _fs.promises.writeFile(_path.default.join(distDir, "package.json"), '{"type": "commonjs"}');
// We need to write the manifest with rewrites before build
await nextBuildSpan.traceChild("write-routes-manifest").traceAsyncFn(()=>_fs.promises.writeFile(routesManifestPath, JSON.stringify(routesManifest), "utf8"));
// We need to write a partial prerender manifest to make preview mode settings available in edge middleware
const partialManifest = {
preview: previewProps
};
await _fs.promises.writeFile(_path.default.join(distDir, _constants1.PRERENDER_MANIFEST).replace(/\.json$/, ".js"), `self.__PRERENDER_MANIFEST=${JSON.stringify(JSON.stringify(partialManifest))}`, "utf8");
const outputFileTracingRoot = config.experimental.outputFileTracingRoot || dir;
const manifestPath = _path.default.join(distDir, _constants1.SERVER_DIRECTORY, _constants1.PAGES_MANIFEST);
const { incrementalCacheHandlerPath } = config.experimental;
const requiredServerFiles = nextBuildSpan.traceChild("generate-required-server-files").traceFn(()=>({
version: 1,
config: {
...config,
configFile: undefined,
..._ciinfo.hasNextSupport ? {
compress: false
} : {},
experimental: {
...config.experimental,
trustHostHeader: _ciinfo.hasNextSupport,
incrementalCacheHandlerPath: incrementalCacheHandlerPath ? _path.default.relative(distDir, incrementalCacheHandlerPath) : undefined
}
},
appDir: dir,
relativeAppDir: _path.default.relative(outputFileTracingRoot, dir),
files: [
_constants1.ROUTES_MANIFEST,
_path.default.relative(distDir, manifestPath),
_constants1.BUILD_MANIFEST,
_constants1.PRERENDER_MANIFEST,
_constants1.PRERENDER_MANIFEST.replace(/\.json$/, ".js"),
_path.default.join(_constants1.SERVER_DIRECTORY, _constants1.MIDDLEWARE_MANIFEST),
_path.default.join(_constants1.SERVER_DIRECTORY, _constants1.MIDDLEWARE_BUILD_MANIFEST + ".js"),
_path.default.join(_constants1.SERVER_DIRECTORY, _constants1.MIDDLEWARE_REACT_LOADABLE_MANIFEST + ".js"),
...appDir ? [
...config.experimental.sri ? [
_path.default.join(_constants1.SERVER_DIRECTORY, _constants1.SUBRESOURCE_INTEGRITY_MANIFEST + ".js"),
_path.default.join(_constants1.SERVER_DIRECTORY, _constants1.SUBRESOURCE_INTEGRITY_MANIFEST + ".json")
] : [],
_path.default.join(_constants1.SERVER_DIRECTORY, _constants1.APP_PATHS_MANIFEST),
_path.default.join(_constants1.APP_PATH_ROUTES_MANIFEST),
_constants1.APP_BUILD_MANIFEST,
_path.default.join(_constants1.SERVER_DIRECTORY, _constants1.SERVER_REFERENCE_MANIFEST + ".js"),
_path.default.join(_constants1.SERVER_DIRECTORY, _constants1.SERVER_REFERENCE_MANIFEST + ".json")
] : [],
_constants1.REACT_LOADABLE_MANIFEST,
config.optimizeFonts ? _path.default.join(_constants1.SERVER_DIRECTORY, _constants1.FONT_MANIFEST) : null,
_constants1.BUILD_ID_FILE,
_path.default.join(_constants1.SERVER_DIRECTORY, _constants1.NEXT_FONT_MANIFEST + ".js"),
_path.default.join(_constants1.SERVER_DIRECTORY, _constants1.NEXT_FONT_MANIFEST + ".json"),
...hasInstrumentationHook ? [
_path.default.join(_constants1.SERVER_DIRECTORY, `${_constants.INSTRUMENTATION_HOOK_FILENAME}.js`),
_path.default.join(_constants1.SERVER_DIRECTORY, `edge-${_constants.INSTRUMENTATION_HOOK_FILENAME}.js`)
] : []
].filter(_nonnullable.nonNullable).map((file)=>_path.default.join(config.distDir, file)),
ignore: []
}));
let binding = await (0, _swc.loadBindings)();
async function turbopackBuild() {
const turboNextBuildStart = process.hrtime();
const turboJson = _findup.default.sync("turbo.json", {
cwd: dir
});
// eslint-disable-next-line no-shadow
const packagePath = _findup.default.sync("package.json", {
cwd: dir
});
let root = turboNextBuildRoot ?? (turboJson ? _path.default.dirname(turboJson) : packagePath ? _path.default.dirname(packagePath) : undefined);
await binding.turbo.nextBuild({
..._buildcontext.NextBuildContext,
root
});
const [duration] = process.hrtime(turboNextBuildStart);
return {
duration,
turbotraceContext: null
};
}
let runTurbotrace = async (_staticPages)=>{};
let turboTasksForTrace;
if (!isGenerate) {
const { duration: webpackBuildDuration , turbotraceContext } = turboNextBuild ? await turbopackBuild() : await (0, _webpackbuild.webpackBuild)();
telemetry.record((0, _events.eventBuildCompleted)(pagesPaths, {
durationInSeconds: webpackBuildDuration,
totalAppPagesCount
}));
runTurbotrace = async function(staticPages) {
if (!turbotraceContext) {
return;
}
if (!(binding == null ? void 0 : binding.isWasm) && typeof binding.turbo.startTrace === "function") {
var _config_experimental_turbotrace;
let turbotraceOutputPath;
let turbotraceFiles;
turboTasksForTrace = binding.turbo.createTurboTasks((((_config_experimental_turbotrace = config.experimental.turbotrace) == null ? void 0 : _config_experimental_turbotrace.memoryLimit) ?? _constants1.TURBO_TRACE_DEFAULT_MEMORY_LIMIT) * 1024 * 1024);
const { entriesTrace , chunksTrace } = turbotraceContext;
if (entriesTrace) {
const { appDir: turbotraceContextAppDir , depModArray , entryNameMap , outputPath , action } = entriesTrace;
const depModSet = new Set(depModArray);
const filesTracedInEntries = await binding.turbo.startTrace(action, turboTasksForTrace);
const { contextDirectory , input: entriesToTrace } = action;
// only trace the assets under the appDir
// exclude files from node_modules, entries and processed by webpack
const filesTracedFromEntries = filesTracedInEntries.map((f)=>_path.default.join(contextDirectory, f)).filter((f)=>!f.includes("/node_modules/") && f.startsWith(turbotraceContextAppDir) && !entriesToTrace.includes(f) && !depModSet.has(f));
if (filesTracedFromEntries.length) {
// The turbo trace doesn't provide the traced file type and reason at present
// let's write the traced files into the first [entry].nft.json
const [[, entryName]] = Array.from(entryNameMap.entries()).filter(([k])=>k.startsWith(turbotraceContextAppDir));
const traceOutputPath = _path.default.join(outputPath, `../${entryName}.js.nft.json`);
const traceOutputDir = _path.default.dirname(traceOutputPath);
turbotraceOutputPath = traceOutputPath;
turbotraceFiles = filesTracedFromEntries.map((file)=>_path.default.relative(traceOutputDir, file));
}
}
if (chunksTrace) {
const { action , outputPath } = chunksTrace;
action.input = action.input.filter((f)=>{
const outputPagesPath = _path.default.join(outputPath, "..", "pages");
return !f.startsWith(outputPagesPath) || !staticPages.has(// strip `outputPagesPath` and file ext from absolute
f.substring(outputPagesPath.length, f.length - 3));
});
await binding.turbo.startTrace(action, turboTasksForTrace);
if (turbotraceOutputPath && turbotraceFiles) {
const existedNftFile = await _fs.promises.readFile(turbotraceOutputPath, "utf8").then((existedContent)=>JSON.parse(existedContent)).catch(()=>({
version: _constants1.TRACE_OUTPUT_VERSION,
files: []
}));
existedNftFile.files.push(...turbotraceFiles);
const filesSet = new Set(existedNftFile.files);
existedNftFile.files = [
...filesSet
];
await _fs.promises.writeFile(turbotraceOutputPath, JSON.stringify(existedNftFile), "utf8");
}
}
}
};
}
// For app directory, we run type checking after build.
if (appDir && !(isCompile || isGenerate)) {
await (0, _typecheck.startTypeChecking)(typeCheckingOptions);
}
const postCompileSpinner = (0, _spinner.default)({
prefixText: `${_log.prefixes.info} Collecting page data`
});
const buildManifestPath = _path.default.join(distDir, _constants1.BUILD_MANIFEST);
const appBuildManifestPath = _path.default.join(distDir, _constants1.APP_BUILD_MANIFEST);
let staticAppPagesCount = 0;
let serverAppPagesCount = 0;
let edgeRuntimeAppCount = 0;
let edgeRuntimePagesCount = 0;
const ssgPages = new Set();
const ssgStaticFallbackPages = new Set();
const ssgBlockingFallbackPages = new Set();
const staticPages = new Set();
const invalidPages = new Set();
const hybridAmpPages = new Set();
const serverPropsPages = new Set();
const additionalSsgPaths = new Map();
const additionalSsgPathsEncoded = new Map();
const appStaticPaths = new Map();
const appStaticPathsEncoded = new Map();
const appNormalizedPaths = new Map();
const appDynamicParamPaths = new Set();
const appDefaultConfigs = new Map();
const pageInfos = new Map();
const pagesManifest = JSON.parse(await _fs.promises.readFile(manifestPath, "utf8"));
const buildManifest = JSON.parse(await _fs.promises.readFile(buildManifestPath, "utf8"));
const appBuildManifest = appDir ? JSON.parse(await _fs.promises.readFile(appBuildManifestPath, "utf8")) : undefined;
const timeout = config.staticPageGenerationTimeout || 0;
const sharedPool = config.experimental.sharedPool || false;
const staticWorkerPath = sharedPool ? require.resolve("./worker") : require.resolve("./utils");
let appPathsManifest = {};
const appPathRoutes = {};
if (appDir) {
appPathsManifest = JSON.parse(await _fs.promises.readFile(_path.default.join(distDir, _constants1.SERVER_DIRECTORY, _constants1.APP_PATHS_MANIFEST), "utf8"));
Object.keys(appPathsManifest).forEach((entry)=>{
appPathRoutes[entry] = (0, _apppaths.normalizeAppPath)(entry);
});
await _fs.promises.writeFile(_path.default.join(distDir, _constants1.APP_PATH_ROUTES_MANIFEST), JSON.stringify(appPathRoutes, null, 2));
}
process.env.NEXT_PHASE = _constants1.PHASE_PRODUCTION_BUILD;
const numWorkers = config.experimental.memoryBasedWorkersCount ? Math.max(config.experimental.cpus !== _configshared.defaultConfig.experimental.cpus ? config.experimental.cpus : Math.min(config.experimental.cpus || 1, Math.floor(_os.default.freemem() / 1e9)), // enforce a minimum of 4 workers
4) : config.experimental.cpus || 4;
function createStaticWorker(type, ipcPort, ipcValidationKey) {
let infoPrinted = false;
return new _worker.Worker(staticWorkerPath, {
timeout: timeout * 1000,
onRestart: (method, [arg], attempts)=>{
if (method === "exportPage") {
const { path: pagePath } = arg;
if (attempts >= 3) {
throw new Error(`Static page generation for ${pagePath} is still timing out after 3 attempts. See more info here https://nextjs.org/docs/messages/static-page-generation-timeout`);
}
_log.warn(`Restarted static page generation for ${pagePath} because it took more than ${timeout} seconds`);
} else {
const pagePath = arg;
if (attempts >= 2) {
throw new Error(`Collecting page data for ${pagePath} is still timing out after 2 attempts. See more info here https://nextjs.org/docs/messages/page-data-collection-timeout`);
}
_log.warn(`Restarted collecting page data for ${pagePath} because it took more than ${timeout} seconds`);
}
if (!infoPrinted) {
_log.warn("See more info here https://nextjs.org/docs/messages/static-page-generation-timeout");
infoPrinted = true;
}
},
numWorkers,
forkOptions: {
env: {
...process.env,
__NEXT_INCREMENTAL_CACHE_IPC_PORT: ipcPort + "",
__NEXT_INCREMENTAL_CACHE_IPC_KEY: ipcValidationKey,
__NEXT_PRIVATE_PREBUNDLED_REACT: type === "app" ? config.experimental.serverActions ? "experimental" : "next" : ""
}
},
enableWorkerThreads: config.experimental.workerThreads,
exposedMethods: sharedPool ? [
"hasCustomGetInitialProps",
"isPageStatic",
"getDefinedNamedExports",
"exportPage"
] : [
"hasCustomGetInitialProps",
"isPageStatic",
"getDefinedNamedExports"
]
});
}
let CacheHandler;
if (incrementalCacheHandlerPath) {
CacheHandler = require(_path.default.isAbsolute(incrementalCacheHandlerPath) ? incrementalCacheHandlerPath : _path.default.join(dir, incrementalCacheHandlerPath));
}
const { ipcPort , ipcValidationKey } = await (0, _incrementalcacheserver.initialize)({
fs: _nodefsmethods.nodeFs,
dev: false,
appDir: isAppDirEnabled,
fetchCache: isAppDirEnabled,
flushToDisk: config.experimental.isrFlushToDisk,
serverDistDir: _path.default.join(distDir, "server"),
fetchCacheKeyPrefix: config.experimental.fetchCacheKeyPrefix,
maxMemoryCacheSize: config.experimental.isrMemoryCacheSize,
getPrerenderManifest: ()=>({
version: -1,
routes: {},
dynamicRoutes: {},
notFoundRoutes: [],
preview: null
}),
requestHeaders: {},
CurCacheHandler: CacheHandler,
minimalMode: _ciinfo.hasNextSupport,
allowedRevalidateHeaderKeys: config.experimental.allowedRevalidateHeaderKeys
});
const pagesStaticWorkers = createStaticWorker("pages", ipcPort, ipcValidationKey);
const appStaticWorkers = isAppDirEnabled ? createStaticWorker("app", ipcPort, ipcValidationKey) : undefined;
const analysisBegin = process.hrtime();
const staticCheckSpan = nextBuildSpan.traceChild("static-check");
const functionsConfigManifest = {};
const { customAppGetInitialProps , namedExports , isNextImageImported , hasSsrAmpPages , hasNonStaticErrorPage } = await staticCheckSpan.traceAsyncFn(async ()=>{
if (isCompile) {
return {
customAppGetInitialProps: false,
namedExports: [],
isNextImageImported: true,
hasSsrAmpPages: !!pagesDir,
hasNonStaticErrorPage: true
};
}
const { configFileName , publicRuntimeConfig , serverRuntimeConfig } = config;
const runtimeEnvConfig = {
publicRuntimeConfig,
serverRuntimeConfig
};
const nonStaticErrorPageSpan = staticCheckSpan.traceChild("check-static-error-page");
const errorPageHasCustomGetInitialProps = nonStaticErrorPageSpan.traceAsyncFn(async ()=>hasCustomErrorPage && await pagesStaticWorkers.hasCustomGetInitialProps("/_error", distDir, runtimeEnvConfig, false));
const errorPageStaticResult = nonStaticErrorPageSpan.traceAsyncFn(async ()=>{
var _config_i18n, _config_i18n1;
return hasCustomErrorPage && pagesStaticWorkers.isPageStatic({
page: "/_error",
distDir,
configFileName,
runtimeEnvConfig,
httpAgentOptions: config.httpAgentOptions,
locales: (_config_i18n = config.i18n) == null ? void 0 : _config_i18n.locales,
defaultLocale: (_config_i18n1 = config.i18n) == null ? void 0 : _config_i18n1.defaultLocale,
nextConfigOutput: config.output
});
});
const appPageToCheck = "/_app";
const customAppGetInitialPropsPromise = pagesStaticWorkers.hasCustomGetInitialProps(appPageToCheck, distDir, runtimeEnvConfig, true);
const namedExportsPromise = pagesStaticWorkers.getDefinedNamedExports(appPageToCheck, distDir, runtimeEnvConfig);
// eslint-disable-next-line @typescript-eslint/no-shadow
let isNextImageImported;
// eslint-disable-next-line @typescript-eslint/no-shadow
let hasSsrAmpPages = false;
const computedManifestData = await (0, _utils1.computeFromManifest)({
build: buildManifest,
app: appBuildManifest
}, distDir, config.experimental.gzipSize);
const middlewareManifest = require(_path.default.join(distDir, _constants1.SERVER_DIRECTORY, _constants1.MIDDLEWARE_MANIFEST));
const actionManifest = appDir ? require(_path.default.join(distDir, _constants1.SERVER_DIRECTORY, _constants1.SERVER_REFERENCE_MANIFEST + ".json")) : null;
const entriesWithAction = actionManifest ? new Set() : null;
if (actionManifest && entriesWithAction) {
for(const id in actionManifest.node){
for(const entry in actionManifest.node[id].workers){
entriesWithAction.add(entry);
}
}
for(const id in actionManifest.edge){
for(const entry in actionManifest.edge[id].workers){
entriesWithAction.add(entry);
}
}
}
for (const key of Object.keys(middlewareManifest == null ? void