UNPKG

next

Version:

The React Framework

255 lines (254 loc) • 12.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); 0 && (module.exports = { default: null, generateClientManifest: null, getEntrypointFiles: null, normalizeRewritesForBuildManifest: null, processRoute: null, srcEmptySsgManifest: null }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { // This plugin creates a build-manifest.json for all assets that are being output // It has a mapping of "entry" filename to real filename. Because the real filename can be hashed in production default: function() { return BuildManifestPlugin; }, generateClientManifest: function() { return generateClientManifest; }, getEntrypointFiles: function() { return getEntrypointFiles; }, normalizeRewritesForBuildManifest: function() { return normalizeRewritesForBuildManifest; }, processRoute: function() { return processRoute; }, srcEmptySsgManifest: function() { return srcEmptySsgManifest; } }); const _devalue = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/devalue")); const _webpack = require("next/dist/compiled/webpack/webpack"); const _constants = require("../../../shared/lib/constants"); const _getroutefromentrypoint = /*#__PURE__*/ _interop_require_default(require("../../../server/get-route-from-entrypoint")); const _nextdropclientpageplugin = require("./next-drop-client-page-plugin"); const _utils = require("../../../shared/lib/router/utils"); const _trace = require("../../../trace"); const _utils1 = require("../utils"); function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const srcEmptySsgManifest = `self.__SSG_MANIFEST=new Set;self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB()`; // nodejs: '/static/<build id>/low-priority.js' function buildNodejsLowPriorityPath(filename, buildId) { return `${_constants.CLIENT_STATIC_FILES_PATH}/${buildId}/${filename}`; } function createEdgeRuntimeManifest(originAssetMap) { const manifestFilenames = [ '_buildManifest.js', '_ssgManifest.js' ]; const assetMap = { ...originAssetMap, lowPriorityFiles: [] }; // we use globalThis here because middleware can be node // which doesn't have "self" const manifestDefCode = `globalThis.__BUILD_MANIFEST = ${JSON.stringify(assetMap, null, 2)};\n`; // edge lowPriorityFiles item: '"/static/" + process.env.__NEXT_BUILD_ID + "/low-priority.js"'. // Since lowPriorityFiles is not fixed and relying on `process.env.__NEXT_BUILD_ID`, we'll produce code creating it dynamically. const lowPriorityFilesCode = `globalThis.__BUILD_MANIFEST.lowPriorityFiles = [\n` + manifestFilenames.map((filename)=>{ return `"/static/" + process.env.__NEXT_BUILD_ID + "/${filename}",\n`; }).join(',') + `\n];`; return manifestDefCode + lowPriorityFilesCode; } function normalizeRewrite(item) { return { has: item.has, source: item.source, destination: item.destination }; } function normalizeRewritesForBuildManifest(rewrites) { var _rewrites_afterFiles_map, _rewrites_afterFiles, _rewrites_beforeFiles_map, _rewrites_beforeFiles, _rewrites_fallback_map, _rewrites_fallback; return { afterFiles: (_rewrites_afterFiles = rewrites.afterFiles) == null ? void 0 : (_rewrites_afterFiles_map = _rewrites_afterFiles.map(processRoute)) == null ? void 0 : _rewrites_afterFiles_map.map((item)=>normalizeRewrite(item)), beforeFiles: (_rewrites_beforeFiles = rewrites.beforeFiles) == null ? void 0 : (_rewrites_beforeFiles_map = _rewrites_beforeFiles.map(processRoute)) == null ? void 0 : _rewrites_beforeFiles_map.map((item)=>normalizeRewrite(item)), fallback: (_rewrites_fallback = rewrites.fallback) == null ? void 0 : (_rewrites_fallback_map = _rewrites_fallback.map(processRoute)) == null ? void 0 : _rewrites_fallback_map.map((item)=>normalizeRewrite(item)) }; } function generateClientManifest(assetMap, rewrites, clientRouterFilters, compiler, compilation) { const compilationSpan = compilation ? (0, _utils1.getCompilationSpan)(compilation) : compiler ? (0, _utils1.getCompilationSpan)(compiler) : new _trace.Span({ name: 'client-manifest' }); const genClientManifestSpan = compilationSpan == null ? void 0 : compilationSpan.traceChild('NextJsBuildManifest-generateClientManifest'); return genClientManifestSpan == null ? void 0 : genClientManifestSpan.traceFn(()=>{ const clientManifest = { __rewrites: normalizeRewritesForBuildManifest(rewrites), __routerFilterStatic: clientRouterFilters == null ? void 0 : clientRouterFilters.staticFilter, __routerFilterDynamic: clientRouterFilters == null ? void 0 : clientRouterFilters.dynamicFilter }; const appDependencies = new Set(assetMap.pages['/_app']); const sortedPageKeys = (0, _utils.getSortedRoutes)(Object.keys(assetMap.pages)); sortedPageKeys.forEach((page)=>{ const dependencies = assetMap.pages[page]; if (page === '/_app') return; // Filter out dependencies in the _app entry, because those will have already // been loaded by the client prior to a navigation event const filteredDeps = dependencies.filter((dep)=>!appDependencies.has(dep)); // The manifest can omit the page if it has no requirements if (filteredDeps.length) { clientManifest[page] = filteredDeps; } }); // provide the sorted pages as an array so we don't rely on the object's keys // being in order and we don't slow down look-up time for page assets clientManifest.sortedPages = sortedPageKeys; return (0, _devalue.default)(clientManifest); }); } function getEntrypointFiles(entrypoint) { return (entrypoint == null ? void 0 : entrypoint.getFiles().filter((file)=>{ // We don't want to include `.hot-update.js` files into the initial page return /(?<!\.hot-update)\.(js|css)($|\?)/.test(file); }).map((file)=>file.replace(/\\/g, '/'))) ?? []; } const processRoute = (r)=>{ var _rewrite_destination; const rewrite = { ...r }; // omit external rewrite destinations since these aren't // handled client-side if (!(rewrite == null ? void 0 : (_rewrite_destination = rewrite.destination) == null ? void 0 : _rewrite_destination.startsWith('/'))) { delete rewrite.destination; } return rewrite; }; class BuildManifestPlugin { constructor(options){ this.buildId = options.buildId; this.isDevFallback = !!options.isDevFallback; this.rewrites = { beforeFiles: [], afterFiles: [], fallback: [] }; this.appDirEnabled = options.appDirEnabled; this.clientRouterFilters = options.clientRouterFilters; this.rewrites.beforeFiles = options.rewrites.beforeFiles.map(processRoute); this.rewrites.afterFiles = options.rewrites.afterFiles.map(processRoute); this.rewrites.fallback = options.rewrites.fallback.map(processRoute); } createAssets(compiler, compilation) { const compilationSpan = (0, _utils1.getCompilationSpan)(compilation) ?? (0, _utils1.getCompilationSpan)(compiler); if (!compilationSpan) { throw Object.defineProperty(new Error('No span found for compilation'), "__NEXT_ERROR_CODE", { value: "E646", enumerable: false, configurable: true }); } const createAssetsSpan = compilationSpan.traceChild('NextJsBuildManifest-createassets'); return createAssetsSpan.traceFn(()=>{ const entrypoints = compilation.entrypoints; const assetMap = { polyfillFiles: [], devFiles: [], ampDevFiles: [], lowPriorityFiles: [], rootMainFiles: [], rootMainFilesTree: {}, pages: { '/_app': [] }, ampFirstPages: [] }; const ampFirstEntryNames = _nextdropclientpageplugin.ampFirstEntryNamesMap.get(compilation); if (ampFirstEntryNames) { for (const entryName of ampFirstEntryNames){ const pagePath = (0, _getroutefromentrypoint.default)(entryName); if (!pagePath) { continue; } assetMap.ampFirstPages.push(pagePath); } } const mainFiles = new Set(getEntrypointFiles(entrypoints.get(_constants.CLIENT_STATIC_FILES_RUNTIME_MAIN))); if (this.appDirEnabled) { assetMap.rootMainFiles = [ ...new Set(getEntrypointFiles(entrypoints.get(_constants.CLIENT_STATIC_FILES_RUNTIME_MAIN_APP))) ]; } const compilationAssets = compilation.getAssets(); assetMap.polyfillFiles = compilationAssets.filter((p)=>{ // Ensure only .js files are passed through if (!p.name.endsWith('.js')) { return false; } return p.info && _constants.CLIENT_STATIC_FILES_RUNTIME_POLYFILLS_SYMBOL in p.info; }).map((v)=>v.name); assetMap.devFiles = getEntrypointFiles(entrypoints.get(_constants.CLIENT_STATIC_FILES_RUNTIME_REACT_REFRESH)).filter((file)=>!mainFiles.has(file)); assetMap.ampDevFiles = getEntrypointFiles(entrypoints.get(_constants.CLIENT_STATIC_FILES_RUNTIME_AMP)); for (const entrypoint of compilation.entrypoints.values()){ if (_constants.SYSTEM_ENTRYPOINTS.has(entrypoint.name)) continue; const pagePath = (0, _getroutefromentrypoint.default)(entrypoint.name); if (!pagePath) { continue; } const filesForPage = getEntrypointFiles(entrypoint); assetMap.pages[pagePath] = [ ...new Set([ ...mainFiles, ...filesForPage ]) ]; } if (!this.isDevFallback) { // Add the runtime build manifest file (generated later in this file) // as a dependency for the app. If the flag is false, the file won't be // downloaded by the client. const buildManifestPath = buildNodejsLowPriorityPath('_buildManifest.js', this.buildId); const ssgManifestPath = buildNodejsLowPriorityPath('_ssgManifest.js', this.buildId); assetMap.lowPriorityFiles.push(buildManifestPath, ssgManifestPath); compilation.emitAsset(ssgManifestPath, new _webpack.sources.RawSource(srcEmptySsgManifest)); } assetMap.pages = Object.keys(assetMap.pages).sort().reduce(// eslint-disable-next-line (a, c)=>(a[c] = assetMap.pages[c], a), {}); let buildManifestName = _constants.BUILD_MANIFEST; if (this.isDevFallback) { buildManifestName = `fallback-${_constants.BUILD_MANIFEST}`; } compilation.emitAsset(buildManifestName, new _webpack.sources.RawSource(JSON.stringify(assetMap, null, 2))); compilation.emitAsset(`server/${_constants.MIDDLEWARE_BUILD_MANIFEST}.js`, new _webpack.sources.RawSource(`${createEdgeRuntimeManifest(assetMap)}`)); if (!this.isDevFallback) { compilation.emitAsset(`${_constants.CLIENT_STATIC_FILES_PATH}/${this.buildId}/_buildManifest.js`, new _webpack.sources.RawSource(`self.__BUILD_MANIFEST = ${generateClientManifest(assetMap, this.rewrites, this.clientRouterFilters, compiler, compilation)};self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB()`)); } }); } apply(compiler) { compiler.hooks.make.tap('NextJsBuildManifest', (compilation)=>{ compilation.hooks.processAssets.tap({ name: 'NextJsBuildManifest', stage: _webpack.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS }, ()=>{ this.createAssets(compiler, compilation); }); }); return; } } //# sourceMappingURL=build-manifest-plugin.js.map