create project

This commit is contained in:
ismailsosic
2022-12-27 12:05:56 +01:00
parent 2a33a2d3de
commit cd2143287c
16035 changed files with 2489703 additions and 0 deletions

View File

@@ -0,0 +1,173 @@
import { isMiddlewareFilename } from "../../build/utils";
import { nonNullable } from "../../lib/non-nullable";
function isMiddlewareStats(stats) {
for (const key of stats.compilation.entrypoints.keys()){
if (isMiddlewareFilename(key)) {
return true;
}
}
return false;
}
function statsToJson(stats) {
if (!stats) return {};
return stats.toJson({
all: false,
errors: true,
hash: true,
warnings: true
});
}
class EventStream {
constructor(){
this.clients = new Set();
}
everyClient(fn) {
for (const client of this.clients){
fn(client);
}
}
close() {
this.everyClient((client)=>{
client.close();
});
this.clients.clear();
}
handler(client) {
this.clients.add(client);
client.addEventListener("close", ()=>{
this.clients.delete(client);
});
}
publish(payload) {
this.everyClient((client)=>{
client.send(JSON.stringify(payload));
});
}
}
export class WebpackHotMiddleware {
constructor(compilers){
this.eventStream = new EventStream();
this.clientLatestStats = null;
this.middlewareLatestStats = null;
this.serverLatestStats = null;
this.closed = false;
compilers[0].hooks.invalid.tap("webpack-hot-middleware", this.onClientInvalid);
compilers[0].hooks.done.tap("webpack-hot-middleware", this.onClientDone);
compilers[1].hooks.invalid.tap("webpack-hot-middleware", this.onServerInvalid);
compilers[1].hooks.done.tap("webpack-hot-middleware", this.onServerDone);
compilers[2].hooks.done.tap("webpack-hot-middleware", this.onEdgeServerDone);
compilers[2].hooks.invalid.tap("webpack-hot-middleware", this.onEdgeServerInvalid);
}
onClientInvalid = ()=>{
var ref;
if (this.closed || ((ref = this.serverLatestStats) == null ? void 0 : ref.stats.hasErrors())) return;
this.eventStream.publish({
action: "building"
});
};
onClientDone = (statsResult)=>{
var ref;
this.clientLatestStats = {
ts: Date.now(),
stats: statsResult
};
if (this.closed || ((ref = this.serverLatestStats) == null ? void 0 : ref.stats.hasErrors())) return;
this.publishStats("built", statsResult);
};
onServerInvalid = ()=>{
var ref, ref1;
if (!((ref = this.serverLatestStats) == null ? void 0 : ref.stats.hasErrors())) return;
this.serverLatestStats = null;
if ((ref1 = this.clientLatestStats) == null ? void 0 : ref1.stats) {
this.publishStats("built", this.clientLatestStats.stats);
}
};
onServerDone = (statsResult)=>{
if (this.closed) return;
if (statsResult.hasErrors()) {
this.serverLatestStats = {
ts: Date.now(),
stats: statsResult
};
this.publishStats("built", statsResult);
}
};
onEdgeServerInvalid = ()=>{
var ref, ref2;
if (!((ref = this.middlewareLatestStats) == null ? void 0 : ref.stats.hasErrors())) return;
this.middlewareLatestStats = null;
if ((ref2 = this.clientLatestStats) == null ? void 0 : ref2.stats) {
this.publishStats("built", this.clientLatestStats.stats);
}
};
onEdgeServerDone = (statsResult)=>{
if (!isMiddlewareStats(statsResult)) {
this.onServerDone(statsResult);
return;
}
if (statsResult.hasErrors()) {
this.middlewareLatestStats = {
ts: Date.now(),
stats: statsResult
};
this.publishStats("built", statsResult);
}
};
/**
* To sync we use the most recent stats but also we append middleware
* errors. This is because it is possible that middleware fails to compile
* and we still want to show the client overlay with the error while
* the error page should be rendered just fine.
*/ onHMR = (client)=>{
if (this.closed) return;
this.eventStream.handler(client);
const [latestStats] = [
this.clientLatestStats,
this.serverLatestStats
].filter(nonNullable).sort((statsA, statsB)=>statsB.ts - statsA.ts);
if (latestStats == null ? void 0 : latestStats.stats) {
var ref;
const stats = statsToJson(latestStats.stats);
const middlewareStats = statsToJson((ref = this.middlewareLatestStats) == null ? void 0 : ref.stats);
this.eventStream.publish({
action: "sync",
hash: stats.hash,
errors: [
...stats.errors || [],
...middlewareStats.errors || []
],
warnings: [
...stats.warnings || [],
...middlewareStats.warnings || [],
]
});
}
};
publishStats = (action, statsResult)=>{
const stats = statsResult.toJson({
all: false,
hash: true,
warnings: true,
errors: true
});
this.eventStream.publish({
action: action,
hash: stats.hash,
warnings: stats.warnings || [],
errors: stats.errors || []
});
};
publish = (payload)=>{
if (this.closed) return;
this.eventStream.publish(payload);
};
close = ()=>{
if (this.closed) return;
// Can't remove compiler plugins, so we just set a flag and noop if closed
// https://github.com/webpack/tapable/issues/32#issuecomment-350644466
this.closed = true;
this.eventStream.close();
};
}
//# sourceMappingURL=hot-middleware.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,816 @@
import { webpack, StringXor } from "next/dist/compiled/webpack/webpack";
import { getOverlayMiddleware } from "next/dist/compiled/@next/react-dev-overlay/dist/middleware";
import { WebpackHotMiddleware } from "./hot-middleware";
import { join, relative, isAbsolute, posix } from "path";
import { createEntrypoints, createPagesMapping, finalizeEntrypoint, getClientEntry, getEdgeServerEntry, getAppEntry, runDependingOnPageType } from "../../build/entries";
import { watchCompilers } from "../../build/output";
import * as Log from "../../build/output/log";
import getBaseWebpackConfig from "../../build/webpack-config";
import { APP_DIR_ALIAS, WEBPACK_LAYERS } from "../../lib/constants";
import { recursiveDelete } from "../../lib/recursive-delete";
import { BLOCKED_PAGES, COMPILER_NAMES, RSC_MODULE_TYPES } from "../../shared/lib/constants";
import { getPathMatch } from "../../shared/lib/router/utils/path-match";
import { findPageFile } from "../lib/find-page-file";
import { BUILDING, entries, EntryTypes, getInvalidator, onDemandEntryHandler } from "./on-demand-entry-handler";
import { denormalizePagePath } from "../../shared/lib/page-path/denormalize-page-path";
import { normalizePathSep } from "../../shared/lib/page-path/normalize-path-sep";
import getRouteFromEntrypoint from "../get-route-from-entrypoint";
import { fileExists } from "../../lib/file-exists";
import { difference, isMiddlewareFilename } from "../../build/utils";
import { DecodeError } from "../../shared/lib/utils";
import { trace } from "../../trace";
import { getProperError } from "../../lib/is-error";
import ws from "next/dist/compiled/ws";
import { promises as fs } from "fs";
import { getPageStaticInfo } from "../../build/analysis/get-page-static-info";
function diff(a, b) {
return new Set([
...a
].filter((v)=>!b.has(v)));
}
const wsServer = new ws.Server({
noServer: true
});
export async function renderScriptError(res, error, { verbose =true } = {}) {
// Asks CDNs and others to not to cache the errored page
res.setHeader("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate");
if (error.code === "ENOENT") {
res.statusCode = 404;
res.end("404 - Not Found");
return;
}
if (verbose) {
console.error(error.stack);
}
res.statusCode = 500;
res.end("500 - Internal Error");
}
function addCorsSupport(req, res) {
// Only rewrite CORS handling when URL matches a hot-reloader middleware
if (!req.url.startsWith("/__next")) {
return {
preflight: false
};
}
if (!req.headers.origin) {
return {
preflight: false
};
}
res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
res.setHeader("Access-Control-Allow-Methods", "OPTIONS, GET");
// Based on https://github.com/primus/access-control/blob/4cf1bc0e54b086c91e6aa44fb14966fa5ef7549c/index.js#L158
if (req.headers["access-control-request-headers"]) {
res.setHeader("Access-Control-Allow-Headers", req.headers["access-control-request-headers"]);
}
if (req.method === "OPTIONS") {
res.writeHead(200);
res.end();
return {
preflight: true
};
}
return {
preflight: false
};
}
const matchNextPageBundleRequest = getPathMatch("/_next/static/chunks/pages/:path*.js(\\.map|)");
// Recursively look up the issuer till it ends up at the root
function findEntryModule(compilation, issuerModule) {
const issuer = compilation.moduleGraph.getIssuer(issuerModule);
if (issuer) {
return findEntryModule(compilation, issuer);
}
return issuerModule;
}
function erroredPages(compilation) {
const failedPages = {};
for (const error of compilation.errors){
if (!error.module) {
continue;
}
const entryModule = findEntryModule(compilation, error.module);
const { name } = entryModule;
if (!name) {
continue;
}
// Only pages have to be reloaded
const enhancedName = getRouteFromEntrypoint(name);
if (!enhancedName) {
continue;
}
if (!failedPages[enhancedName]) {
failedPages[enhancedName] = [];
}
failedPages[enhancedName].push(error);
}
return failedPages;
}
export default class HotReloader {
clientError = null;
serverError = null;
pagesMapping = {};
constructor(dir, { config , pagesDir , distDir , buildId , previewProps , rewrites , appDir }){
this.buildId = buildId;
this.dir = dir;
this.interceptors = [];
this.pagesDir = pagesDir;
this.appDir = appDir;
this.distDir = distDir;
this.clientStats = null;
this.serverStats = null;
this.edgeServerStats = null;
this.serverPrevDocumentHash = null;
this.config = config;
this.hasServerComponents = !!this.appDir;
this.previewProps = previewProps;
this.rewrites = rewrites;
this.hotReloaderSpan = trace("hot-reloader", undefined, {
version: "13.1.1"
});
// Ensure the hotReloaderSpan is flushed immediately as it's the parentSpan for all processing
// of the current `next dev` invocation.
this.hotReloaderSpan.stop();
}
async run(req, res, parsedUrl) {
// Usually CORS support is not needed for the hot-reloader (this is dev only feature)
// With when the app runs for multi-zones support behind a proxy,
// the current page is trying to access this URL via assetPrefix.
// That's when the CORS support is needed.
const { preflight } = addCorsSupport(req, res);
if (preflight) {
return {};
}
// When a request comes in that is a page bundle, e.g. /_next/static/<buildid>/pages/index.js
// we have to compile the page using on-demand-entries, this middleware will handle doing that
// by adding the page to on-demand-entries, waiting till it's done
// and then the bundle will be served like usual by the actual route in server/index.js
const handlePageBundleRequest = async (pageBundleRes, parsedPageBundleUrl)=>{
const { pathname } = parsedPageBundleUrl;
const params = matchNextPageBundleRequest(pathname);
if (!params) {
return {};
}
let decodedPagePath;
try {
decodedPagePath = `/${params.path.map((param)=>decodeURIComponent(param)).join("/")}`;
} catch (_) {
throw new DecodeError("failed to decode param");
}
const page = denormalizePagePath(decodedPagePath);
if (page === "/_error" || BLOCKED_PAGES.indexOf(page) === -1) {
try {
await this.ensurePage({
page,
clientOnly: true
});
} catch (error) {
await renderScriptError(pageBundleRes, getProperError(error));
return {
finished: true
};
}
const errors = await this.getCompilationErrors(page);
if (errors.length > 0) {
await renderScriptError(pageBundleRes, errors[0], {
verbose: false
});
return {
finished: true
};
}
}
return {};
};
const { finished } = await handlePageBundleRequest(res, parsedUrl);
for (const fn of this.interceptors){
await new Promise((resolve, reject)=>{
fn(req, res, (err)=>{
if (err) return reject(err);
resolve();
});
});
}
return {
finished
};
}
onHMR(req, _res, head) {
wsServer.handleUpgrade(req, req.socket, head, (client)=>{
var ref2, ref1;
(ref2 = this.webpackHotMiddleware) == null ? void 0 : ref2.onHMR(client);
(ref1 = this.onDemandEntries) == null ? void 0 : ref1.onHMR(client);
client.addEventListener("message", ({ data })=>{
data = typeof data !== "string" ? data.toString() : data;
try {
const payload = JSON.parse(data);
let traceChild;
switch(payload.event){
case "client-hmr-latency":
{
traceChild = {
name: payload.event,
startTime: BigInt(payload.startTime * 1000 * 1000),
endTime: BigInt(payload.endTime * 1000 * 1000)
};
break;
}
case "client-reload-page":
case "client-success":
{
traceChild = {
name: payload.event
};
break;
}
case "client-error":
{
traceChild = {
name: payload.event,
attrs: {
errorCount: payload.errorCount
}
};
break;
}
case "client-warning":
{
traceChild = {
name: payload.event,
attrs: {
warningCount: payload.warningCount
}
};
break;
}
case "client-removed-page":
case "client-added-page":
{
traceChild = {
name: payload.event,
attrs: {
page: payload.page || ""
}
};
break;
}
case "client-full-reload":
{
const { event , stackTrace , hadRuntimeError } = payload;
traceChild = {
name: event,
attrs: {
stackTrace: stackTrace ?? ""
}
};
if (hadRuntimeError) {
Log.warn(`Fast Refresh had to perform a full reload due to a runtime error.`);
break;
}
let fileMessage = "";
if (stackTrace) {
var ref;
const file = (ref = /Aborted because (.+) is not accepted/.exec(stackTrace)) == null ? void 0 : ref[1];
if (file) {
fileMessage = ` when ${file} changed`;
}
}
Log.warn(`Fast Refresh had to perform a full reload${fileMessage}. Read more: https://nextjs.org/docs/messages/fast-refresh-reload`);
break;
}
default:
{
break;
}
}
if (traceChild) {
this.hotReloaderSpan.manualTraceChild(traceChild.name, traceChild.startTime || process.hrtime.bigint(), traceChild.endTime || process.hrtime.bigint(), {
...traceChild.attrs,
clientId: payload.id
});
}
} catch (_) {
// invalid WebSocket message
}
});
});
}
async clean(span) {
return span.traceChild("clean").traceAsyncFn(()=>recursiveDelete(join(this.dir, this.config.distDir), /^cache/));
}
async getWebpackConfig(span) {
const webpackConfigSpan = span.traceChild("get-webpack-config");
const pageExtensions = this.config.pageExtensions;
return webpackConfigSpan.traceAsyncFn(async ()=>{
const pagePaths = !this.pagesDir ? [] : await webpackConfigSpan.traceChild("get-page-paths").traceAsyncFn(()=>Promise.all([
findPageFile(this.pagesDir, "/_app", pageExtensions, false),
findPageFile(this.pagesDir, "/_document", pageExtensions, false),
]));
this.pagesMapping = webpackConfigSpan.traceChild("create-pages-mapping").traceFn(()=>createPagesMapping({
isDev: true,
pageExtensions: this.config.pageExtensions,
pagesType: "pages",
pagePaths: pagePaths.filter((i)=>typeof i === "string"),
pagesDir: this.pagesDir
}));
const entrypoints = await webpackConfigSpan.traceChild("create-entrypoints").traceAsyncFn(()=>createEntrypoints({
appDir: this.appDir,
buildId: this.buildId,
config: this.config,
envFiles: [],
isDev: true,
pages: this.pagesMapping,
pagesDir: this.pagesDir,
previewMode: this.previewProps,
rootDir: this.dir,
pageExtensions: this.config.pageExtensions
}));
const commonWebpackOptions = {
dev: true,
buildId: this.buildId,
config: this.config,
pagesDir: this.pagesDir,
rewrites: this.rewrites,
runWebpackSpan: this.hotReloaderSpan,
appDir: this.appDir
};
return webpackConfigSpan.traceChild("generate-webpack-config").traceAsyncFn(()=>Promise.all([
// order is important here
getBaseWebpackConfig(this.dir, {
...commonWebpackOptions,
compilerType: COMPILER_NAMES.client,
entrypoints: entrypoints.client
}),
getBaseWebpackConfig(this.dir, {
...commonWebpackOptions,
compilerType: COMPILER_NAMES.server,
entrypoints: entrypoints.server
}),
getBaseWebpackConfig(this.dir, {
...commonWebpackOptions,
compilerType: COMPILER_NAMES.edgeServer,
entrypoints: entrypoints.edgeServer
}),
]));
});
}
async buildFallbackError() {
if (this.fallbackWatcher) return;
const fallbackConfig = await getBaseWebpackConfig(this.dir, {
runWebpackSpan: this.hotReloaderSpan,
dev: true,
compilerType: COMPILER_NAMES.client,
config: this.config,
buildId: this.buildId,
pagesDir: this.pagesDir,
rewrites: {
beforeFiles: [],
afterFiles: [],
fallback: []
},
isDevFallback: true,
entrypoints: (await createEntrypoints({
appDir: this.appDir,
buildId: this.buildId,
config: this.config,
envFiles: [],
isDev: true,
pages: {
"/_app": "next/dist/pages/_app",
"/_error": "next/dist/pages/_error"
},
pagesDir: this.pagesDir,
previewMode: this.previewProps,
rootDir: this.dir,
pageExtensions: this.config.pageExtensions
})).client
});
const fallbackCompiler = webpack(fallbackConfig);
this.fallbackWatcher = await new Promise((resolve)=>{
let bootedFallbackCompiler = false;
fallbackCompiler.watch(// @ts-ignore webpack supports an array of watchOptions when using a multiCompiler
fallbackConfig.watchOptions, // Errors are handled separately
(_err)=>{
if (!bootedFallbackCompiler) {
bootedFallbackCompiler = true;
resolve(true);
}
});
});
}
async start() {
const startSpan = this.hotReloaderSpan.traceChild("start");
startSpan.stop() // Stop immediately to create an artificial parent span
;
await this.clean(startSpan);
// Ensure distDir exists before writing package.json
await fs.mkdir(this.distDir, {
recursive: true
});
const distPackageJsonPath = join(this.distDir, "package.json");
// Ensure commonjs handling is used for files in the distDir (generally .next)
// Files outside of the distDir can be "type": "module"
await fs.writeFile(distPackageJsonPath, '{"type": "commonjs"}');
this.activeConfigs = await this.getWebpackConfig(startSpan);
for (const config1 of this.activeConfigs){
const defaultEntry = config1.entry;
config1.entry = async (...args)=>{
// @ts-ignore entry is always a function
const entrypoints = await defaultEntry(...args);
const isClientCompilation = config1.name === COMPILER_NAMES.client;
const isNodeServerCompilation = config1.name === COMPILER_NAMES.server;
const isEdgeServerCompilation = config1.name === COMPILER_NAMES.edgeServer;
await Promise.all(Object.keys(entries).map(async (entryKey)=>{
const entryData = entries[entryKey];
const { bundlePath , dispose } = entryData;
const result = /^(client|server|edge-server)(.*)/g.exec(entryKey);
const [, key, page] = result// this match should always happen
;
if (key === COMPILER_NAMES.client && !isClientCompilation) return;
if (key === COMPILER_NAMES.server && !isNodeServerCompilation) return;
if (key === COMPILER_NAMES.edgeServer && !isEdgeServerCompilation) return;
const isEntry = entryData.type === EntryTypes.ENTRY;
const isChildEntry = entryData.type === EntryTypes.CHILD_ENTRY;
// Check if the page was removed or disposed and remove it
if (isEntry) {
const pageExists = !dispose && await fileExists(entryData.absolutePagePath);
if (!pageExists) {
delete entries[entryKey];
return;
}
}
const hasAppDir = !!this.appDir;
const isAppPath = hasAppDir && bundlePath.startsWith("app/");
const staticInfo = isEntry ? await getPageStaticInfo({
pageFilePath: entryData.absolutePagePath,
nextConfig: this.config,
isDev: true,
pageType: isAppPath ? "app" : "pages"
}) : {};
const isServerComponent = isAppPath && staticInfo.rsc !== RSC_MODULE_TYPES.client;
await runDependingOnPageType({
page,
pageRuntime: staticInfo.runtime,
onEdgeServer: ()=>{
// TODO-APP: verify if child entry should support.
if (!isEdgeServerCompilation || !isEntry) return;
const appDirLoader = isAppPath ? getAppEntry({
name: bundlePath,
appPaths: entryData.appPaths,
pagePath: posix.join(APP_DIR_ALIAS, relative(this.appDir, entryData.absolutePagePath).replace(/\\/g, "/")),
appDir: this.appDir,
pageExtensions: this.config.pageExtensions,
rootDir: this.dir,
isDev: true,
tsconfigPath: this.config.typescript.tsconfigPath
}).import : undefined;
entries[entryKey].status = BUILDING;
entrypoints[bundlePath] = finalizeEntrypoint({
compilerType: COMPILER_NAMES.edgeServer,
name: bundlePath,
value: getEdgeServerEntry({
absolutePagePath: entryData.absolutePagePath,
rootDir: this.dir,
buildId: this.buildId,
bundlePath,
config: this.config,
isDev: true,
page,
pages: this.pagesMapping,
isServerComponent,
appDirLoader,
pagesType: isAppPath ? "app" : "pages"
}),
hasAppDir
});
},
onClient: ()=>{
if (!isClientCompilation) return;
if (isChildEntry) {
entries[entryKey].status = BUILDING;
entrypoints[bundlePath] = finalizeEntrypoint({
name: bundlePath,
compilerType: COMPILER_NAMES.client,
value: entryData.request,
hasAppDir
});
} else {
entries[entryKey].status = BUILDING;
entrypoints[bundlePath] = finalizeEntrypoint({
name: bundlePath,
compilerType: COMPILER_NAMES.client,
value: getClientEntry({
absolutePagePath: entryData.absolutePagePath,
page
}),
hasAppDir
});
}
},
onServer: ()=>{
// TODO-APP: verify if child entry should support.
if (!isNodeServerCompilation || !isEntry) return;
entries[entryKey].status = BUILDING;
let relativeRequest = relative(config1.context, entryData.absolutePagePath);
if (!isAbsolute(relativeRequest) && !relativeRequest.startsWith("../")) {
relativeRequest = `./${relativeRequest}`;
}
entrypoints[bundlePath] = finalizeEntrypoint({
compilerType: COMPILER_NAMES.server,
name: bundlePath,
isServerComponent,
value: isAppPath ? getAppEntry({
name: bundlePath,
appPaths: entryData.appPaths,
pagePath: posix.join(APP_DIR_ALIAS, relative(this.appDir, entryData.absolutePagePath).replace(/\\/g, "/")),
appDir: this.appDir,
pageExtensions: this.config.pageExtensions,
rootDir: this.dir,
isDev: true,
tsconfigPath: this.config.typescript.tsconfigPath
}) : relativeRequest,
hasAppDir
});
}
});
}));
return entrypoints;
};
}
// Enable building of client compilation before server compilation in development
// @ts-ignore webpack 5
this.activeConfigs.parallelism = 1;
this.multiCompiler = webpack(this.activeConfigs);
watchCompilers(this.multiCompiler.compilers[0], this.multiCompiler.compilers[1], this.multiCompiler.compilers[2]);
// Watch for changes to client/server page files so we can tell when just
// the server file changes and trigger a reload for GS(S)P pages
const changedClientPages = new Set();
const changedServerPages = new Set();
const changedEdgeServerPages = new Set();
const changedServerComponentPages = new Set();
const changedCSSImportPages = new Set();
const prevClientPageHashes = new Map();
const prevServerPageHashes = new Map();
const prevEdgeServerPageHashes = new Map();
const prevCSSImportModuleHashes = new Map();
const trackPageChanges = (pageHashMap, changedItems, serverComponentChangedItems)=>{
return (stats)=>{
try {
stats.entrypoints.forEach((entry, key)=>{
if (key.startsWith("pages/") || key.startsWith("app/") || isMiddlewareFilename(key)) {
// TODO this doesn't handle on demand loaded chunks
entry.chunks.forEach((chunk)=>{
if (chunk.id === key) {
const modsIterable = stats.chunkGraph.getChunkModulesIterable(chunk);
let hasCSSModuleChanges = false;
let chunksHash = new StringXor();
let chunksHashServerLayer = new StringXor();
modsIterable.forEach((mod)=>{
if (mod.resource && mod.resource.replace(/\\/g, "/").includes(key)) {
var ref, ref3;
// use original source to calculate hash since mod.hash
// includes the source map in development which changes
// every time for both server and client so we calculate
// the hash without the source map for the page module
const hash = require("crypto").createHash("sha256").update(mod.originalSource().buffer()).digest().toString("hex");
if (mod.layer === WEBPACK_LAYERS.server && (mod == null ? void 0 : (ref = mod.buildInfo) == null ? void 0 : (ref3 = ref.rsc) == null ? void 0 : ref3.type) !== "client") {
chunksHashServerLayer.add(hash);
}
chunksHash.add(hash);
} else {
var ref4, ref5, ref6;
// for non-pages we can use the module hash directly
const hash = stats.chunkGraph.getModuleHash(mod, chunk.runtime);
if (mod.layer === WEBPACK_LAYERS.server && (mod == null ? void 0 : (ref4 = mod.buildInfo) == null ? void 0 : (ref5 = ref4.rsc) == null ? void 0 : ref5.type) !== "client") {
chunksHashServerLayer.add(hash);
}
chunksHash.add(hash);
// Both CSS import changes from server and client
// components are tracked.
if (key.startsWith("app/") && ((ref6 = mod.resource) == null ? void 0 : ref6.endsWith(".css"))) {
const prevHash = prevCSSImportModuleHashes.get(mod.resource);
if (prevHash && prevHash !== hash) {
hasCSSModuleChanges = true;
}
prevCSSImportModuleHashes.set(mod.resource, hash);
}
}
});
const prevHash1 = pageHashMap.get(key);
const curHash = chunksHash.toString();
if (prevHash1 && prevHash1 !== curHash) {
changedItems.add(key);
}
pageHashMap.set(key, curHash);
if (serverComponentChangedItems) {
const serverKey = WEBPACK_LAYERS.server + ":" + key;
const prevServerHash = pageHashMap.get(serverKey);
const curServerHash = chunksHashServerLayer.toString();
if (prevServerHash && prevServerHash !== curServerHash) {
serverComponentChangedItems.add(key);
}
pageHashMap.set(serverKey, curServerHash);
}
if (hasCSSModuleChanges) {
changedCSSImportPages.add(key);
}
}
});
}
});
} catch (err) {
console.error(err);
}
};
};
this.multiCompiler.compilers[0].hooks.emit.tap("NextjsHotReloaderForClient", trackPageChanges(prevClientPageHashes, changedClientPages));
this.multiCompiler.compilers[1].hooks.emit.tap("NextjsHotReloaderForServer", trackPageChanges(prevServerPageHashes, changedServerPages, changedServerComponentPages));
this.multiCompiler.compilers[2].hooks.emit.tap("NextjsHotReloaderForServer", trackPageChanges(prevEdgeServerPageHashes, changedEdgeServerPages, changedServerComponentPages));
// This plugin watches for changes to _document.js and notifies the client side that it should reload the page
this.multiCompiler.compilers[1].hooks.failed.tap("NextjsHotReloaderForServer", (err)=>{
this.serverError = err;
this.serverStats = null;
});
this.multiCompiler.compilers[2].hooks.done.tap("NextjsHotReloaderForServer", (stats)=>{
this.serverError = null;
this.edgeServerStats = stats;
});
this.multiCompiler.compilers[1].hooks.done.tap("NextjsHotReloaderForServer", (stats)=>{
this.serverError = null;
this.serverStats = stats;
if (!this.pagesDir) {
return;
}
const { compilation } = stats;
// We only watch `_document` for changes on the server compilation
// the rest of the files will be triggered by the client compilation
const documentChunk = compilation.namedChunks.get("pages/_document");
// If the document chunk can't be found we do nothing
if (!documentChunk) {
console.warn("_document.js chunk not found");
return;
}
// Initial value
if (this.serverPrevDocumentHash === null) {
this.serverPrevDocumentHash = documentChunk.hash || null;
return;
}
// If _document.js didn't change we don't trigger a reload
if (documentChunk.hash === this.serverPrevDocumentHash) {
return;
}
// Notify reload to reload the page, as _document.js was changed (different hash)
this.send("reloadPage");
this.serverPrevDocumentHash = documentChunk.hash || null;
});
this.multiCompiler.hooks.done.tap("NextjsHotReloaderForServer", ()=>{
const serverOnlyChanges = difference(changedServerPages, changedClientPages);
const edgeServerOnlyChanges = difference(changedEdgeServerPages, changedClientPages);
const pageChanges = serverOnlyChanges.concat(edgeServerOnlyChanges).filter((key)=>key.startsWith("pages/"));
const middlewareChanges = Array.from(changedEdgeServerPages).filter((name)=>isMiddlewareFilename(name));
if (middlewareChanges.length > 0) {
this.send({
event: "middlewareChanges"
});
}
if (pageChanges.length > 0) {
this.send({
event: "serverOnlyChanges",
pages: serverOnlyChanges.map((pg)=>denormalizePagePath(pg.slice("pages".length)))
});
}
if (changedServerComponentPages.size || changedCSSImportPages.size) {
this.send({
action: "serverComponentChanges"
});
}
changedClientPages.clear();
changedServerPages.clear();
changedEdgeServerPages.clear();
changedServerComponentPages.clear();
changedCSSImportPages.clear();
});
this.multiCompiler.compilers[0].hooks.failed.tap("NextjsHotReloaderForClient", (err)=>{
this.clientError = err;
this.clientStats = null;
});
this.multiCompiler.compilers[0].hooks.done.tap("NextjsHotReloaderForClient", (stats)=>{
this.clientError = null;
this.clientStats = stats;
const { compilation } = stats;
const chunkNames = new Set([
...compilation.namedChunks.keys()
].filter((name)=>!!getRouteFromEntrypoint(name)));
if (this.prevChunkNames) {
// detect chunks which have to be replaced with a new template
// e.g, pages/index.js <-> pages/_error.js
const addedPages = diff(chunkNames, this.prevChunkNames);
const removedPages = diff(this.prevChunkNames, chunkNames);
if (addedPages.size > 0) {
for (const addedPage of addedPages){
const page = getRouteFromEntrypoint(addedPage);
this.send("addedPage", page);
}
}
if (removedPages.size > 0) {
for (const removedPage of removedPages){
const page = getRouteFromEntrypoint(removedPage);
this.send("removedPage", page);
}
}
}
this.prevChunkNames = chunkNames;
});
this.webpackHotMiddleware = new WebpackHotMiddleware(this.multiCompiler.compilers);
let booted = false;
this.watcher = await new Promise((resolve)=>{
var ref;
const watcher = (ref = this.multiCompiler) == null ? void 0 : ref.watch(// @ts-ignore webpack supports an array of watchOptions when using a multiCompiler
this.activeConfigs.map((config)=>config.watchOptions), // Errors are handled separately
(_err)=>{
if (!booted) {
booted = true;
resolve(watcher);
}
});
});
this.onDemandEntries = onDemandEntryHandler({
multiCompiler: this.multiCompiler,
pagesDir: this.pagesDir,
appDir: this.appDir,
rootDir: this.dir,
nextConfig: this.config,
...this.config.onDemandEntries
});
this.interceptors = [
getOverlayMiddleware({
rootDirectory: this.dir,
stats: ()=>this.clientStats,
serverStats: ()=>this.serverStats,
edgeServerStats: ()=>this.edgeServerStats
}),
];
}
invalidate() {
var ref;
return (ref = getInvalidator()) == null ? void 0 : ref.invalidate();
}
async stop() {
await new Promise((resolve, reject)=>{
this.watcher.close((err)=>err ? reject(err) : resolve(true));
});
if (this.fallbackWatcher) {
await new Promise((resolve, reject)=>{
this.fallbackWatcher.close((err)=>err ? reject(err) : resolve(true));
});
}
this.multiCompiler = undefined;
}
async getCompilationErrors(page) {
var ref9, ref7, ref8;
const getErrors = ({ compilation })=>{
var ref;
const failedPages = erroredPages(compilation);
const normalizedPage = normalizePathSep(page);
// If there is an error related to the requesting page we display it instead of the first error
return ((ref = failedPages[normalizedPage]) == null ? void 0 : ref.length) > 0 ? failedPages[normalizedPage] : compilation.errors;
};
if (this.clientError || this.serverError) {
return [
this.clientError || this.serverError
];
} else if ((ref9 = this.clientStats) == null ? void 0 : ref9.hasErrors()) {
return getErrors(this.clientStats);
} else if ((ref7 = this.serverStats) == null ? void 0 : ref7.hasErrors()) {
return getErrors(this.serverStats);
} else if ((ref8 = this.edgeServerStats) == null ? void 0 : ref8.hasErrors()) {
return getErrors(this.edgeServerStats);
} else {
return [];
}
}
send(action, ...args) {
this.webpackHotMiddleware.publish(action && typeof action === "object" ? action : {
action,
data: args
});
}
async ensurePage({ page , clientOnly , appPaths }) {
var ref;
// Make sure we don't re-build or dispose prebuilt pages
if (page !== "/_error" && BLOCKED_PAGES.indexOf(page) !== -1) {
return;
}
const error = clientOnly ? this.clientError : this.serverError || this.clientError;
if (error) {
return Promise.reject(error);
}
return (ref = this.onDemandEntries) == null ? void 0 : ref.ensurePage({
page,
clientOnly,
appPaths
});
}
};
//# sourceMappingURL=hot-reloader.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,475 @@
import origDebug from "next/dist/compiled/debug";
import { EventEmitter } from "events";
import { findPageFile } from "../lib/find-page-file";
import { runDependingOnPageType } from "../../build/entries";
import { join, posix } from "path";
import { normalizePathSep } from "../../shared/lib/page-path/normalize-path-sep";
import { normalizePagePath } from "../../shared/lib/page-path/normalize-page-path";
import { ensureLeadingSlash } from "../../shared/lib/page-path/ensure-leading-slash";
import { removePagePathTail } from "../../shared/lib/page-path/remove-page-path-tail";
import { reportTrigger } from "../../build/output";
import getRouteFromEntrypoint from "../get-route-from-entrypoint";
import { getPageStaticInfo } from "../../build/analysis/get-page-static-info";
import { isMiddlewareFile, isMiddlewareFilename } from "../../build/utils";
import { PageNotFoundError } from "../../shared/lib/utils";
import { COMPILER_INDEXES, COMPILER_NAMES, RSC_MODULE_TYPES } from "../../shared/lib/constants";
const debug = origDebug("next:on-demand-entry-handler");
/**
* Returns object keys with type inferred from the object key
*/ const keys = Object.keys;
const COMPILER_KEYS = keys(COMPILER_INDEXES);
function treePathToEntrypoint(segmentPath, parentPath) {
const [parallelRouteKey, segment] = segmentPath;
// TODO-APP: modify this path to cover parallelRouteKey convention
const path = (parentPath ? parentPath + "/" : "") + (parallelRouteKey !== "children" && !segment.startsWith("@") ? parallelRouteKey + "/" : "") + (segment === "" ? "page" : segment);
// Last segment
if (segmentPath.length === 2) {
return path;
}
const childSegmentPath = segmentPath.slice(2);
return treePathToEntrypoint(childSegmentPath, path);
}
function convertDynamicParamTypeToSyntax(dynamicParamTypeShort, param) {
switch(dynamicParamTypeShort){
case "c":
return `[...${param}]`;
case "oc":
return `[[...${param}]]`;
case "d":
return `[${param}]`;
default:
throw new Error("Unknown dynamic param type");
}
}
function getEntrypointsFromTree(tree, isFirst, parentPath = []) {
const [segment, parallelRoutes] = tree;
const currentSegment = Array.isArray(segment) ? convertDynamicParamTypeToSyntax(segment[2], segment[0]) : segment;
const currentPath = [
...parentPath,
currentSegment
];
if (!isFirst && currentSegment === "") {
// TODO get rid of '' at the start of tree
return [
treePathToEntrypoint(currentPath.slice(1))
];
}
return Object.keys(parallelRoutes).reduce((paths, key)=>{
const childTree = parallelRoutes[key];
const childPages = getEntrypointsFromTree(childTree, false, [
...currentPath,
key,
]);
return [
...paths,
...childPages
];
}, []);
}
export const ADDED = Symbol("added");
export const BUILDING = Symbol("building");
export const BUILT = Symbol("built");
export var EntryTypes;
(function(EntryTypes) {
EntryTypes[EntryTypes["ENTRY"] = 0] = "ENTRY";
EntryTypes[EntryTypes["CHILD_ENTRY"] = 1] = "CHILD_ENTRY";
})(EntryTypes || (EntryTypes = {}));
export const entries = {};
let invalidator;
export const getInvalidator = ()=>invalidator;
const doneCallbacks = new EventEmitter();
const lastClientAccessPages = [
""
];
const lastServerAccessPagesForAppDir = [
""
];
// Make sure only one invalidation happens at a time
// Otherwise, webpack hash gets changed and it'll force the client to reload.
class Invalidator {
building = new Set();
rebuildAgain = new Set();
constructor(multiCompiler){
this.multiCompiler = multiCompiler;
}
shouldRebuildAll() {
return this.rebuildAgain.size > 0;
}
invalidate(compilerKeys = COMPILER_KEYS) {
for (const key of compilerKeys){
var ref;
// If there's a current build is processing, we won't abort it by invalidating.
// (If aborted, it'll cause a client side hard reload)
// But let it to invalidate just after the completion.
// So, it can re-build the queued pages at once.
if (this.building.has(key)) {
this.rebuildAgain.add(key);
continue;
}
(ref = this.multiCompiler.compilers[COMPILER_INDEXES[key]].watching) == null ? void 0 : ref.invalidate();
this.building.add(key);
}
}
startBuilding(compilerKey) {
this.building.add(compilerKey);
}
doneBuilding() {
const rebuild = [];
for (const key of COMPILER_KEYS){
this.building.delete(key);
if (this.rebuildAgain.has(key)) {
rebuild.push(key);
this.rebuildAgain.delete(key);
}
}
this.invalidate(rebuild);
}
}
function disposeInactiveEntries(maxInactiveAge) {
Object.keys(entries).forEach((entryKey)=>{
const entryData = entries[entryKey];
const { lastActiveTime , status , dispose } = entryData;
// TODO-APP: implement disposing of CHILD_ENTRY
if (entryData.type === 1) {
return;
}
if (dispose) // Skip pages already scheduled for disposing
return;
// This means this entry is currently building or just added
// We don't need to dispose those entries.
if (status !== BUILT) return;
// We should not build the last accessed page even we didn't get any pings
// Sometimes, it's possible our XHR ping to wait before completing other requests.
// In that case, we should not dispose the current viewing page
if (lastClientAccessPages.includes(entryKey) || lastServerAccessPagesForAppDir.includes(entryKey)) return;
if (lastActiveTime && Date.now() - lastActiveTime > maxInactiveAge) {
entries[entryKey].dispose = true;
}
});
}
// Normalize both app paths and page paths
function tryToNormalizePagePath(page) {
try {
return normalizePagePath(page);
} catch (err) {
console.error(err);
throw new PageNotFoundError(page);
}
}
/**
* Attempts to find a page file path from the given pages absolute directory,
* a page and allowed extensions. If the page can't be found it will throw an
* error. It defaults the `/_error` page to Next.js internal error page.
*
* @param rootDir Absolute path to the project root.
* @param pagesDir Absolute path to the pages folder with trailing `/pages`.
* @param normalizedPagePath The page normalized (it will be denormalized).
* @param pageExtensions Array of page extensions.
*/ async function findPagePathData(rootDir, page, extensions, pagesDir, appDir) {
const normalizedPagePath = tryToNormalizePagePath(page);
let pagePath = null;
if (isMiddlewareFile(normalizedPagePath)) {
pagePath = await findPageFile(rootDir, normalizedPagePath, extensions, false);
if (!pagePath) {
throw new PageNotFoundError(normalizedPagePath);
}
const pageUrl = ensureLeadingSlash(removePagePathTail(normalizePathSep(pagePath), {
extensions
}));
return {
absolutePagePath: join(rootDir, pagePath),
bundlePath: normalizedPagePath.slice(1),
page: posix.normalize(pageUrl)
};
}
// Check appDir first falling back to pagesDir
if (appDir) {
pagePath = await findPageFile(appDir, normalizedPagePath, extensions, true);
if (pagePath) {
const pageUrl = ensureLeadingSlash(removePagePathTail(normalizePathSep(pagePath), {
keepIndex: true,
extensions
}));
return {
absolutePagePath: join(appDir, pagePath),
bundlePath: posix.join("app", normalizePagePath(pageUrl)),
page: posix.normalize(pageUrl)
};
}
}
if (!pagePath && pagesDir) {
pagePath = await findPageFile(pagesDir, normalizedPagePath, extensions, false);
}
if (pagePath !== null && pagesDir) {
const pageUrl = ensureLeadingSlash(removePagePathTail(normalizePathSep(pagePath), {
extensions
}));
return {
absolutePagePath: join(pagesDir, pagePath),
bundlePath: posix.join("pages", normalizePagePath(pageUrl)),
page: posix.normalize(pageUrl)
};
}
if (page === "/_error") {
return {
absolutePagePath: require.resolve("next/dist/pages/_error"),
bundlePath: page,
page: normalizePathSep(page)
};
} else {
throw new PageNotFoundError(normalizedPagePath);
}
}
export function onDemandEntryHandler({ maxInactiveAge , multiCompiler , nextConfig , pagesBufferLength , pagesDir , rootDir , appDir }) {
invalidator = new Invalidator(multiCompiler);
const startBuilding = (compilation)=>{
const compilationName = compilation.name;
invalidator.startBuilding(compilationName);
};
for (const compiler of multiCompiler.compilers){
compiler.hooks.make.tap("NextJsOnDemandEntries", startBuilding);
}
function getPagePathsFromEntrypoints(type, entrypoints, root) {
const pagePaths = [];
for (const entrypoint of entrypoints.values()){
const page = getRouteFromEntrypoint(entrypoint.name, root);
if (page) {
pagePaths.push(`${type}${page}`);
} else if (root && entrypoint.name === "root" || isMiddlewareFilename(entrypoint.name)) {
pagePaths.push(`${type}/${entrypoint.name}`);
}
}
return pagePaths;
}
multiCompiler.hooks.done.tap("NextJsOnDemandEntries", (multiStats)=>{
if (invalidator.shouldRebuildAll()) {
return invalidator.doneBuilding();
}
const [clientStats, serverStats, edgeServerStats] = multiStats.stats;
const root = !!appDir;
const pagePaths = [
...getPagePathsFromEntrypoints(COMPILER_NAMES.client, clientStats.compilation.entrypoints, root),
...getPagePathsFromEntrypoints(COMPILER_NAMES.server, serverStats.compilation.entrypoints, root),
...edgeServerStats ? getPagePathsFromEntrypoints(COMPILER_NAMES.edgeServer, edgeServerStats.compilation.entrypoints, root) : [],
];
for (const page of pagePaths){
const entry = entries[page];
if (!entry) {
continue;
}
if (entry.status !== BUILDING) {
continue;
}
entry.status = BUILT;
doneCallbacks.emit(page);
}
invalidator.doneBuilding();
});
const pingIntervalTime = Math.max(1000, Math.min(5000, maxInactiveAge));
setInterval(function() {
disposeInactiveEntries(maxInactiveAge);
}, pingIntervalTime + 1000).unref();
function handleAppDirPing(tree) {
const pages = getEntrypointsFromTree(tree, true);
let toSend = {
invalid: true
};
for (const page of pages){
for (const compilerType of [
COMPILER_NAMES.client,
COMPILER_NAMES.server,
COMPILER_NAMES.edgeServer,
]){
const pageKey = `${compilerType}/${page}`;
const entryInfo = entries[pageKey];
// If there's no entry, it may have been invalidated and needs to be re-built.
if (!entryInfo) {
continue;
}
// We don't need to maintain active state of anything other than BUILT entries
if (entryInfo.status !== BUILT) continue;
// If there's an entryInfo
if (!lastServerAccessPagesForAppDir.includes(pageKey)) {
lastServerAccessPagesForAppDir.unshift(pageKey);
// Maintain the buffer max length
// TODO: verify that the current pageKey is not at the end of the array as multiple entrypoints can exist
if (lastServerAccessPagesForAppDir.length > pagesBufferLength) {
lastServerAccessPagesForAppDir.pop();
}
}
entryInfo.lastActiveTime = Date.now();
entryInfo.dispose = false;
toSend = {
success: true
};
}
}
return toSend;
}
function handlePing(pg) {
const page = normalizePathSep(pg);
let toSend = {
invalid: true
};
for (const compilerType of [
COMPILER_NAMES.client,
COMPILER_NAMES.server,
COMPILER_NAMES.edgeServer,
]){
const pageKey = `${compilerType}${page}`;
const entryInfo = entries[pageKey];
// If there's no entry, it may have been invalidated and needs to be re-built.
if (!entryInfo) {
// if (page !== lastEntry) client pings, but there's no entry for page
if (compilerType === COMPILER_NAMES.client) {
return {
invalid: true
};
}
continue;
}
// 404 is an on demand entry but when a new page is added we have to refresh the page
toSend = page === "/_error" ? {
invalid: true
} : {
success: true
};
// We don't need to maintain active state of anything other than BUILT entries
if (entryInfo.status !== BUILT) continue;
// If there's an entryInfo
if (!lastClientAccessPages.includes(pageKey)) {
lastClientAccessPages.unshift(pageKey);
// Maintain the buffer max length
if (lastClientAccessPages.length > pagesBufferLength) {
lastClientAccessPages.pop();
}
}
entryInfo.lastActiveTime = Date.now();
entryInfo.dispose = false;
}
return toSend;
}
return {
async ensurePage ({ page , clientOnly , appPaths =null }) {
const stalledTime = 60;
const stalledEnsureTimeout = setTimeout(()=>{
debug(`Ensuring ${page} has taken longer than ${stalledTime}s, if this continues to stall this may be a bug`);
}, stalledTime * 1000);
try {
const pagePathData = await findPagePathData(rootDir, page, nextConfig.pageExtensions, pagesDir, appDir);
const isInsideAppDir = !!appDir && pagePathData.absolutePagePath.startsWith(appDir);
const addEntry = (compilerType)=>{
const entryKey = `${compilerType}${pagePathData.page}`;
if (entries[entryKey]) {
entries[entryKey].dispose = false;
entries[entryKey].lastActiveTime = Date.now();
if (entries[entryKey].status === BUILT) {
return {
entryKey,
newEntry: false,
shouldInvalidate: false
};
}
return {
entryKey,
newEntry: false,
shouldInvalidate: true
};
}
entries[entryKey] = {
type: 0,
appPaths,
absolutePagePath: pagePathData.absolutePagePath,
request: pagePathData.absolutePagePath,
bundlePath: pagePathData.bundlePath,
dispose: false,
lastActiveTime: Date.now(),
status: ADDED
};
return {
entryKey: entryKey,
newEntry: true,
shouldInvalidate: true
};
};
const staticInfo = await getPageStaticInfo({
pageFilePath: pagePathData.absolutePagePath,
nextConfig,
isDev: true,
pageType: isInsideAppDir ? "app" : "pages"
});
const added = new Map();
const isServerComponent = isInsideAppDir && staticInfo.rsc !== RSC_MODULE_TYPES.client;
await runDependingOnPageType({
page: pagePathData.page,
pageRuntime: staticInfo.runtime,
onClient: ()=>{
// Skip adding the client entry for app / Server Components.
if (isServerComponent || isInsideAppDir) {
return;
}
added.set(COMPILER_NAMES.client, addEntry(COMPILER_NAMES.client));
},
onServer: ()=>{
added.set(COMPILER_NAMES.server, addEntry(COMPILER_NAMES.server));
const edgeServerEntry = `${COMPILER_NAMES.edgeServer}${pagePathData.page}`;
if (entries[edgeServerEntry]) {
// Runtime switched from edge to server
delete entries[edgeServerEntry];
}
},
onEdgeServer: ()=>{
added.set(COMPILER_NAMES.edgeServer, addEntry(COMPILER_NAMES.edgeServer));
const serverEntry = `${COMPILER_NAMES.server}${pagePathData.page}`;
if (entries[serverEntry]) {
// Runtime switched from server to edge
delete entries[serverEntry];
}
}
});
const addedValues = [
...added.values()
];
const entriesThatShouldBeInvalidated = addedValues.filter((entry)=>entry.shouldInvalidate);
const hasNewEntry = addedValues.some((entry)=>entry.newEntry);
if (hasNewEntry) {
reportTrigger(!clientOnly && hasNewEntry ? `${pagePathData.page} (client and server)` : pagePathData.page);
}
if (entriesThatShouldBeInvalidated.length > 0) {
const invalidatePromises = entriesThatShouldBeInvalidated.map(({ entryKey })=>{
return new Promise((resolve, reject)=>{
doneCallbacks.once(entryKey, (err)=>{
if (err) {
return reject(err);
}
resolve();
});
});
});
invalidator.invalidate([
...added.keys()
]);
await Promise.all(invalidatePromises);
}
} finally{
clearTimeout(stalledEnsureTimeout);
}
},
onHMR (client) {
client.addEventListener("message", ({ data })=>{
try {
const parsedData = JSON.parse(typeof data !== "string" ? data.toString() : data);
if (parsedData.event === "ping") {
const result = parsedData.appDirRoute ? handleAppDirPing(parsedData.tree) : handlePing(parsedData.page);
client.send(JSON.stringify({
...result,
[parsedData.appDirRoute ? "action" : "event"]: "pong"
}));
}
} catch (_) {}
});
}
};
}
//# sourceMappingURL=on-demand-entry-handler.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,60 @@
import "../node-polyfill-fetch";
import { buildAppStaticPaths, buildStaticPaths, collectGenerateParams } from "../../build/utils";
import { loadComponents } from "../load-components";
import { setHttpClientAndAgentOptions } from "../config";
import { loadRequireHook, overrideBuiltInReactPackages } from "../../build/webpack/require-hook";
loadRequireHook();
if (process.env.NEXT_PREBUNDLED_REACT) {
overrideBuiltInReactPackages();
}
let workerWasUsed = false;
// expose AsyncLocalStorage on globalThis for react usage
const { AsyncLocalStorage } = require("async_hooks");
globalThis.AsyncLocalStorage = AsyncLocalStorage;
// we call getStaticPaths in a separate process to ensure
// side-effects aren't relied on in dev that will break
// during a production build
export async function loadStaticPaths({ distDir , pathname , config , httpAgentOptions , enableUndici , locales , defaultLocale , isAppPath , originalAppPath }) {
// we only want to use each worker once to prevent any invalid
// caches
if (workerWasUsed) {
process.exit(1);
}
// update work memory runtime-config
require("../../shared/lib/runtime-config").setConfig(config);
setHttpClientAndAgentOptions({
httpAgentOptions,
experimental: {
enableUndici
}
});
const components = await loadComponents({
distDir,
pathname: originalAppPath || pathname,
hasServerComponents: false,
isAppPath: !!isAppPath
});
if (!components.getStaticPaths && !isAppPath) {
// we shouldn't get to this point since the worker should
// only be called for SSG pages with getStaticPaths
throw new Error(`Invariant: failed to load page with getStaticPaths for ${pathname}`);
}
workerWasUsed = true;
if (isAppPath) {
const generateParams = await collectGenerateParams(components.ComponentMod.tree);
return buildAppStaticPaths({
page: pathname,
generateParams,
configFileName: config.configFileName
});
}
return buildStaticPaths({
page: pathname,
getStaticPaths: components.getStaticPaths,
configFileName: config.configFileName,
locales,
defaultLocale
});
}
//# sourceMappingURL=static-paths-worker.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../server/dev/static-paths-worker.ts"],"names":["buildAppStaticPaths","buildStaticPaths","collectGenerateParams","loadComponents","setHttpClientAndAgentOptions","loadRequireHook","overrideBuiltInReactPackages","process","env","NEXT_PREBUNDLED_REACT","workerWasUsed","AsyncLocalStorage","require","globalThis","loadStaticPaths","distDir","pathname","config","httpAgentOptions","enableUndici","locales","defaultLocale","isAppPath","originalAppPath","exit","setConfig","experimental","components","hasServerComponents","getStaticPaths","Error","generateParams","ComponentMod","tree","page","configFileName"],"mappings":"AAEA,OAAO,wBAAwB,CAAA;AAC/B,SACEA,mBAAmB,EACnBC,gBAAgB,EAChBC,qBAAqB,QAChB,mBAAmB,CAAA;AAC1B,SAASC,cAAc,QAAQ,oBAAoB,CAAA;AACnD,SAASC,4BAA4B,QAAQ,WAAW,CAAA;AACxD,SACEC,eAAe,EACfC,4BAA4B,QACvB,kCAAkC,CAAA;AAIzCD,eAAe,EAAE;AACjB,IAAIE,OAAO,CAACC,GAAG,CAACC,qBAAqB,EAAE;IACrCH,4BAA4B,EAAE;CAC/B;AAED,IAAII,aAAa,GAAG,KAAK;AAEzB,yDAAyD;AACzD,MAAM,EAAEC,iBAAiB,CAAA,EAAE,GAAGC,OAAO,CAAC,aAAa,CAAC,AACnD;AAAA,AAACC,UAAU,CAASF,iBAAiB,GAAGA,iBAAiB;AAE1D,yDAAyD;AACzD,uDAAuD;AACvD,4BAA4B;AAC5B,OAAO,eAAeG,eAAe,CAAC,EACpCC,OAAO,CAAA,EACPC,QAAQ,CAAA,EACRC,MAAM,CAAA,EACNC,gBAAgB,CAAA,EAChBC,YAAY,CAAA,EACZC,OAAO,CAAA,EACPC,aAAa,CAAA,EACbC,SAAS,CAAA,EACTC,eAAe,CAAA,EAWhB,EAIE;IACD,8DAA8D;IAC9D,SAAS;IACT,IAAIb,aAAa,EAAE;QACjBH,OAAO,CAACiB,IAAI,CAAC,CAAC,CAAC;KAChB;IAED,oCAAoC;IACpCZ,OAAO,CAAC,iCAAiC,CAAC,CAACa,SAAS,CAACR,MAAM,CAAC;IAC5Db,4BAA4B,CAAC;QAC3Bc,gBAAgB;QAChBQ,YAAY,EAAE;YAAEP,YAAY;SAAE;KAC/B,CAAC;IAEF,MAAMQ,UAAU,GAAG,MAAMxB,cAAc,CAAC;QACtCY,OAAO;QACPC,QAAQ,EAAEO,eAAe,IAAIP,QAAQ;QACrCY,mBAAmB,EAAE,KAAK;QAC1BN,SAAS,EAAE,CAAC,CAACA,SAAS;KACvB,CAAC;IAEF,IAAI,CAACK,UAAU,CAACE,cAAc,IAAI,CAACP,SAAS,EAAE;QAC5C,yDAAyD;QACzD,mDAAmD;QACnD,MAAM,IAAIQ,KAAK,CACb,CAAC,uDAAuD,EAAEd,QAAQ,CAAC,CAAC,CACrE,CAAA;KACF;IACDN,aAAa,GAAG,IAAI;IAEpB,IAAIY,SAAS,EAAE;QACb,MAAMS,cAAc,GAAG,MAAM7B,qBAAqB,CAChDyB,UAAU,CAACK,YAAY,CAACC,IAAI,CAC7B;QACD,OAAOjC,mBAAmB,CAAC;YACzBkC,IAAI,EAAElB,QAAQ;YACde,cAAc;YACdI,cAAc,EAAElB,MAAM,CAACkB,cAAc;SACtC,CAAC,CAAA;KACH;IAED,OAAOlC,gBAAgB,CAAC;QACtBiC,IAAI,EAAElB,QAAQ;QACda,cAAc,EAAEF,UAAU,CAACE,cAAc;QACzCM,cAAc,EAAElB,MAAM,CAACkB,cAAc;QACrCf,OAAO;QACPC,aAAa;KACd,CAAC,CAAA;CACH"}