You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			578 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			JavaScript
		
	
		
		
			
		
	
	
			578 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			JavaScript
		
	
| 
											9 months ago
										 | "use strict"; | ||
|  | Object.defineProperty(exports, "__esModule", { | ||
|  |     value: true | ||
|  | }); | ||
|  | Object.defineProperty(exports, "collectBuildTraces", { | ||
|  |     enumerable: true, | ||
|  |     get: function() { | ||
|  |         return collectBuildTraces; | ||
|  |     } | ||
|  | }); | ||
|  | const _trace = require("../trace"); | ||
|  | const _nexttraceentrypointsplugin = require("./webpack/plugins/next-trace-entrypoints-plugin"); | ||
|  | const _constants = require("../shared/lib/constants"); | ||
|  | const _path = /*#__PURE__*/ _interop_require_default(require("path")); | ||
|  | const _promises = /*#__PURE__*/ _interop_require_default(require("fs/promises")); | ||
|  | const _utils = require("./utils"); | ||
|  | const _swc = require("./swc"); | ||
|  | const _nonnullable = require("../lib/non-nullable"); | ||
|  | const _ciinfo = /*#__PURE__*/ _interop_require_wildcard(require("../telemetry/ci-info")); | ||
|  | const _debug = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/debug")); | ||
|  | const _micromatch = require("next/dist/compiled/micromatch"); | ||
|  | const _requirehook = require("../server/require-hook"); | ||
|  | const _nft = require("next/dist/compiled/@vercel/nft"); | ||
|  | const _normalizepagepath = require("../shared/lib/page-path/normalize-page-path"); | ||
|  | const _apppaths = require("../shared/lib/router/utils/app-paths"); | ||
|  | const _iserror = /*#__PURE__*/ _interop_require_default(require("../lib/is-error")); | ||
|  | 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; | ||
|  | } | ||
|  | const debug = (0, _debug.default)("next:build:build-traces"); | ||
|  | function shouldIgnore(file, serverIgnoreFn, reasons, cachedIgnoreFiles, children = new Set()) { | ||
|  |     if (cachedIgnoreFiles.has(file)) { | ||
|  |         return cachedIgnoreFiles.get(file); | ||
|  |     } | ||
|  |     if (serverIgnoreFn(file)) { | ||
|  |         cachedIgnoreFiles.set(file, true); | ||
|  |         return true; | ||
|  |     } | ||
|  |     children.add(file); | ||
|  |     const reason = reasons.get(file); | ||
|  |     if (!reason || reason.parents.size === 0 || reason.type.includes("initial")) { | ||
|  |         cachedIgnoreFiles.set(file, false); | ||
|  |         return false; | ||
|  |     } | ||
|  |     // if all parents are ignored the child file
 | ||
|  |     // should be ignored as well
 | ||
|  |     let allParentsIgnored = true; | ||
|  |     for (const parent of reason.parents.values()){ | ||
|  |         if (!children.has(parent)) { | ||
|  |             children.add(parent); | ||
|  |             if (!shouldIgnore(parent, serverIgnoreFn, reasons, cachedIgnoreFiles, children)) { | ||
|  |                 allParentsIgnored = false; | ||
|  |                 break; | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  |     cachedIgnoreFiles.set(file, allParentsIgnored); | ||
|  |     return allParentsIgnored; | ||
|  | } | ||
|  | async function collectBuildTraces({ dir, config, distDir, pageInfos, staticPages, nextBuildSpan = new _trace.Span({ | ||
|  |     name: "build" | ||
|  | }), hasSsrAmpPages, buildTraceContext, outputFileTracingRoot }) { | ||
|  |     const startTime = Date.now(); | ||
|  |     debug("starting build traces"); | ||
|  |     let turboTasksForTrace; | ||
|  |     let bindings = await (0, _swc.loadBindings)(); | ||
|  |     const runTurbotrace = async function() { | ||
|  |         if (!config.experimental.turbotrace || !buildTraceContext) { | ||
|  |             return; | ||
|  |         } | ||
|  |         if (!(bindings == null ? void 0 : bindings.isWasm) && typeof bindings.turbo.startTrace === "function") { | ||
|  |             var _config_experimental_turbotrace; | ||
|  |             let turbotraceOutputPath; | ||
|  |             let turbotraceFiles; | ||
|  |             turboTasksForTrace = bindings.turbo.createTurboTasks((((_config_experimental_turbotrace = config.experimental.turbotrace) == null ? void 0 : _config_experimental_turbotrace.memoryLimit) ?? _constants.TURBO_TRACE_DEFAULT_MEMORY_LIMIT) * 1024 * 1024); | ||
|  |             const { entriesTrace, chunksTrace } = buildTraceContext; | ||
|  |             if (entriesTrace) { | ||
|  |                 const { appDir: buildTraceContextAppDir, depModArray, entryNameMap, outputPath, action } = entriesTrace; | ||
|  |                 const depModSet = new Set(depModArray); | ||
|  |                 const filesTracedInEntries = await bindings.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(buildTraceContextAppDir) && !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(Object.entries(entryNameMap)).filter(([k])=>k.startsWith(buildTraceContextAppDir)); | ||
|  |                     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.includes(// strip `outputPagesPath` and file ext from absolute
 | ||
|  |                     f.substring(outputPagesPath.length, f.length - 3)); | ||
|  |                 }); | ||
|  |                 await bindings.turbo.startTrace(action, turboTasksForTrace); | ||
|  |                 if (turbotraceOutputPath && turbotraceFiles) { | ||
|  |                     const existedNftFile = await _promises.default.readFile(turbotraceOutputPath, "utf8").then((existedContent)=>JSON.parse(existedContent)).catch(()=>({ | ||
|  |                             version: _constants.TRACE_OUTPUT_VERSION, | ||
|  |                             files: [] | ||
|  |                         })); | ||
|  |                     existedNftFile.files.push(...turbotraceFiles); | ||
|  |                     const filesSet = new Set(existedNftFile.files); | ||
|  |                     existedNftFile.files = [ | ||
|  |                         ...filesSet | ||
|  |                     ]; | ||
|  |                     await _promises.default.writeFile(turbotraceOutputPath, JSON.stringify(existedNftFile), "utf8"); | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |     }; | ||
|  |     const { outputFileTracingIncludes = {}, outputFileTracingExcludes = {} } = config.experimental; | ||
|  |     const excludeGlobKeys = Object.keys(outputFileTracingExcludes); | ||
|  |     const includeGlobKeys = Object.keys(outputFileTracingIncludes); | ||
|  |     await nextBuildSpan.traceChild("node-file-trace-build", { | ||
|  |         isTurbotrace: Boolean(config.experimental.turbotrace) ? "true" : "false" | ||
|  |     }).traceAsyncFn(async ()=>{ | ||
|  |         var _config_experimental_turbotrace, _config_experimental; | ||
|  |         const nextServerTraceOutput = _path.default.join(distDir, "next-server.js.nft.json"); | ||
|  |         const nextMinimalTraceOutput = _path.default.join(distDir, "next-minimal-server.js.nft.json"); | ||
|  |         const root = ((_config_experimental = config.experimental) == null ? void 0 : (_config_experimental_turbotrace = _config_experimental.turbotrace) == null ? void 0 : _config_experimental_turbotrace.contextDirectory) ?? outputFileTracingRoot; | ||
|  |         // Under standalone mode, we need to trace the extra IPC server and
 | ||
|  |         // worker files.
 | ||
|  |         const isStandalone = config.output === "standalone"; | ||
|  |         const nextServerEntry = require.resolve("next/dist/server/next-server"); | ||
|  |         const sharedEntriesSet = [ | ||
|  |             ...config.experimental.turbotrace ? [] : Object.keys(_requirehook.defaultOverrides).map((value)=>require.resolve(value, { | ||
|  |                     paths: [ | ||
|  |                         require.resolve("next/dist/server/require-hook") | ||
|  |                     ] | ||
|  |                 })) | ||
|  |         ]; | ||
|  |         const { cacheHandler } = config; | ||
|  |         // ensure we trace any dependencies needed for custom
 | ||
|  |         // incremental cache handler
 | ||
|  |         if (cacheHandler) { | ||
|  |             sharedEntriesSet.push(require.resolve(_path.default.isAbsolute(cacheHandler) ? cacheHandler : _path.default.join(dir, cacheHandler))); | ||
|  |         } | ||
|  |         const serverEntries = [ | ||
|  |             ...sharedEntriesSet, | ||
|  |             ...isStandalone ? [ | ||
|  |                 require.resolve("next/dist/server/lib/start-server"), | ||
|  |                 require.resolve("next/dist/server/next"), | ||
|  |                 require.resolve("next/dist/server/require-hook") | ||
|  |             ] : [], | ||
|  |             require.resolve("next/dist/server/next-server") | ||
|  |         ].filter(Boolean); | ||
|  |         const minimalServerEntries = [ | ||
|  |             ...sharedEntriesSet, | ||
|  |             require.resolve("next/dist/compiled/next-server/server.runtime.prod") | ||
|  |         ].filter(Boolean); | ||
|  |         const additionalIgnores = new Set(); | ||
|  |         for (const glob of excludeGlobKeys){ | ||
|  |             if ((0, _micromatch.isMatch)("next-server", glob)) { | ||
|  |                 outputFileTracingExcludes[glob].forEach((exclude)=>{ | ||
|  |                     additionalIgnores.add(exclude); | ||
|  |                 }); | ||
|  |             } | ||
|  |         } | ||
|  |         const makeIgnoreFn = (ignores)=>(pathname)=>{ | ||
|  |                 if (_path.default.isAbsolute(pathname) && !pathname.startsWith(root)) { | ||
|  |                     return true; | ||
|  |                 } | ||
|  |                 return (0, _micromatch.isMatch)(pathname, ignores, { | ||
|  |                     contains: true, | ||
|  |                     dot: true | ||
|  |                 }); | ||
|  |             }; | ||
|  |         const sharedIgnores = [ | ||
|  |             "**/next/dist/compiled/next-server/**/*.dev.js", | ||
|  |             isStandalone ? null : "**/next/dist/compiled/jest-worker/**/*", | ||
|  |             "**/next/dist/compiled/webpack/(bundle4|bundle5).js", | ||
|  |             "**/node_modules/webpack5/**/*", | ||
|  |             "**/next/dist/server/lib/route-resolver*", | ||
|  |             "next/dist/compiled/@next/react-dev-overlay/dist/**/*", | ||
|  |             "next/dist/compiled/semver/semver/**/*.js", | ||
|  |             ..._ciinfo.hasNextSupport ? [ | ||
|  |                 // only ignore image-optimizer code when
 | ||
|  |                 // this is being handled outside of next-server
 | ||
|  |                 "**/next/dist/server/image-optimizer.js", | ||
|  |                 "**/next/dist/server/lib/squoosh/**/*.wasm" | ||
|  |             ] : [], | ||
|  |             ...!hasSsrAmpPages ? [ | ||
|  |                 "**/next/dist/compiled/@ampproject/toolbox-optimizer/**/*" | ||
|  |             ] : [], | ||
|  |             ...isStandalone ? [] : _nexttraceentrypointsplugin.TRACE_IGNORES, | ||
|  |             ...additionalIgnores, | ||
|  |             ...config.experimental.outputFileTracingIgnores || [] | ||
|  |         ]; | ||
|  |         const serverIgnores = [ | ||
|  |             ...sharedIgnores, | ||
|  |             "**/node_modules/react{,-dom,-dom-server-turbopack}/**/*.development.js", | ||
|  |             "**/*.d.ts", | ||
|  |             "**/*.map", | ||
|  |             "**/next/dist/pages/**/*", | ||
|  |             ..._ciinfo.hasNextSupport ? [ | ||
|  |                 "**/node_modules/sharp/**/*", | ||
|  |                 "**/@img/sharp-libvips*/**/*" | ||
|  |             ] : [] | ||
|  |         ].filter(_nonnullable.nonNullable); | ||
|  |         const serverIgnoreFn = makeIgnoreFn(serverIgnores); | ||
|  |         const minimalServerIgnores = [ | ||
|  |             ...serverIgnores, | ||
|  |             "**/next/dist/compiled/edge-runtime/**/*", | ||
|  |             "**/next/dist/server/web/sandbox/**/*", | ||
|  |             "**/next/dist/server/post-process.js" | ||
|  |         ]; | ||
|  |         const minimalServerIgnoreFn = makeIgnoreFn(minimalServerIgnores); | ||
|  |         const routesIgnores = [ | ||
|  |             ...sharedIgnores, | ||
|  |             // server chunks are provided via next-trace-entrypoints-plugin plugin
 | ||
|  |             // as otherwise all chunks are traced here and included for all pages
 | ||
|  |             // whether they are needed or not
 | ||
|  |             "**/.next/server/chunks/**", | ||
|  |             "**/next/dist/server/optimize-amp.js", | ||
|  |             "**/next/dist/server/post-process.js" | ||
|  |         ].filter(_nonnullable.nonNullable); | ||
|  |         const routeIgnoreFn = makeIgnoreFn(routesIgnores); | ||
|  |         const traceContext = _path.default.join(nextServerEntry, "..", ".."); | ||
|  |         const serverTracedFiles = new Set(); | ||
|  |         const minimalServerTracedFiles = new Set(); | ||
|  |         function addToTracedFiles(base, file, dest) { | ||
|  |             dest.add(_path.default.relative(distDir, _path.default.join(base, file)).replace(/\\/g, "/")); | ||
|  |         } | ||
|  |         if (isStandalone) { | ||
|  |             addToTracedFiles("", require.resolve("next/dist/compiled/jest-worker/processChild"), serverTracedFiles); | ||
|  |             addToTracedFiles("", require.resolve("next/dist/compiled/jest-worker/threadChild"), serverTracedFiles); | ||
|  |         } | ||
|  |         if (config.experimental.turbotrace) { | ||
|  |             await runTurbotrace(); | ||
|  |             const startTrace = bindings.turbo.startTrace; | ||
|  |             const makeTrace = async (entries)=>{ | ||
|  |                 var _config_experimental_turbotrace, _config_experimental_turbotrace1, _config_experimental_turbotrace2, _config_experimental_turbotrace3; | ||
|  |                 return startTrace({ | ||
|  |                     action: "print", | ||
|  |                     input: entries, | ||
|  |                     contextDirectory: traceContext, | ||
|  |                     logLevel: (_config_experimental_turbotrace = config.experimental.turbotrace) == null ? void 0 : _config_experimental_turbotrace.logLevel, | ||
|  |                     processCwd: (_config_experimental_turbotrace1 = config.experimental.turbotrace) == null ? void 0 : _config_experimental_turbotrace1.processCwd, | ||
|  |                     logDetail: (_config_experimental_turbotrace2 = config.experimental.turbotrace) == null ? void 0 : _config_experimental_turbotrace2.logDetail, | ||
|  |                     showAll: (_config_experimental_turbotrace3 = config.experimental.turbotrace) == null ? void 0 : _config_experimental_turbotrace3.logAll | ||
|  |                 }, turboTasksForTrace); | ||
|  |             }; | ||
|  |             // turbotrace does not handle concurrent tracing
 | ||
|  |             const vanillaFiles = await makeTrace(serverEntries); | ||
|  |             const minimalFiles = await makeTrace(minimalServerEntries); | ||
|  |             for (const [set, files] of [ | ||
|  |                 [ | ||
|  |                     serverTracedFiles, | ||
|  |                     vanillaFiles | ||
|  |                 ], | ||
|  |                 [ | ||
|  |                     minimalServerTracedFiles, | ||
|  |                     minimalFiles | ||
|  |                 ] | ||
|  |             ]){ | ||
|  |                 for (const file of files){ | ||
|  |                     if (!(set === minimalServerTracedFiles ? minimalServerIgnoreFn : serverIgnoreFn)(_path.default.join(traceContext, file))) { | ||
|  |                         addToTracedFiles(traceContext, file, set); | ||
|  |                     } | ||
|  |                 } | ||
|  |             } | ||
|  |         } else { | ||
|  |             var _buildTraceContext_chunksTrace; | ||
|  |             const chunksToTrace = [ | ||
|  |                 ...(buildTraceContext == null ? void 0 : (_buildTraceContext_chunksTrace = buildTraceContext.chunksTrace) == null ? void 0 : _buildTraceContext_chunksTrace.action.input) || [], | ||
|  |                 ...serverEntries, | ||
|  |                 ...minimalServerEntries | ||
|  |             ]; | ||
|  |             const result = await (0, _nft.nodeFileTrace)(chunksToTrace, { | ||
|  |                 base: outputFileTracingRoot, | ||
|  |                 processCwd: dir, | ||
|  |                 mixedModules: true, | ||
|  |                 async readFile (p) { | ||
|  |                     try { | ||
|  |                         return await _promises.default.readFile(p, "utf8"); | ||
|  |                     } catch (e) { | ||
|  |                         if ((0, _iserror.default)(e) && (e.code === "ENOENT" || e.code === "EISDIR")) { | ||
|  |                             // since tracing runs in parallel with static generation server
 | ||
|  |                             // files might be removed from that step so tolerate ENOENT
 | ||
|  |                             // errors gracefully
 | ||
|  |                             return ""; | ||
|  |                         } | ||
|  |                         throw e; | ||
|  |                     } | ||
|  |                 }, | ||
|  |                 async readlink (p) { | ||
|  |                     try { | ||
|  |                         return await _promises.default.readlink(p); | ||
|  |                     } catch (e) { | ||
|  |                         if ((0, _iserror.default)(e) && (e.code === "EINVAL" || e.code === "ENOENT" || e.code === "UNKNOWN")) { | ||
|  |                             return null; | ||
|  |                         } | ||
|  |                         throw e; | ||
|  |                     } | ||
|  |                 }, | ||
|  |                 async stat (p) { | ||
|  |                     try { | ||
|  |                         return await _promises.default.stat(p); | ||
|  |                     } catch (e) { | ||
|  |                         if ((0, _iserror.default)(e) && (e.code === "ENOENT" || e.code === "ENOTDIR")) { | ||
|  |                             return null; | ||
|  |                         } | ||
|  |                         throw e; | ||
|  |                     } | ||
|  |                 } | ||
|  |             }); | ||
|  |             const reasons = result.reasons; | ||
|  |             const fileList = result.fileList; | ||
|  |             for (const file of result.esmFileList){ | ||
|  |                 fileList.add(file); | ||
|  |             } | ||
|  |             const parentFilesMap = (0, _nexttraceentrypointsplugin.getFilesMapFromReasons)(fileList, reasons); | ||
|  |             const cachedLookupIgnore = new Map(); | ||
|  |             const cachedLookupIgnoreMinimal = new Map(); | ||
|  |             for (const [entries, tracedFiles] of [ | ||
|  |                 [ | ||
|  |                     serverEntries, | ||
|  |                     serverTracedFiles | ||
|  |                 ], | ||
|  |                 [ | ||
|  |                     minimalServerEntries, | ||
|  |                     minimalServerTracedFiles | ||
|  |                 ] | ||
|  |             ]){ | ||
|  |                 for (const file of entries){ | ||
|  |                     const curFiles = parentFilesMap.get(_path.default.relative(outputFileTracingRoot, file)); | ||
|  |                     tracedFiles.add(_path.default.relative(distDir, file).replace(/\\/g, "/")); | ||
|  |                     for (const curFile of curFiles || []){ | ||
|  |                         const filePath = _path.default.join(outputFileTracingRoot, curFile); | ||
|  |                         if (!shouldIgnore(curFile, tracedFiles === minimalServerTracedFiles ? minimalServerIgnoreFn : serverIgnoreFn, reasons, tracedFiles === minimalServerTracedFiles ? cachedLookupIgnoreMinimal : cachedLookupIgnore)) { | ||
|  |                             tracedFiles.add(_path.default.relative(distDir, filePath).replace(/\\/g, "/")); | ||
|  |                         } | ||
|  |                     } | ||
|  |                 } | ||
|  |             } | ||
|  |             const { entryNameFilesMap } = (buildTraceContext == null ? void 0 : buildTraceContext.chunksTrace) || {}; | ||
|  |             const cachedLookupIgnoreRoutes = new Map(); | ||
|  |             await Promise.all([ | ||
|  |                 ...entryNameFilesMap ? Object.entries(entryNameFilesMap) : new Map() | ||
|  |             ].map(async ([entryName, entryNameFiles])=>{ | ||
|  |                 const isApp = entryName.startsWith("app/"); | ||
|  |                 const isPages = entryName.startsWith("pages/"); | ||
|  |                 let route = entryName; | ||
|  |                 if (isApp) { | ||
|  |                     route = (0, _apppaths.normalizeAppPath)(route.substring("app".length)); | ||
|  |                 } | ||
|  |                 if (isPages) { | ||
|  |                     route = (0, _normalizepagepath.normalizePagePath)(route.substring("pages".length)); | ||
|  |                 } | ||
|  |                 // we don't need to trace for automatically statically optimized
 | ||
|  |                 // pages as they don't have server bundles
 | ||
|  |                 if (staticPages.includes(route)) { | ||
|  |                     return; | ||
|  |                 } | ||
|  |                 const entryOutputPath = _path.default.join(distDir, "server", `${entryName}.js`); | ||
|  |                 const traceOutputPath = `${entryOutputPath}.nft.json`; | ||
|  |                 const existingTrace = JSON.parse(await _promises.default.readFile(traceOutputPath, "utf8")); | ||
|  |                 const traceOutputDir = _path.default.dirname(traceOutputPath); | ||
|  |                 const curTracedFiles = new Set(); | ||
|  |                 for (const file of [ | ||
|  |                     ...entryNameFiles, | ||
|  |                     entryOutputPath | ||
|  |                 ]){ | ||
|  |                     const curFiles = parentFilesMap.get(_path.default.relative(outputFileTracingRoot, file)); | ||
|  |                     for (const curFile of curFiles || []){ | ||
|  |                         if (!shouldIgnore(curFile, routeIgnoreFn, reasons, cachedLookupIgnoreRoutes)) { | ||
|  |                             const filePath = _path.default.join(outputFileTracingRoot, curFile); | ||
|  |                             const outputFile = _path.default.relative(traceOutputDir, filePath).replace(/\\/g, "/"); | ||
|  |                             curTracedFiles.add(outputFile); | ||
|  |                         } | ||
|  |                     } | ||
|  |                 } | ||
|  |                 for (const file of existingTrace.files || []){ | ||
|  |                     curTracedFiles.add(file); | ||
|  |                 } | ||
|  |                 await _promises.default.writeFile(traceOutputPath, JSON.stringify({ | ||
|  |                     ...existingTrace, | ||
|  |                     files: [ | ||
|  |                         ...curTracedFiles | ||
|  |                     ].sort() | ||
|  |                 })); | ||
|  |             })); | ||
|  |         } | ||
|  |         const moduleTypes = [ | ||
|  |             "app-page", | ||
|  |             "pages" | ||
|  |         ]; | ||
|  |         for (const type of moduleTypes){ | ||
|  |             const modulePath = require.resolve(`next/dist/server/future/route-modules/${type}/module.compiled`); | ||
|  |             const relativeModulePath = _path.default.relative(root, modulePath); | ||
|  |             const contextDir = _path.default.join(_path.default.dirname(modulePath), "vendored", "contexts"); | ||
|  |             for (const item of (await _promises.default.readdir(contextDir))){ | ||
|  |                 const itemPath = _path.default.relative(root, _path.default.join(contextDir, item)); | ||
|  |                 if (!serverIgnoreFn(itemPath)) { | ||
|  |                     addToTracedFiles(root, itemPath, serverTracedFiles); | ||
|  |                     addToTracedFiles(root, itemPath, minimalServerTracedFiles); | ||
|  |                 } | ||
|  |             } | ||
|  |             addToTracedFiles(root, relativeModulePath, serverTracedFiles); | ||
|  |             addToTracedFiles(root, relativeModulePath, minimalServerTracedFiles); | ||
|  |         } | ||
|  |         await Promise.all([ | ||
|  |             _promises.default.writeFile(nextServerTraceOutput, JSON.stringify({ | ||
|  |                 version: 1, | ||
|  |                 files: Array.from(serverTracedFiles) | ||
|  |             })), | ||
|  |             _promises.default.writeFile(nextMinimalTraceOutput, JSON.stringify({ | ||
|  |                 version: 1, | ||
|  |                 files: Array.from(minimalServerTracedFiles) | ||
|  |             })) | ||
|  |         ]); | ||
|  |     }); | ||
|  |     // apply outputFileTracingIncludes/outputFileTracingExcludes after runTurbotrace
 | ||
|  |     const includeExcludeSpan = nextBuildSpan.traceChild("apply-include-excludes"); | ||
|  |     await includeExcludeSpan.traceAsyncFn(async ()=>{ | ||
|  |         const globOrig = require("next/dist/compiled/glob"); | ||
|  |         const glob = (pattern)=>{ | ||
|  |             return new Promise((resolve, reject)=>{ | ||
|  |                 globOrig(pattern, { | ||
|  |                     cwd: dir, | ||
|  |                     nodir: true, | ||
|  |                     dot: true | ||
|  |                 }, (err, files)=>{ | ||
|  |                     if (err) { | ||
|  |                         return reject(err); | ||
|  |                     } | ||
|  |                     resolve(files); | ||
|  |                 }); | ||
|  |             }); | ||
|  |         }; | ||
|  |         const { entryNameFilesMap } = (buildTraceContext == null ? void 0 : buildTraceContext.chunksTrace) || {}; | ||
|  |         const infos = pageInfos instanceof Map ? pageInfos : (0, _utils.deserializePageInfos)(pageInfos); | ||
|  |         await Promise.all([ | ||
|  |             ...entryNameFilesMap ? Object.entries(entryNameFilesMap) : new Map() | ||
|  |         ].map(async ([entryName])=>{ | ||
|  |             const isApp = entryName.startsWith("app/"); | ||
|  |             const isPages = entryName.startsWith("pages/"); | ||
|  |             let route = entryName; | ||
|  |             if (isApp) { | ||
|  |                 route = (0, _apppaths.normalizeAppPath)(entryName); | ||
|  |             } | ||
|  |             if (isPages) { | ||
|  |                 route = (0, _normalizepagepath.normalizePagePath)(entryName); | ||
|  |             } | ||
|  |             if (staticPages.includes(route)) { | ||
|  |                 return; | ||
|  |             } | ||
|  |             // edge routes have no trace files
 | ||
|  |             const pageInfo = infos.get(route); | ||
|  |             if ((pageInfo == null ? void 0 : pageInfo.runtime) === "edge") { | ||
|  |                 return; | ||
|  |             } | ||
|  |             const combinedIncludes = new Set(); | ||
|  |             const combinedExcludes = new Set(); | ||
|  |             for (const curGlob of includeGlobKeys){ | ||
|  |                 if ((0, _micromatch.isMatch)(route, [ | ||
|  |                     curGlob | ||
|  |                 ], { | ||
|  |                     dot: true, | ||
|  |                     contains: true | ||
|  |                 })) { | ||
|  |                     for (const include of outputFileTracingIncludes[curGlob]){ | ||
|  |                         combinedIncludes.add(include.replace(/\\/g, "/")); | ||
|  |                     } | ||
|  |                 } | ||
|  |             } | ||
|  |             for (const curGlob of excludeGlobKeys){ | ||
|  |                 if ((0, _micromatch.isMatch)(route, [ | ||
|  |                     curGlob | ||
|  |                 ], { | ||
|  |                     dot: true, | ||
|  |                     contains: true | ||
|  |                 })) { | ||
|  |                     for (const exclude of outputFileTracingExcludes[curGlob]){ | ||
|  |                         combinedExcludes.add(exclude); | ||
|  |                     } | ||
|  |                 } | ||
|  |             } | ||
|  |             if (!(combinedIncludes == null ? void 0 : combinedIncludes.size) && !(combinedExcludes == null ? void 0 : combinedExcludes.size)) { | ||
|  |                 return; | ||
|  |             } | ||
|  |             const traceFile = _path.default.join(distDir, `server`, `${entryName}.js.nft.json`); | ||
|  |             const pageDir = _path.default.dirname(traceFile); | ||
|  |             const traceContent = JSON.parse(await _promises.default.readFile(traceFile, "utf8")); | ||
|  |             const includes = []; | ||
|  |             const resolvedTraceIncludes = new Map(); | ||
|  |             if (combinedIncludes == null ? void 0 : combinedIncludes.size) { | ||
|  |                 await Promise.all([ | ||
|  |                     ...combinedIncludes | ||
|  |                 ].map(async (includeGlob)=>{ | ||
|  |                     const results = await glob(includeGlob); | ||
|  |                     const resolvedInclude = resolvedTraceIncludes.get(includeGlob) || [ | ||
|  |                         ...results.map((file)=>{ | ||
|  |                             return _path.default.relative(pageDir, _path.default.join(dir, file)); | ||
|  |                         }) | ||
|  |                     ]; | ||
|  |                     includes.push(...resolvedInclude); | ||
|  |                     resolvedTraceIncludes.set(includeGlob, resolvedInclude); | ||
|  |                 })); | ||
|  |             } | ||
|  |             const combined = new Set([ | ||
|  |                 ...traceContent.files, | ||
|  |                 ...includes | ||
|  |             ]); | ||
|  |             if (combinedExcludes == null ? void 0 : combinedExcludes.size) { | ||
|  |                 const resolvedGlobs = [ | ||
|  |                     ...combinedExcludes | ||
|  |                 ].map((exclude)=>_path.default.join(dir, exclude)); | ||
|  |                 combined.forEach((file)=>{ | ||
|  |                     if ((0, _micromatch.isMatch)(_path.default.join(pageDir, file), resolvedGlobs, { | ||
|  |                         dot: true, | ||
|  |                         contains: true | ||
|  |                     })) { | ||
|  |                         combined.delete(file); | ||
|  |                     } | ||
|  |                 }); | ||
|  |             } | ||
|  |             // overwrite trace file with custom includes/excludes
 | ||
|  |             await _promises.default.writeFile(traceFile, JSON.stringify({ | ||
|  |                 version: traceContent.version, | ||
|  |                 files: [ | ||
|  |                     ...combined | ||
|  |                 ] | ||
|  |             })); | ||
|  |         })); | ||
|  |     }); | ||
|  |     debug(`finished build tracing ${Date.now() - startTime}ms`); | ||
|  | } | ||
|  | 
 | ||
|  | //# sourceMappingURL=collect-build-traces.js.map
 |