UNPKG

next

Version:

The React Framework

109 lines (108 loc) 5.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _path = require("path"); var _webpack = require("next/dist/compiled/webpack/webpack"); var _normalizePagePath = require("../../../server/normalize-page-path"); var _constants = require("../../../shared/lib/constants"); var _entries = require("../../entries"); var _middlewarePlugin = require("./middleware-plugin"); const PLUGIN_NAME = 'FunctionsManifestPlugin'; function containsPath(outer, inner) { const rel = (0, _path).relative(outer, inner); return !rel.startsWith('../') && rel !== '..'; } class FunctionsManifestPlugin { constructor({ dev , pagesDir , pageExtensions , isEdgeRuntime }){ this.dev = dev; this.pagesDir = pagesDir; this.isEdgeRuntime = isEdgeRuntime; this.pageExtensions = pageExtensions; this.pagesRuntime = new Map(); } createAssets(compilation, assets, perRoute, isEdgeRuntime) { const functionsManifest = { version: 1, pages: {} }; const infos = (0, _middlewarePlugin).getEntrypointInfo(compilation, perRoute, isEdgeRuntime); infos.forEach((info)=>{ const { page } = info; // TODO: use global default runtime instead of 'web' const pageRuntime = this.pagesRuntime.get(page); const isWebRuntime = pageRuntime === 'edge' || this.isEdgeRuntime && !pageRuntime; functionsManifest.pages[page] = { // Not assign if it's nodejs runtime, project configured node version is used instead ...isWebRuntime && { runtime: 'web' }, ...info }; }); const assetPath = (this.isEdgeRuntime ? '' : 'server/') + _constants.FUNCTIONS_MANIFEST; assets[assetPath] = new _webpack.sources.RawSource(JSON.stringify(functionsManifest, null, 2)); } apply(compiler) { const handler = (parser)=>{ parser.hooks.exportSpecifier.tap(PLUGIN_NAME, (statement, _identifierName, exportName)=>{ const { resource } = parser.state.module; const isPagePath = containsPath(this.pagesDir, resource); // Only parse exported config in pages if (!isPagePath) { return; } const { declaration } = statement; if (exportName === 'config') { const varDecl = declaration.declarations[0]; const { properties } = varDecl.init; const prop = properties.find((p)=>p.key.name === 'runtime' ); if (!prop) return; const runtime = prop.value.value; if (![ 'nodejs', 'edge' ].includes(runtime)) throw new Error(`The runtime option can only be 'nodejs' or 'edge'`); // @ts-ignore buildInfo exists on Module parser.state.module.buildInfo.NEXT_runtime = runtime; } }); }; compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation, { normalModuleFactory: factory })=>{ factory.hooks.parser.for('javascript/auto').tap(PLUGIN_NAME, handler); factory.hooks.parser.for('javascript/esm').tap(PLUGIN_NAME, handler); compilation.hooks.seal.tap(PLUGIN_NAME, ()=>{ for (const entryData of compilation.entries.values()){ for (const dependency of entryData.dependencies){ // @ts-ignore TODO: webpack 5 types const module = compilation.moduleGraph.getModule(dependency); const outgoingConnections = compilation.moduleGraph.getOutgoingConnectionsByModule(module); if (!outgoingConnections) return; const entryModules = outgoingConnections.keys(); for (const mod of entryModules){ var ref; const runtime = mod === null || mod === void 0 ? void 0 : (ref = mod.buildInfo) === null || ref === void 0 ? void 0 : ref.NEXT_runtime; if (runtime) { // @ts-ignore: TODO: webpack 5 types const normalizedPagePath = (0, _normalizePagePath).normalizePagePath(mod.userRequest); const pagePath = normalizedPagePath.replace(this.pagesDir, ''); const page = (0, _entries).getPageFromPath(pagePath, this.pageExtensions); this.pagesRuntime.set(page, runtime); break; } } } } }); }); (0, _middlewarePlugin).collectAssets(compiler, this.createAssets.bind(this), { dev: this.dev, pluginName: PLUGIN_NAME, isEdgeRuntime: this.isEdgeRuntime }); } } exports.default = FunctionsManifestPlugin; //# sourceMappingURL=functions-manifest-plugin.js.map