UNPKG

next

Version:

The React Framework

353 lines (352 loc) • 15.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPageFromPath = getPageFromPath; exports.createPagesMapping = createPagesMapping; exports.getEdgeServerEntry = getEdgeServerEntry; exports.getAppEntry = getAppEntry; exports.getServerlessEntry = getServerlessEntry; exports.getClientEntry = getClientEntry; exports.createEntrypoints = createEntrypoints; exports.runDependingOnPageType = runDependingOnPageType; exports.finalizeEntrypoint = finalizeEntrypoint; var _chalk = _interopRequireDefault(require("next/dist/compiled/chalk")); var _path = require("path"); var _querystring = require("querystring"); var _constants = require("../lib/constants"); var _constants1 = require("../shared/lib/constants"); var _utils = require("../server/utils"); var _log = require("./output/log"); var _utils1 = require("./utils"); var _getPageStaticInfo = require("./analysis/get-page-static-info"); var _normalizePathSep = require("../shared/lib/page-path/normalize-path-sep"); var _normalizePagePath = require("../shared/lib/page-path/normalize-page-path"); var _utils2 = require("./webpack/loaders/utils"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function getPageFromPath(pagePath, pageExtensions) { let page = (0, _normalizePathSep).normalizePathSep(pagePath.replace(new RegExp(`\\.+(${pageExtensions.join("|")})$`), "")); page = page.replace(/\/index$/, ""); return page === "" ? "/" : page; } function createPagesMapping({ hasServerComponents , isDev , pageExtensions , pagePaths , pagesType }) { const previousPages = {}; const pages = pagePaths.reduce((result, pagePath)=>{ // Do not process .d.ts files inside the `pages` folder if (pagePath.endsWith(".d.ts") && pageExtensions.includes("ts")) { return result; } const pageKey = getPageFromPath(pagePath, pageExtensions); // Assume that if there's a Client Component, that there is // a matching Server Component that will map to the page. // so we will not process it if (hasServerComponents && /\.client$/.test(pageKey)) { return result; } if (pageKey in result) { (0, _log).warn(`Duplicate page detected. ${_chalk.default.cyan((0, _path).join("pages", previousPages[pageKey]))} and ${_chalk.default.cyan((0, _path).join("pages", pagePath))} both resolve to ${_chalk.default.cyan(pageKey)}.`); } else { previousPages[pageKey] = pagePath; } result[pageKey] = (0, _normalizePathSep).normalizePathSep((0, _path).join(pagesType === "pages" ? _constants.PAGES_DIR_ALIAS : pagesType === "app" ? _constants.APP_DIR_ALIAS : _constants.ROOT_DIR_ALIAS, pagePath)); return result; }, {}); if (pagesType !== "pages") { return pages; } if (isDev) { delete pages["/_app"]; delete pages["/_error"]; delete pages["/_document"]; } // In development we always alias these to allow Webpack to fallback to // the correct source file so that HMR can work properly when a file is // added or removed. const root = isDev ? _constants.PAGES_DIR_ALIAS : "next/dist/pages"; return { "/_app": `${root}/_app`, "/_error": `${root}/_error`, "/_document": `${root}/_document`, ...pages }; } function getEdgeServerEntry(opts) { if ((0, _utils1).isMiddlewareFile(opts.page)) { var ref; const loaderParams = { absolutePagePath: opts.absolutePagePath, page: opts.page, // pathMatcher can have special characters that break the loader params // parsing so we base64 encode/decode the string matcherRegexp: Buffer.from(((ref = opts.middleware) == null ? void 0 : ref.pathMatcher) && opts.middleware.pathMatcher.source || "").toString("base64") }; return `next-middleware-loader?${(0, _querystring).stringify(loaderParams)}!`; } if (opts.page.startsWith("/api/") || opts.page === "/api") { const loaderParams = { absolutePagePath: opts.absolutePagePath, page: opts.page }; return `next-edge-function-loader?${(0, _querystring).stringify(loaderParams)}!`; } const loaderParams = { absolute500Path: opts.pages["/500"] || "", absoluteAppPath: opts.pages["/_app"], absoluteDocumentPath: opts.pages["/_document"], absoluteErrorPath: opts.pages["/_error"], absolutePagePath: opts.absolutePagePath, buildId: opts.buildId, dev: opts.isDev, isServerComponent: (0, _utils1).isServerComponentPage(opts.config, opts.absolutePagePath), page: opts.page, stringifiedConfig: JSON.stringify(opts.config) }; return { import: `next-edge-ssr-loader?${(0, _querystring).stringify(loaderParams)}!`, layer: opts.isServerComponent ? "sc_server" : undefined }; } function getAppEntry(opts) { return { import: `next-app-loader?${(0, _querystring).stringify(opts)}!`, layer: "sc_server" }; } function getServerlessEntry(opts) { const loaderParams = { absolute404Path: opts.pages["/404"] || "", absoluteAppPath: opts.pages["/_app"], absoluteDocumentPath: opts.pages["/_document"], absoluteErrorPath: opts.pages["/_error"], absolutePagePath: opts.absolutePagePath, assetPrefix: opts.config.assetPrefix, basePath: opts.config.basePath, buildId: opts.buildId, canonicalBase: opts.config.amp.canonicalBase || "", distDir: _constants.DOT_NEXT_ALIAS, generateEtags: opts.config.generateEtags ? "true" : "", i18n: opts.config.i18n ? JSON.stringify(opts.config.i18n) : "", // base64 encode to make sure contents don't break webpack URL loading loadedEnvFiles: Buffer.from(JSON.stringify(opts.envFiles)).toString("base64"), page: opts.page, poweredByHeader: opts.config.poweredByHeader ? "true" : "", previewProps: JSON.stringify(opts.previewMode), runtimeConfig: Object.keys(opts.config.publicRuntimeConfig).length > 0 || Object.keys(opts.config.serverRuntimeConfig).length > 0 ? JSON.stringify({ publicRuntimeConfig: opts.config.publicRuntimeConfig, serverRuntimeConfig: opts.config.serverRuntimeConfig }) : "" }; return `next-serverless-loader?${(0, _querystring).stringify(loaderParams)}!`; } function getClientEntry(opts) { const loaderOptions = { absolutePagePath: opts.absolutePagePath, page: opts.page }; const pageLoader = `next-client-pages-loader?${(0, _querystring).stringify(loaderOptions)}!`; // Make sure next/router is a dependency of _app or else chunk splitting // might cause the router to not be able to load causing hydration // to fail return opts.page === "/_app" ? [ pageLoader, require.resolve("../client/router") ] : pageLoader; } async function createEntrypoints(params) { const { config , pages , pagesDir , isDev , rootDir , rootPaths , target , appDir , appPaths , pageExtensions , } = params; const edgeServer = {}; const server = {}; const client = {}; const nestedMiddleware = []; let middlewareRegex = undefined; const getEntryHandler = (mappings, pagesType)=>{ return async (page)=>{ const bundleFile = (0, _normalizePagePath).normalizePagePath(page); const clientBundlePath = _path.posix.join(pagesType, bundleFile); const serverBundlePath = pagesType === "pages" ? _path.posix.join("pages", bundleFile) : pagesType === "app" ? _path.posix.join("app", bundleFile) : bundleFile.slice(1); const absolutePagePath = mappings[page]; // Handle paths that have aliases const pageFilePath = (()=>{ if (absolutePagePath.startsWith(_constants.PAGES_DIR_ALIAS)) { return absolutePagePath.replace(_constants.PAGES_DIR_ALIAS, pagesDir); } if (absolutePagePath.startsWith(_constants.APP_DIR_ALIAS) && appDir) { return absolutePagePath.replace(_constants.APP_DIR_ALIAS, appDir); } if (absolutePagePath.startsWith(_constants.ROOT_DIR_ALIAS)) { return absolutePagePath.replace(_constants.ROOT_DIR_ALIAS, rootDir); } return require.resolve(absolutePagePath); })(); /** * When we find a middleware file that is not in the ROOT_DIR we fail. * There is no need to check on `dev` as this should only happen when * building for production. */ if (!absolutePagePath.startsWith(_constants.ROOT_DIR_ALIAS) && /[\\\\/]_middleware$/.test(page)) { nestedMiddleware.push(page); } const isServerComponent = _utils2.serverComponentRegex.test(absolutePagePath); const isInsideAppDir = appDir && absolutePagePath.startsWith(appDir); const staticInfo = await (0, _getPageStaticInfo).getPageStaticInfo({ nextConfig: config, pageFilePath, isDev, page }); if ((0, _utils1).isMiddlewareFile(page)) { var ref, ref1; middlewareRegex = ((ref = staticInfo.middleware) == null ? void 0 : (ref1 = ref.pathMatcher) == null ? void 0 : ref1.source) || ".*"; if (target === "serverless") { throw new _utils1.MiddlewareInServerlessTargetError(); } } runDependingOnPageType({ page, pageRuntime: staticInfo.runtime, onClient: ()=>{ if (isServerComponent || isInsideAppDir) { // We skip the initial entries for server component pages and let the // server compiler inject them instead. } else { client[clientBundlePath] = getClientEntry({ absolutePagePath: mappings[page], page }); } }, onServer: ()=>{ if (pagesType === "app" && appDir) { server[serverBundlePath] = getAppEntry({ name: serverBundlePath, pagePath: mappings[page], appDir, pageExtensions }); } else if ((0, _utils).isTargetLikeServerless(target)) { if (page !== "/_app" && page !== "/_document") { server[serverBundlePath] = getServerlessEntry({ ...params, absolutePagePath: mappings[page], page }); } } else { server[serverBundlePath] = isServerComponent ? { import: mappings[page], layer: "sc_server" } : [ mappings[page] ]; } }, onEdgeServer: ()=>{ edgeServer[serverBundlePath] = getEdgeServerEntry({ ...params, absolutePagePath: mappings[page], bundlePath: clientBundlePath, isDev: false, isServerComponent, page, middleware: staticInfo == null ? void 0 : staticInfo.middleware }); } }); }; }; if (appDir && appPaths) { const entryHandler = getEntryHandler(appPaths, "app"); await Promise.all(Object.keys(appPaths).map(entryHandler)); } if (rootPaths) { await Promise.all(Object.keys(rootPaths).map(getEntryHandler(rootPaths, "root"))); } await Promise.all(Object.keys(pages).map(getEntryHandler(pages, "pages"))); if (nestedMiddleware.length > 0) { throw new _utils1.NestedMiddlewareError(nestedMiddleware, rootDir, pagesDir); } return { client, server, edgeServer, middlewareRegex }; } function runDependingOnPageType(params) { if ((0, _utils1).isMiddlewareFile(params.page)) { return { edgeServer: params.onEdgeServer() }; } else if (params.page.match(_constants.API_ROUTE)) { return params.pageRuntime === _constants.SERVER_RUNTIME.edge ? { edgeServer: params.onEdgeServer() } : { server: params.onServer() }; } else if (params.page === "/_document") { return { server: params.onServer() }; } else if (params.page === "/_app" || params.page === "/_error" || params.page === "/404" || params.page === "/500") { return { client: params.onClient(), server: params.onServer() }; } else { return params.pageRuntime === _constants.SERVER_RUNTIME.edge ? { client: params.onClient(), edgeServer: params.onEdgeServer() } : { client: params.onClient(), server: params.onServer() }; } } function finalizeEntrypoint({ name , compilerType , value , isServerComponent , appDir }) { const entry = typeof value !== "object" || Array.isArray(value) ? { import: value } : value; const isApi = name.startsWith("pages/api/"); if (compilerType === "server") { return { publicPath: isApi ? "" : undefined, runtime: isApi ? "webpack-api-runtime" : "webpack-runtime", layer: isApi ? "api" : isServerComponent ? "sc_server" : undefined, ...entry }; } if (compilerType === "edge-server") { return { layer: (0, _utils1).isMiddlewareFilename(name) || isApi ? "middleware" : undefined, library: { name: [ "_ENTRIES", `middleware_[name]` ], type: "assign" }, runtime: _constants1.EDGE_RUNTIME_WEBPACK, asyncChunks: false, ...entry }; } if (// Client special cases name !== "polyfills" && name !== _constants1.CLIENT_STATIC_FILES_RUNTIME_MAIN && name !== _constants1.CLIENT_STATIC_FILES_RUNTIME_MAIN_APP && name !== _constants1.CLIENT_STATIC_FILES_RUNTIME_AMP && name !== _constants1.CLIENT_STATIC_FILES_RUNTIME_REACT_REFRESH) { // TODO-APP: this is a temporary fix. @shuding is going to change the handling of server components if (appDir && entry.import.includes("flight")) { return { dependOn: _constants1.CLIENT_STATIC_FILES_RUNTIME_MAIN_APP, ...entry }; } return { dependOn: name.startsWith("pages/") && name !== "pages/_app" ? "pages/_app" : _constants1.CLIENT_STATIC_FILES_RUNTIME_MAIN, ...entry }; } return entry; } //# sourceMappingURL=entries.js.map