Initial boiler plate project
This commit is contained in:
762
node_modules/next/dist/esm/server/lib/router-utils/setup-dev-bundler.js
generated
vendored
Normal file
762
node_modules/next/dist/esm/server/lib/router-utils/setup-dev-bundler.js
generated
vendored
Normal file
@ -0,0 +1,762 @@
|
||||
import { createDefineEnv } from "../../../build/swc";
|
||||
import fs from "fs";
|
||||
import url from "url";
|
||||
import path from "path";
|
||||
import qs from "querystring";
|
||||
import Watchpack from "next/dist/compiled/watchpack";
|
||||
import { loadEnvConfig } from "@next/env";
|
||||
import isError from "../../../lib/is-error";
|
||||
import findUp from "next/dist/compiled/find-up";
|
||||
import { buildCustomRoute } from "./filesystem";
|
||||
import * as Log from "../../../build/output/log";
|
||||
import HotReloaderWebpack from "../../dev/hot-reloader-webpack";
|
||||
import { setGlobal } from "../../../trace/shared";
|
||||
import loadJsConfig from "../../../build/load-jsconfig";
|
||||
import { createValidFileMatcher } from "../find-page-file";
|
||||
import { eventCliSession } from "../../../telemetry/events";
|
||||
import { getDefineEnv } from "../../../build/webpack/plugins/define-env-plugin";
|
||||
import { logAppDirError } from "../../dev/log-app-dir-error";
|
||||
import { getSortedRoutes } from "../../../shared/lib/router/utils";
|
||||
import { getStaticInfoIncludingLayouts, sortByPageExts } from "../../../build/entries";
|
||||
import { verifyTypeScriptSetup } from "../../../lib/verify-typescript-setup";
|
||||
import { verifyPartytownSetup } from "../../../lib/verify-partytown-setup";
|
||||
import { getRouteRegex } from "../../../shared/lib/router/utils/route-regex";
|
||||
import { normalizeAppPath } from "../../../shared/lib/router/utils/app-paths";
|
||||
import { buildDataRoute } from "./build-data-route";
|
||||
import { getRouteMatcher } from "../../../shared/lib/router/utils/route-matcher";
|
||||
import { normalizePathSep } from "../../../shared/lib/page-path/normalize-path-sep";
|
||||
import { createClientRouterFilter } from "../../../lib/create-client-router-filter";
|
||||
import { absolutePathToPage } from "../../../shared/lib/page-path/absolute-path-to-page";
|
||||
import { generateInterceptionRoutesRewrites } from "../../../lib/generate-interception-routes-rewrites";
|
||||
import { CLIENT_STATIC_FILES_PATH, COMPILER_NAMES, DEV_CLIENT_PAGES_MANIFEST, DEV_MIDDLEWARE_MANIFEST, PHASE_DEVELOPMENT_SERVER } from "../../../shared/lib/constants";
|
||||
import { getMiddlewareRouteMatcher } from "../../../shared/lib/router/utils/middleware-route-matcher";
|
||||
import { isMiddlewareFile, NestedMiddlewareError, isInstrumentationHookFile, getPossibleMiddlewareFilenames, getPossibleInstrumentationHookFilenames } from "../../../build/utils";
|
||||
import { createOriginalStackFrame, getSourceById, parseStack } from "../../../client/components/react-dev-overlay/server/middleware";
|
||||
import { batchedTraceSource, createOriginalStackFrame as createOriginalTurboStackFrame } from "../../../client/components/react-dev-overlay/server/middleware-turbopack";
|
||||
import { devPageFiles } from "../../../build/webpack/plugins/next-types-plugin/shared";
|
||||
import { HMR_ACTIONS_SENT_TO_BROWSER } from "../../dev/hot-reloader-types";
|
||||
import { PAGE_TYPES } from "../../../lib/page-types";
|
||||
import { createHotReloaderTurbopack } from "../../dev/hot-reloader-turbopack";
|
||||
import { getErrorSource } from "../../../shared/lib/error-source";
|
||||
import { generateEncryptionKeyBase64 } from "../../app-render/encryption-utils";
|
||||
async function verifyTypeScript(opts) {
|
||||
let usingTypeScript = false;
|
||||
const verifyResult = await verifyTypeScriptSetup({
|
||||
dir: opts.dir,
|
||||
distDir: opts.nextConfig.distDir,
|
||||
intentDirs: [
|
||||
opts.pagesDir,
|
||||
opts.appDir
|
||||
].filter(Boolean),
|
||||
typeCheckPreflight: false,
|
||||
tsconfigPath: opts.nextConfig.typescript.tsconfigPath,
|
||||
disableStaticImages: opts.nextConfig.images.disableStaticImages,
|
||||
hasAppDir: !!opts.appDir,
|
||||
hasPagesDir: !!opts.pagesDir
|
||||
});
|
||||
if (verifyResult.version) {
|
||||
usingTypeScript = true;
|
||||
}
|
||||
return usingTypeScript;
|
||||
}
|
||||
class ModuleBuildError extends Error {
|
||||
}
|
||||
export async function propagateServerField(opts, field, args) {
|
||||
var _opts_renderServer_instance, _opts_renderServer;
|
||||
await ((_opts_renderServer = opts.renderServer) == null ? void 0 : (_opts_renderServer_instance = _opts_renderServer.instance) == null ? void 0 : _opts_renderServer_instance.propagateServerField(opts.dir, field, args));
|
||||
}
|
||||
async function startWatcher(opts) {
|
||||
const { nextConfig, appDir, pagesDir, dir } = opts;
|
||||
const { useFileSystemPublicRoutes } = nextConfig;
|
||||
const usingTypeScript = await verifyTypeScript(opts);
|
||||
const distDir = path.join(opts.dir, opts.nextConfig.distDir);
|
||||
setGlobal("distDir", distDir);
|
||||
setGlobal("phase", PHASE_DEVELOPMENT_SERVER);
|
||||
const validFileMatcher = createValidFileMatcher(nextConfig.pageExtensions, appDir);
|
||||
const serverFields = {};
|
||||
const hotReloader = opts.turbo ? await createHotReloaderTurbopack(opts, serverFields, distDir) : new HotReloaderWebpack(opts.dir, {
|
||||
appDir,
|
||||
pagesDir,
|
||||
distDir: distDir,
|
||||
config: opts.nextConfig,
|
||||
buildId: "development",
|
||||
encryptionKey: await generateEncryptionKeyBase64(),
|
||||
telemetry: opts.telemetry,
|
||||
rewrites: opts.fsChecker.rewrites,
|
||||
previewProps: opts.fsChecker.prerenderManifest.preview
|
||||
});
|
||||
await hotReloader.start();
|
||||
if (opts.nextConfig.experimental.nextScriptWorkers) {
|
||||
await verifyPartytownSetup(opts.dir, path.join(distDir, CLIENT_STATIC_FILES_PATH));
|
||||
}
|
||||
opts.fsChecker.ensureCallback(async function ensure(item) {
|
||||
if (item.type === "appFile" || item.type === "pageFile") {
|
||||
await hotReloader.ensurePage({
|
||||
clientOnly: false,
|
||||
page: item.itemPath,
|
||||
isApp: item.type === "appFile",
|
||||
definition: undefined
|
||||
});
|
||||
}
|
||||
});
|
||||
let resolved = false;
|
||||
let prevSortedRoutes = [];
|
||||
await new Promise(async (resolve, reject)=>{
|
||||
if (pagesDir) {
|
||||
// Watchpack doesn't emit an event for an empty directory
|
||||
fs.readdir(pagesDir, (_, files)=>{
|
||||
if (files == null ? void 0 : files.length) {
|
||||
return;
|
||||
}
|
||||
if (!resolved) {
|
||||
resolve();
|
||||
resolved = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
const pages = pagesDir ? [
|
||||
pagesDir
|
||||
] : [];
|
||||
const app = appDir ? [
|
||||
appDir
|
||||
] : [];
|
||||
const directories = [
|
||||
...pages,
|
||||
...app
|
||||
];
|
||||
const rootDir = pagesDir || appDir;
|
||||
const files = [
|
||||
...getPossibleMiddlewareFilenames(path.join(rootDir, ".."), nextConfig.pageExtensions),
|
||||
...getPossibleInstrumentationHookFilenames(path.join(rootDir, ".."), nextConfig.pageExtensions)
|
||||
];
|
||||
let nestedMiddleware = [];
|
||||
const envFiles = [
|
||||
".env.development.local",
|
||||
".env.local",
|
||||
".env.development",
|
||||
".env"
|
||||
].map((file)=>path.join(dir, file));
|
||||
files.push(...envFiles);
|
||||
// tsconfig/jsconfig paths hot-reloading
|
||||
const tsconfigPaths = [
|
||||
path.join(dir, "tsconfig.json"),
|
||||
path.join(dir, "jsconfig.json")
|
||||
];
|
||||
files.push(...tsconfigPaths);
|
||||
const wp = new Watchpack({
|
||||
ignored: (pathname)=>{
|
||||
return !files.some((file)=>file.startsWith(pathname)) && !directories.some((d)=>pathname.startsWith(d) || d.startsWith(pathname));
|
||||
}
|
||||
});
|
||||
const fileWatchTimes = new Map();
|
||||
let enabledTypeScript = usingTypeScript;
|
||||
let previousClientRouterFilters;
|
||||
let previousConflictingPagePaths = new Set();
|
||||
wp.on("aggregated", async ()=>{
|
||||
var _serverFields_middleware, _serverFields_middleware1;
|
||||
let middlewareMatchers;
|
||||
const routedPages = [];
|
||||
const knownFiles = wp.getTimeInfoEntries();
|
||||
const appPaths = {};
|
||||
const pageNameSet = new Set();
|
||||
const conflictingAppPagePaths = new Set();
|
||||
const appPageFilePaths = new Map();
|
||||
const pagesPageFilePaths = new Map();
|
||||
let envChange = false;
|
||||
let tsconfigChange = false;
|
||||
let conflictingPageChange = 0;
|
||||
let hasRootAppNotFound = false;
|
||||
const { appFiles, pageFiles } = opts.fsChecker;
|
||||
appFiles.clear();
|
||||
pageFiles.clear();
|
||||
devPageFiles.clear();
|
||||
const sortedKnownFiles = [
|
||||
...knownFiles.keys()
|
||||
].sort(sortByPageExts(nextConfig.pageExtensions));
|
||||
for (const fileName of sortedKnownFiles){
|
||||
if (!files.includes(fileName) && !directories.some((d)=>fileName.startsWith(d))) {
|
||||
continue;
|
||||
}
|
||||
const meta = knownFiles.get(fileName);
|
||||
const watchTime = fileWatchTimes.get(fileName);
|
||||
// If the file is showing up for the first time or the meta.timestamp is changed since last time
|
||||
const watchTimeChange = watchTime === undefined || watchTime && watchTime !== (meta == null ? void 0 : meta.timestamp);
|
||||
fileWatchTimes.set(fileName, meta == null ? void 0 : meta.timestamp);
|
||||
if (envFiles.includes(fileName)) {
|
||||
if (watchTimeChange) {
|
||||
envChange = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (tsconfigPaths.includes(fileName)) {
|
||||
if (fileName.endsWith("tsconfig.json")) {
|
||||
enabledTypeScript = true;
|
||||
}
|
||||
if (watchTimeChange) {
|
||||
tsconfigChange = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ((meta == null ? void 0 : meta.accuracy) === undefined || !validFileMatcher.isPageFile(fileName)) {
|
||||
continue;
|
||||
}
|
||||
const isAppPath = Boolean(appDir && normalizePathSep(fileName).startsWith(normalizePathSep(appDir) + "/"));
|
||||
const isPagePath = Boolean(pagesDir && normalizePathSep(fileName).startsWith(normalizePathSep(pagesDir) + "/"));
|
||||
const rootFile = absolutePathToPage(fileName, {
|
||||
dir: dir,
|
||||
extensions: nextConfig.pageExtensions,
|
||||
keepIndex: false,
|
||||
pagesType: PAGE_TYPES.ROOT
|
||||
});
|
||||
if (isMiddlewareFile(rootFile)) {
|
||||
var _staticInfo_middleware;
|
||||
const staticInfo = await getStaticInfoIncludingLayouts({
|
||||
pageFilePath: fileName,
|
||||
config: nextConfig,
|
||||
appDir: appDir,
|
||||
page: rootFile,
|
||||
isDev: true,
|
||||
isInsideAppDir: isAppPath,
|
||||
pageExtensions: nextConfig.pageExtensions
|
||||
});
|
||||
if (nextConfig.output === "export") {
|
||||
Log.error('Middleware cannot be used with "output: export". See more info here: https://nextjs.org/docs/advanced-features/static-html-export');
|
||||
continue;
|
||||
}
|
||||
serverFields.actualMiddlewareFile = rootFile;
|
||||
await propagateServerField(opts, "actualMiddlewareFile", serverFields.actualMiddlewareFile);
|
||||
middlewareMatchers = ((_staticInfo_middleware = staticInfo.middleware) == null ? void 0 : _staticInfo_middleware.matchers) || [
|
||||
{
|
||||
regexp: ".*",
|
||||
originalSource: "/:path*"
|
||||
}
|
||||
];
|
||||
continue;
|
||||
}
|
||||
if (isInstrumentationHookFile(rootFile) && nextConfig.experimental.instrumentationHook) {
|
||||
serverFields.actualInstrumentationHookFile = rootFile;
|
||||
await propagateServerField(opts, "actualInstrumentationHookFile", serverFields.actualInstrumentationHookFile);
|
||||
continue;
|
||||
}
|
||||
if (fileName.endsWith(".ts") || fileName.endsWith(".tsx")) {
|
||||
enabledTypeScript = true;
|
||||
}
|
||||
if (!(isAppPath || isPagePath)) {
|
||||
continue;
|
||||
}
|
||||
// Collect all current filenames for the TS plugin to use
|
||||
devPageFiles.add(fileName);
|
||||
let pageName = absolutePathToPage(fileName, {
|
||||
dir: isAppPath ? appDir : pagesDir,
|
||||
extensions: nextConfig.pageExtensions,
|
||||
keepIndex: isAppPath,
|
||||
pagesType: isAppPath ? PAGE_TYPES.APP : PAGE_TYPES.PAGES
|
||||
});
|
||||
if (!isAppPath && pageName.startsWith("/api/") && nextConfig.output === "export") {
|
||||
Log.error('API Routes cannot be used with "output: export". See more info here: https://nextjs.org/docs/advanced-features/static-html-export');
|
||||
continue;
|
||||
}
|
||||
if (isAppPath) {
|
||||
const isRootNotFound = validFileMatcher.isRootNotFound(fileName);
|
||||
hasRootAppNotFound = true;
|
||||
if (isRootNotFound) {
|
||||
continue;
|
||||
}
|
||||
if (!isRootNotFound && !validFileMatcher.isAppRouterPage(fileName)) {
|
||||
continue;
|
||||
}
|
||||
// Ignore files/directories starting with `_` in the app directory
|
||||
if (normalizePathSep(pageName).includes("/_")) {
|
||||
continue;
|
||||
}
|
||||
const originalPageName = pageName;
|
||||
pageName = normalizeAppPath(pageName).replace(/%5F/g, "_");
|
||||
if (!appPaths[pageName]) {
|
||||
appPaths[pageName] = [];
|
||||
}
|
||||
appPaths[pageName].push(originalPageName);
|
||||
if (useFileSystemPublicRoutes) {
|
||||
appFiles.add(pageName);
|
||||
}
|
||||
if (routedPages.includes(pageName)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (useFileSystemPublicRoutes) {
|
||||
pageFiles.add(pageName);
|
||||
// always add to nextDataRoutes for now but in future only add
|
||||
// entries that actually use getStaticProps/getServerSideProps
|
||||
opts.fsChecker.nextDataRoutes.add(pageName);
|
||||
}
|
||||
}
|
||||
(isAppPath ? appPageFilePaths : pagesPageFilePaths).set(pageName, fileName);
|
||||
if (appDir && pageNameSet.has(pageName)) {
|
||||
conflictingAppPagePaths.add(pageName);
|
||||
} else {
|
||||
pageNameSet.add(pageName);
|
||||
}
|
||||
/**
|
||||
* If there is a middleware that is not declared in the root we will
|
||||
* warn without adding it so it doesn't make its way into the system.
|
||||
*/ if (/[\\\\/]_middleware$/.test(pageName)) {
|
||||
nestedMiddleware.push(pageName);
|
||||
continue;
|
||||
}
|
||||
routedPages.push(pageName);
|
||||
}
|
||||
const numConflicting = conflictingAppPagePaths.size;
|
||||
conflictingPageChange = numConflicting - previousConflictingPagePaths.size;
|
||||
if (conflictingPageChange !== 0) {
|
||||
if (numConflicting > 0) {
|
||||
let errorMessage = `Conflicting app and page file${numConflicting === 1 ? " was" : "s were"} found, please remove the conflicting files to continue:\n`;
|
||||
for (const p of conflictingAppPagePaths){
|
||||
const appPath = path.relative(dir, appPageFilePaths.get(p));
|
||||
const pagesPath = path.relative(dir, pagesPageFilePaths.get(p));
|
||||
errorMessage += ` "${pagesPath}" - "${appPath}"\n`;
|
||||
}
|
||||
hotReloader.setHmrServerError(new Error(errorMessage));
|
||||
} else if (numConflicting === 0) {
|
||||
hotReloader.clearHmrServerError();
|
||||
await propagateServerField(opts, "reloadMatchers", undefined);
|
||||
}
|
||||
}
|
||||
previousConflictingPagePaths = conflictingAppPagePaths;
|
||||
let clientRouterFilters;
|
||||
if (nextConfig.experimental.clientRouterFilter) {
|
||||
clientRouterFilters = createClientRouterFilter(Object.keys(appPaths), nextConfig.experimental.clientRouterFilterRedirects ? (nextConfig._originalRedirects || []).filter((r)=>!r.internal) : [], nextConfig.experimental.clientRouterFilterAllowedRate);
|
||||
if (!previousClientRouterFilters || JSON.stringify(previousClientRouterFilters) !== JSON.stringify(clientRouterFilters)) {
|
||||
envChange = true;
|
||||
previousClientRouterFilters = clientRouterFilters;
|
||||
}
|
||||
}
|
||||
if (!usingTypeScript && enabledTypeScript) {
|
||||
// we tolerate the error here as this is best effort
|
||||
// and the manual install command will be shown
|
||||
await verifyTypeScript(opts).then(()=>{
|
||||
tsconfigChange = true;
|
||||
}).catch(()=>{});
|
||||
}
|
||||
if (envChange || tsconfigChange) {
|
||||
var _hotReloader_activeWebpackConfigs;
|
||||
if (envChange) {
|
||||
// only log changes in router server
|
||||
loadEnvConfig(dir, true, Log, true, (envFilePath)=>{
|
||||
Log.info(`Reload env: ${envFilePath}`);
|
||||
});
|
||||
await propagateServerField(opts, "loadEnvConfig", [
|
||||
{
|
||||
dev: true,
|
||||
forceReload: true,
|
||||
silent: true
|
||||
}
|
||||
]);
|
||||
}
|
||||
let tsconfigResult;
|
||||
if (tsconfigChange) {
|
||||
try {
|
||||
tsconfigResult = await loadJsConfig(dir, nextConfig);
|
||||
} catch (_) {
|
||||
/* do we want to log if there are syntax errors in tsconfig while editing? */ }
|
||||
}
|
||||
if (hotReloader.turbopackProject) {
|
||||
const hasRewrites = opts.fsChecker.rewrites.afterFiles.length > 0 || opts.fsChecker.rewrites.beforeFiles.length > 0 || opts.fsChecker.rewrites.fallback.length > 0;
|
||||
await hotReloader.turbopackProject.update({
|
||||
defineEnv: createDefineEnv({
|
||||
isTurbopack: true,
|
||||
clientRouterFilters,
|
||||
config: nextConfig,
|
||||
dev: true,
|
||||
distDir,
|
||||
fetchCacheKeyPrefix: opts.nextConfig.experimental.fetchCacheKeyPrefix,
|
||||
hasRewrites,
|
||||
// TODO: Implement
|
||||
middlewareMatchers: undefined
|
||||
})
|
||||
});
|
||||
}
|
||||
(_hotReloader_activeWebpackConfigs = hotReloader.activeWebpackConfigs) == null ? void 0 : _hotReloader_activeWebpackConfigs.forEach((config, idx)=>{
|
||||
const isClient = idx === 0;
|
||||
const isNodeServer = idx === 1;
|
||||
const isEdgeServer = idx === 2;
|
||||
const hasRewrites = opts.fsChecker.rewrites.afterFiles.length > 0 || opts.fsChecker.rewrites.beforeFiles.length > 0 || opts.fsChecker.rewrites.fallback.length > 0;
|
||||
if (tsconfigChange) {
|
||||
var _config_resolve_plugins, _config_resolve;
|
||||
(_config_resolve = config.resolve) == null ? void 0 : (_config_resolve_plugins = _config_resolve.plugins) == null ? void 0 : _config_resolve_plugins.forEach((plugin)=>{
|
||||
// look for the JsConfigPathsPlugin and update with
|
||||
// the latest paths/baseUrl config
|
||||
if (plugin && plugin.jsConfigPlugin && tsconfigResult) {
|
||||
var _config_resolve_modules, _config_resolve, _jsConfig_compilerOptions;
|
||||
const { resolvedBaseUrl, jsConfig } = tsconfigResult;
|
||||
const currentResolvedBaseUrl = plugin.resolvedBaseUrl;
|
||||
const resolvedUrlIndex = (_config_resolve = config.resolve) == null ? void 0 : (_config_resolve_modules = _config_resolve.modules) == null ? void 0 : _config_resolve_modules.findIndex((item)=>item === currentResolvedBaseUrl);
|
||||
if (resolvedBaseUrl) {
|
||||
if (resolvedBaseUrl.baseUrl !== currentResolvedBaseUrl.baseUrl) {
|
||||
// remove old baseUrl and add new one
|
||||
if (resolvedUrlIndex && resolvedUrlIndex > -1) {
|
||||
var _config_resolve_modules1, _config_resolve1;
|
||||
(_config_resolve1 = config.resolve) == null ? void 0 : (_config_resolve_modules1 = _config_resolve1.modules) == null ? void 0 : _config_resolve_modules1.splice(resolvedUrlIndex, 1);
|
||||
}
|
||||
// If the resolvedBaseUrl is implicit we only remove the previous value.
|
||||
// Only add the baseUrl if it's explicitly set in tsconfig/jsconfig
|
||||
if (!resolvedBaseUrl.isImplicit) {
|
||||
var _config_resolve_modules2, _config_resolve2;
|
||||
(_config_resolve2 = config.resolve) == null ? void 0 : (_config_resolve_modules2 = _config_resolve2.modules) == null ? void 0 : _config_resolve_modules2.push(resolvedBaseUrl.baseUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((jsConfig == null ? void 0 : (_jsConfig_compilerOptions = jsConfig.compilerOptions) == null ? void 0 : _jsConfig_compilerOptions.paths) && resolvedBaseUrl) {
|
||||
Object.keys(plugin.paths).forEach((key)=>{
|
||||
delete plugin.paths[key];
|
||||
});
|
||||
Object.assign(plugin.paths, jsConfig.compilerOptions.paths);
|
||||
plugin.resolvedBaseUrl = resolvedBaseUrl;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (envChange) {
|
||||
var _config_plugins;
|
||||
(_config_plugins = config.plugins) == null ? void 0 : _config_plugins.forEach((plugin)=>{
|
||||
// we look for the DefinePlugin definitions so we can
|
||||
// update them on the active compilers
|
||||
if (plugin && typeof plugin.definitions === "object" && plugin.definitions.__NEXT_DEFINE_ENV) {
|
||||
const newDefine = getDefineEnv({
|
||||
isTurbopack: false,
|
||||
clientRouterFilters,
|
||||
config: nextConfig,
|
||||
dev: true,
|
||||
distDir,
|
||||
fetchCacheKeyPrefix: opts.nextConfig.experimental.fetchCacheKeyPrefix,
|
||||
hasRewrites,
|
||||
isClient,
|
||||
isEdgeServer,
|
||||
isNodeOrEdgeCompilation: isNodeServer || isEdgeServer,
|
||||
isNodeServer,
|
||||
middlewareMatchers: undefined
|
||||
});
|
||||
Object.keys(plugin.definitions).forEach((key)=>{
|
||||
if (!(key in newDefine)) {
|
||||
delete plugin.definitions[key];
|
||||
}
|
||||
});
|
||||
Object.assign(plugin.definitions, newDefine);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
await hotReloader.invalidate({
|
||||
reloadAfterInvalidation: envChange
|
||||
});
|
||||
}
|
||||
if (nestedMiddleware.length > 0) {
|
||||
Log.error(new NestedMiddlewareError(nestedMiddleware, dir, pagesDir || appDir).message);
|
||||
nestedMiddleware = [];
|
||||
}
|
||||
// Make sure to sort parallel routes to make the result deterministic.
|
||||
serverFields.appPathRoutes = Object.fromEntries(Object.entries(appPaths).map(([k, v])=>[
|
||||
k,
|
||||
v.sort()
|
||||
]));
|
||||
await propagateServerField(opts, "appPathRoutes", serverFields.appPathRoutes);
|
||||
// TODO: pass this to fsChecker/next-dev-server?
|
||||
serverFields.middleware = middlewareMatchers ? {
|
||||
match: null,
|
||||
page: "/",
|
||||
matchers: middlewareMatchers
|
||||
} : undefined;
|
||||
await propagateServerField(opts, "middleware", serverFields.middleware);
|
||||
serverFields.hasAppNotFound = hasRootAppNotFound;
|
||||
opts.fsChecker.middlewareMatcher = ((_serverFields_middleware = serverFields.middleware) == null ? void 0 : _serverFields_middleware.matchers) ? getMiddlewareRouteMatcher((_serverFields_middleware1 = serverFields.middleware) == null ? void 0 : _serverFields_middleware1.matchers) : undefined;
|
||||
const interceptionRoutes = generateInterceptionRoutesRewrites(Object.keys(appPaths), opts.nextConfig.basePath).map((item)=>buildCustomRoute("before_files_rewrite", item, opts.nextConfig.basePath, opts.nextConfig.experimental.caseSensitiveRoutes));
|
||||
opts.fsChecker.rewrites.beforeFiles.push(...interceptionRoutes);
|
||||
const exportPathMap = typeof nextConfig.exportPathMap === "function" && await (nextConfig.exportPathMap == null ? void 0 : nextConfig.exportPathMap.call(nextConfig, {}, {
|
||||
dev: true,
|
||||
dir: opts.dir,
|
||||
outDir: null,
|
||||
distDir: distDir,
|
||||
buildId: "development"
|
||||
})) || {};
|
||||
const exportPathMapEntries = Object.entries(exportPathMap || {});
|
||||
if (exportPathMapEntries.length > 0) {
|
||||
opts.fsChecker.exportPathMapRoutes = exportPathMapEntries.map(([key, value])=>buildCustomRoute("before_files_rewrite", {
|
||||
source: key,
|
||||
destination: `${value.page}${value.query ? "?" : ""}${qs.stringify(value.query)}`
|
||||
}, opts.nextConfig.basePath, opts.nextConfig.experimental.caseSensitiveRoutes));
|
||||
}
|
||||
try {
|
||||
// we serve a separate manifest with all pages for the client in
|
||||
// dev mode so that we can match a page after a rewrite on the client
|
||||
// before it has been built and is populated in the _buildManifest
|
||||
const sortedRoutes = getSortedRoutes(routedPages);
|
||||
opts.fsChecker.dynamicRoutes = sortedRoutes.map((page)=>{
|
||||
const regex = getRouteRegex(page);
|
||||
return {
|
||||
regex: regex.re.toString(),
|
||||
match: getRouteMatcher(regex),
|
||||
page
|
||||
};
|
||||
});
|
||||
const dataRoutes = [];
|
||||
for (const page of sortedRoutes){
|
||||
const route = buildDataRoute(page, "development");
|
||||
const routeRegex = getRouteRegex(route.page);
|
||||
dataRoutes.push({
|
||||
...route,
|
||||
regex: routeRegex.re.toString(),
|
||||
match: getRouteMatcher({
|
||||
// TODO: fix this in the manifest itself, must also be fixed in
|
||||
// upstream builder that relies on this
|
||||
re: opts.nextConfig.i18n ? new RegExp(route.dataRouteRegex.replace(`/development/`, `/development/(?<nextLocale>[^/]+?)/`)) : new RegExp(route.dataRouteRegex),
|
||||
groups: routeRegex.groups
|
||||
})
|
||||
});
|
||||
}
|
||||
opts.fsChecker.dynamicRoutes.unshift(...dataRoutes);
|
||||
if (!(prevSortedRoutes == null ? void 0 : prevSortedRoutes.every((val, idx)=>val === sortedRoutes[idx]))) {
|
||||
const addedRoutes = sortedRoutes.filter((route)=>!prevSortedRoutes.includes(route));
|
||||
const removedRoutes = prevSortedRoutes.filter((route)=>!sortedRoutes.includes(route));
|
||||
// emit the change so clients fetch the update
|
||||
hotReloader.send({
|
||||
action: HMR_ACTIONS_SENT_TO_BROWSER.DEV_PAGES_MANIFEST_UPDATE,
|
||||
data: [
|
||||
{
|
||||
devPagesManifest: true
|
||||
}
|
||||
]
|
||||
});
|
||||
addedRoutes.forEach((route)=>{
|
||||
hotReloader.send({
|
||||
action: HMR_ACTIONS_SENT_TO_BROWSER.ADDED_PAGE,
|
||||
data: [
|
||||
route
|
||||
]
|
||||
});
|
||||
});
|
||||
removedRoutes.forEach((route)=>{
|
||||
hotReloader.send({
|
||||
action: HMR_ACTIONS_SENT_TO_BROWSER.REMOVED_PAGE,
|
||||
data: [
|
||||
route
|
||||
]
|
||||
});
|
||||
});
|
||||
}
|
||||
prevSortedRoutes = sortedRoutes;
|
||||
if (!resolved) {
|
||||
resolve();
|
||||
resolved = true;
|
||||
}
|
||||
} catch (e) {
|
||||
if (!resolved) {
|
||||
reject(e);
|
||||
resolved = true;
|
||||
} else {
|
||||
Log.warn("Failed to reload dynamic routes:", e);
|
||||
}
|
||||
} finally{
|
||||
// Reload the matchers. The filesystem would have been written to,
|
||||
// and the matchers need to re-scan it to update the router.
|
||||
await propagateServerField(opts, "reloadMatchers", undefined);
|
||||
}
|
||||
});
|
||||
wp.watch({
|
||||
directories: [
|
||||
dir
|
||||
],
|
||||
startTime: 0
|
||||
});
|
||||
});
|
||||
const clientPagesManifestPath = `/_next/${CLIENT_STATIC_FILES_PATH}/development/${DEV_CLIENT_PAGES_MANIFEST}`;
|
||||
opts.fsChecker.devVirtualFsItems.add(clientPagesManifestPath);
|
||||
const devMiddlewareManifestPath = `/_next/${CLIENT_STATIC_FILES_PATH}/development/${DEV_MIDDLEWARE_MANIFEST}`;
|
||||
opts.fsChecker.devVirtualFsItems.add(devMiddlewareManifestPath);
|
||||
async function requestHandler(req, res) {
|
||||
var _parsedUrl_pathname, _parsedUrl_pathname1;
|
||||
const parsedUrl = url.parse(req.url || "/");
|
||||
if ((_parsedUrl_pathname = parsedUrl.pathname) == null ? void 0 : _parsedUrl_pathname.includes(clientPagesManifestPath)) {
|
||||
res.statusCode = 200;
|
||||
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
||||
res.end(JSON.stringify({
|
||||
pages: prevSortedRoutes.filter((route)=>!opts.fsChecker.appFiles.has(route))
|
||||
}));
|
||||
return {
|
||||
finished: true
|
||||
};
|
||||
}
|
||||
if ((_parsedUrl_pathname1 = parsedUrl.pathname) == null ? void 0 : _parsedUrl_pathname1.includes(devMiddlewareManifestPath)) {
|
||||
var _serverFields_middleware;
|
||||
res.statusCode = 200;
|
||||
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
||||
res.end(JSON.stringify(((_serverFields_middleware = serverFields.middleware) == null ? void 0 : _serverFields_middleware.matchers) || []));
|
||||
return {
|
||||
finished: true
|
||||
};
|
||||
}
|
||||
return {
|
||||
finished: false
|
||||
};
|
||||
}
|
||||
async function logErrorWithOriginalStack(err, type) {
|
||||
let usedOriginalStack = false;
|
||||
if (isError(err) && err.stack) {
|
||||
try {
|
||||
const frames = parseStack(err.stack);
|
||||
// Filter out internal edge related runtime stack
|
||||
const frame = frames.find(({ file })=>!(file == null ? void 0 : file.startsWith("eval")) && !(file == null ? void 0 : file.includes("web/adapter")) && !(file == null ? void 0 : file.includes("web/globals")) && !(file == null ? void 0 : file.includes("sandbox/context")) && !(file == null ? void 0 : file.includes("<anonymous>")));
|
||||
let originalFrame, isEdgeCompiler;
|
||||
const frameFile = frame == null ? void 0 : frame.file;
|
||||
if ((frame == null ? void 0 : frame.lineNumber) && frameFile) {
|
||||
if (hotReloader.turbopackProject) {
|
||||
try {
|
||||
originalFrame = await createOriginalTurboStackFrame(hotReloader.turbopackProject, {
|
||||
file: frameFile,
|
||||
methodName: frame.methodName,
|
||||
line: frame.lineNumber ?? 0,
|
||||
column: frame.column,
|
||||
isServer: true
|
||||
});
|
||||
} catch {}
|
||||
} else {
|
||||
var _hotReloader_edgeServerStats, _hotReloader_serverStats, _frame_file, _frame_file1;
|
||||
const moduleId = frameFile.replace(/^(webpack-internal:\/\/\/|file:\/\/)/, "");
|
||||
const modulePath = frameFile.replace(/^(webpack-internal:\/\/\/|file:\/\/)(\(.*\)\/)?/, "");
|
||||
const src = getErrorSource(err);
|
||||
isEdgeCompiler = src === COMPILER_NAMES.edgeServer;
|
||||
const compilation = isEdgeCompiler ? (_hotReloader_edgeServerStats = hotReloader.edgeServerStats) == null ? void 0 : _hotReloader_edgeServerStats.compilation : (_hotReloader_serverStats = hotReloader.serverStats) == null ? void 0 : _hotReloader_serverStats.compilation;
|
||||
const source = await getSourceById(!!((_frame_file = frame.file) == null ? void 0 : _frame_file.startsWith(path.sep)) || !!((_frame_file1 = frame.file) == null ? void 0 : _frame_file1.startsWith("file:")), moduleId, compilation);
|
||||
try {
|
||||
var _hotReloader_edgeServerStats1, _hotReloader_serverStats1;
|
||||
originalFrame = await createOriginalStackFrame({
|
||||
source,
|
||||
frame,
|
||||
moduleId,
|
||||
modulePath,
|
||||
rootDirectory: opts.dir,
|
||||
errorMessage: err.message,
|
||||
compilation: isEdgeCompiler ? (_hotReloader_edgeServerStats1 = hotReloader.edgeServerStats) == null ? void 0 : _hotReloader_edgeServerStats1.compilation : (_hotReloader_serverStats1 = hotReloader.serverStats) == null ? void 0 : _hotReloader_serverStats1.compilation
|
||||
});
|
||||
} catch {}
|
||||
}
|
||||
if ((originalFrame == null ? void 0 : originalFrame.originalCodeFrame) && originalFrame.originalStackFrame) {
|
||||
const { originalCodeFrame, originalStackFrame } = originalFrame;
|
||||
const { file, lineNumber, column, methodName } = originalStackFrame;
|
||||
Log[type === "warning" ? "warn" : "error"](`${file} (${lineNumber}:${column}) @ ${methodName}`);
|
||||
let errorToLog;
|
||||
if (isEdgeCompiler) {
|
||||
errorToLog = err.message;
|
||||
} else if (isError(err) && hotReloader.turbopackProject) {
|
||||
const stack = await traceTurbopackErrorStack(hotReloader.turbopackProject, err, frames);
|
||||
const error = new Error(err.message);
|
||||
error.stack = stack;
|
||||
error.digest = err.digest;
|
||||
errorToLog = error;
|
||||
} else {
|
||||
errorToLog = err;
|
||||
}
|
||||
if (type === "warning") {
|
||||
Log.warn(errorToLog);
|
||||
} else if (type === "app-dir") {
|
||||
logAppDirError(errorToLog);
|
||||
} else if (type) {
|
||||
Log.error(`${type}:`, errorToLog);
|
||||
} else {
|
||||
Log.error(errorToLog);
|
||||
}
|
||||
console[type === "warning" ? "warn" : "error"](originalCodeFrame);
|
||||
usedOriginalStack = true;
|
||||
}
|
||||
}
|
||||
} catch (_) {
|
||||
// failed to load original stack using source maps
|
||||
// this un-actionable by users so we don't show the
|
||||
// internal error and only show the provided stack
|
||||
}
|
||||
}
|
||||
if (!usedOriginalStack) {
|
||||
if (err instanceof ModuleBuildError) {
|
||||
Log.error(err.message);
|
||||
} else if (type === "warning") {
|
||||
Log.warn(err);
|
||||
} else if (type === "app-dir") {
|
||||
logAppDirError(err);
|
||||
} else if (type) {
|
||||
Log.error(`${type}:`, err);
|
||||
} else {
|
||||
Log.error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
serverFields,
|
||||
hotReloader,
|
||||
requestHandler,
|
||||
logErrorWithOriginalStack,
|
||||
async ensureMiddleware (requestUrl) {
|
||||
if (!serverFields.actualMiddlewareFile) return;
|
||||
return hotReloader.ensurePage({
|
||||
page: serverFields.actualMiddlewareFile,
|
||||
clientOnly: false,
|
||||
definition: undefined,
|
||||
url: requestUrl
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
export async function setupDevBundler(opts) {
|
||||
const isSrcDir = path.relative(opts.dir, opts.pagesDir || opts.appDir || "").startsWith("src");
|
||||
const result = await startWatcher(opts);
|
||||
opts.telemetry.record(eventCliSession(path.join(opts.dir, opts.nextConfig.distDir), opts.nextConfig, {
|
||||
webpackVersion: 5,
|
||||
isSrcDir,
|
||||
turboFlag: !!opts.turbo,
|
||||
cliCommand: "dev",
|
||||
appDir: !!opts.appDir,
|
||||
pagesDir: !!opts.pagesDir,
|
||||
isCustomServer: !!opts.isCustomServer,
|
||||
hasNowJson: !!await findUp("now.json", {
|
||||
cwd: opts.dir
|
||||
})
|
||||
}));
|
||||
return result;
|
||||
}
|
||||
// Returns a trace rewritten through Turbopack's sourcemaps
|
||||
async function traceTurbopackErrorStack(project, error, frames) {
|
||||
let originalFrames = await Promise.all(frames.map(async (f)=>{
|
||||
try {
|
||||
const traced = await batchedTraceSource(project, {
|
||||
file: f.file,
|
||||
methodName: f.methodName,
|
||||
line: f.lineNumber ?? 0,
|
||||
column: f.column,
|
||||
isServer: true
|
||||
});
|
||||
return (traced == null ? void 0 : traced.frame) ?? f;
|
||||
} catch {
|
||||
return f;
|
||||
}
|
||||
}));
|
||||
return error.name + ": " + error.message + "\n" + originalFrames.map((f)=>{
|
||||
if (f == null) {
|
||||
return null;
|
||||
}
|
||||
let line = " at";
|
||||
if (f.methodName != null) {
|
||||
line += " " + f.methodName;
|
||||
}
|
||||
if (f.file != null) {
|
||||
const file = f.file.startsWith("/") || // Built-in "filenames" like `<anonymous>` shouldn't be made relative
|
||||
f.file.startsWith("<") || f.file.startsWith("node:") ? f.file : `./${f.file}`;
|
||||
line += ` (${file}`;
|
||||
if (f.lineNumber != null) {
|
||||
line += ":" + f.lineNumber;
|
||||
if (f.column != null) {
|
||||
line += ":" + f.column;
|
||||
}
|
||||
}
|
||||
line += ")";
|
||||
}
|
||||
return line;
|
||||
}).filter(Boolean).join("\n");
|
||||
}
|
||||
|
||||
//# sourceMappingURL=setup-dev-bundler.js.map
|
||||
Reference in New Issue
Block a user