diff --git a/.eslintrc.json b/.eslintrc.json
index feb49b2ecbbff..8c46d8c02736f 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -162,10 +162,7 @@
},
{
"files": ["packages/**"],
- "excludedFiles": [
- "packages/next/taskfile*.js",
- "packages/next/webpack.config.js"
- ],
+ "excludedFiles": ["packages/next/taskfile.js"],
"rules": {
"no-shadow": ["warn", { "builtinGlobals": false }],
"import/no-extraneous-dependencies": [
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 2de2ef61939c7..3b28ea4bab515 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -18,19 +18,15 @@
],
// Disable Jest autoRun as otherwise it will start running all tests the first time.
"jest.autoRun": "off",
-
// Debugging.
"debug.javascript.unmapMissingSources": true,
-
"files.exclude": {
"**/node_modules": false,
"node_modules": true,
"*[!test]**/node_modules": true
},
-
// Ensure enough terminal history is preserved when running tests.
"terminal.integrated.scrollback": 10000,
-
// Configure todo-tree to exclude node_modules, dist, and compiled.
"todo-tree.filtering.excludeGlobs": [
"**/node_modules",
@@ -48,10 +44,8 @@
"[x]",
"TODO-APP"
],
-
// Disable TypeScript surveys.
"typescript.surveys.enabled": false,
-
// Enable file nesting for unit test files.
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.patterns": {
@@ -82,5 +76,6 @@
"language": "markdown",
"scheme": "file"
}
- ]
+ ],
+ "typescript.tsdk": "node_modules/typescript/lib"
}
diff --git a/bench/basic-app/app/api/app/route.js b/bench/basic-app/app/api/app/route.js
deleted file mode 100644
index 944ba5a8e827f..0000000000000
--- a/bench/basic-app/app/api/app/route.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export function GET() {
- return { name: 'John Doe' }
-}
-
-export const dynamic = 'force-dynamic'
diff --git a/bench/basic-app/app/layout.js b/bench/basic-app/app/layout.js
deleted file mode 100644
index 8ebf54889577d..0000000000000
--- a/bench/basic-app/app/layout.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from 'react'
-
-export default function Layout({ children }) {
- return (
-
-
- My App
-
- {children}
-
- )
-}
diff --git a/bench/basic-app/app/page.js b/bench/basic-app/app/page.js
deleted file mode 100644
index 83dc3aa56c9a0..0000000000000
--- a/bench/basic-app/app/page.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import React from 'react'
-
-export default function Page() {
- return My Page
-}
-
-export const dynamic = 'force-dynamic'
diff --git a/bench/basic-app/next.config.js b/bench/basic-app/next.config.js
deleted file mode 100644
index 0957c472383fa..0000000000000
--- a/bench/basic-app/next.config.js
+++ /dev/null
@@ -1,5 +0,0 @@
-module.exports = {
- experimental: {
- serverMinification: true,
- },
-}
diff --git a/bench/basic-app/pages/api/index.js b/bench/basic-app/pages/api/index.js
deleted file mode 100644
index 8f603094bd288..0000000000000
--- a/bench/basic-app/pages/api/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function handler(req, res) {
- res.status(200).json({ name: 'John Doe' })
-}
diff --git a/bench/basic-app/pages/pages/index.js b/bench/basic-app/pages/pages/index.js
deleted file mode 100644
index e06229eee0637..0000000000000
--- a/bench/basic-app/pages/pages/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export default () => 'Hello World'
-
-export function getServerSideProps() {
- return {
- props: {},
- }
-}
diff --git a/lerna.json b/lerna.json
index 9473ac4b6bb84..a589ef7b023c6 100644
--- a/lerna.json
+++ b/lerna.json
@@ -16,5 +16,5 @@
"registry": "https://registry.npmjs.org/"
}
},
- "version": "13.4.20-canary.20"
+ "version": "13.4.20-canary.21"
}
diff --git a/package.json b/package.json
index 5582290ae2d4c..21a75dfea9279 100644
--- a/package.json
+++ b/package.json
@@ -101,7 +101,7 @@
"@types/node-fetch": "2.6.1",
"@types/react": "18.2.8",
"@types/react-dom": "18.2.4",
- "@types/relay-runtime": "13.0.0",
+ "@types/relay-runtime": "14.1.13",
"@types/selenium-webdriver": "4.0.15",
"@types/sharp": "0.29.3",
"@types/string-hash": "1.1.1",
@@ -226,7 +226,7 @@
"tree-kill": "1.2.2",
"tsec": "0.2.1",
"turbo": "1.10.9",
- "typescript": "5.1.3",
+ "typescript": "5.2.2",
"unfetch": "4.2.0",
"wait-port": "0.2.2",
"webpack": "5.86.0",
diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json
index cca799bdb09c9..93dd0606ab6e7 100644
--- a/packages/create-next-app/package.json
+++ b/packages/create-next-app/package.json
@@ -1,6 +1,6 @@
{
"name": "create-next-app",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"keywords": [
"react",
"next",
diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json
index 8e028a9ab6d75..d8032af352f66 100644
--- a/packages/eslint-config-next/package.json
+++ b/packages/eslint-config-next/package.json
@@ -1,6 +1,6 @@
{
"name": "eslint-config-next",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"description": "ESLint configuration used by Next.js.",
"main": "index.js",
"license": "MIT",
@@ -10,7 +10,7 @@
},
"homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config",
"dependencies": {
- "@next/eslint-plugin-next": "13.4.20-canary.20",
+ "@next/eslint-plugin-next": "13.4.20-canary.21",
"@rushstack/eslint-patch": "^1.3.3",
"@typescript-eslint/parser": "^5.4.2 || ^6.0.0",
"eslint-import-resolver-node": "^0.3.6",
diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json
index 61d7b0aa5012f..2d2c6da7a230c 100644
--- a/packages/eslint-plugin-next/package.json
+++ b/packages/eslint-plugin-next/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/eslint-plugin-next",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"description": "ESLint plugin for NextJS.",
"main": "dist/index.js",
"license": "MIT",
diff --git a/packages/font/package.json b/packages/font/package.json
index 590100e487387..20b38c3da5458 100644
--- a/packages/font/package.json
+++ b/packages/font/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/font",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"repository": {
"url": "vercel/next.js",
"directory": "packages/font"
diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json
index 11e767e1d13e3..ba98bb5b04259 100644
--- a/packages/next-bundle-analyzer/package.json
+++ b/packages/next-bundle-analyzer/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/bundle-analyzer",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"main": "index.js",
"types": "index.d.ts",
"license": "MIT",
diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json
index 42ac260ab258e..60c2888bcfe50 100644
--- a/packages/next-codemod/package.json
+++ b/packages/next-codemod/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/codemod",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"license": "MIT",
"repository": {
"type": "git",
diff --git a/packages/next-env/package.json b/packages/next-env/package.json
index dbac7a4a5d26e..38d1e9f40a0bd 100644
--- a/packages/next-env/package.json
+++ b/packages/next-env/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/env",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"keywords": [
"react",
"next",
diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json
index 75739c7731f17..01daaf6790025 100644
--- a/packages/next-mdx/package.json
+++ b/packages/next-mdx/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/mdx",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"main": "index.js",
"license": "MIT",
"repository": {
diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json
index 1af2a0530ad19..fd6347ce0ca81 100644
--- a/packages/next-plugin-storybook/package.json
+++ b/packages/next-plugin-storybook/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-storybook",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-storybook"
diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json
index f333bb9010080..d7bb163c02bc2 100644
--- a/packages/next-polyfill-module/package.json
+++ b/packages/next-polyfill-module/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-module",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)",
"main": "dist/polyfill-module.js",
"license": "MIT",
diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json
index c7b23dcd1e426..63889fce9a931 100644
--- a/packages/next-polyfill-nomodule/package.json
+++ b/packages/next-polyfill-nomodule/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-nomodule",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"description": "A polyfill for non-dead, nomodule browsers.",
"main": "dist/polyfill-nomodule.js",
"license": "MIT",
diff --git a/packages/next-swc/crates/next-api/src/app.rs b/packages/next-swc/crates/next-api/src/app.rs
index 12ed8e5498879..295b57369a6d3 100644
--- a/packages/next-swc/crates/next-api/src/app.rs
+++ b/packages/next-swc/crates/next-api/src/app.rs
@@ -8,7 +8,7 @@ use next_core::{
mode::NextMode,
next_app::{
get_app_client_references_chunks, get_app_client_shared_chunks, get_app_page_entry,
- get_app_route_entry, AppEntry,
+ get_app_route_entry, AppEntry, AppPage,
},
next_client::{
get_client_module_options_context, get_client_resolve_options_context,
@@ -344,8 +344,7 @@ impl AppProject {
.map(|(pathname, app_entrypoint)| async {
Ok((
pathname.clone(),
- *app_entry_point_to_route(self, app_entrypoint.clone(), pathname.clone())
- .await?,
+ *app_entry_point_to_route(self, app_entrypoint.clone()).await?,
))
})
.try_join()
@@ -360,13 +359,9 @@ impl AppProject {
pub async fn app_entry_point_to_route(
app_project: Vc,
entrypoint: AppEntrypoint,
- pathname: String,
) -> Vc {
match entrypoint {
- AppEntrypoint::AppPage {
- original_name,
- loader_tree,
- } => Route::AppPage {
+ AppEntrypoint::AppPage { page, loader_tree } => Route::AppPage {
html_endpoint: Vc::upcast(
AppEndpoint {
ty: AppEndpointType::Page {
@@ -374,8 +369,7 @@ pub async fn app_entry_point_to_route(
loader_tree,
},
app_project,
- pathname: pathname.clone(),
- original_name: original_name.clone(),
+ page: page.clone(),
}
.cell(),
),
@@ -386,22 +380,17 @@ pub async fn app_entry_point_to_route(
loader_tree,
},
app_project,
- pathname,
- original_name,
+ page,
}
.cell(),
),
},
- AppEntrypoint::AppRoute {
- original_name,
- path,
- } => Route::AppRoute {
+ AppEntrypoint::AppRoute { page, path } => Route::AppRoute {
endpoint: Vc::upcast(
AppEndpoint {
ty: AppEndpointType::Route { path },
app_project,
- pathname,
- original_name,
+ page,
}
.cell(),
),
@@ -431,8 +420,7 @@ enum AppEndpointType {
struct AppEndpoint {
ty: AppEndpointType,
app_project: Vc,
- pathname: String,
- original_name: String,
+ page: AppPage,
}
#[turbo_tasks::value_impl]
@@ -444,8 +432,7 @@ impl AppEndpoint {
self.app_project.edge_rsc_module_context(),
loader_tree,
self.app_project.app_dir(),
- self.pathname.clone(),
- self.original_name.clone(),
+ self.page.clone(),
self.app_project.project().project_path(),
)
}
@@ -456,8 +443,7 @@ impl AppEndpoint {
self.app_project.rsc_module_context(),
self.app_project.edge_rsc_module_context(),
Vc::upcast(FileSource::new(path)),
- self.pathname.clone(),
- self.original_name.clone(),
+ self.page.clone(),
self.app_project.project().project_path(),
)
}
diff --git a/packages/next-swc/crates/next-build/src/next_app/app_entries.rs b/packages/next-swc/crates/next-build/src/next_app/app_entries.rs
index 973b30ea7d548..9c7271ecdd66d 100644
--- a/packages/next-swc/crates/next-build/src/next_app/app_entries.rs
+++ b/packages/next-swc/crates/next-build/src/next_app/app_entries.rs
@@ -187,31 +187,23 @@ pub async fn get_app_entries(
let mut entries = entrypoints
.await?
.iter()
- .map(|(pathname, entrypoint)| async move {
+ .map(|(_, entrypoint)| async move {
Ok(match entrypoint {
- Entrypoint::AppPage {
- original_name,
- loader_tree,
- } => get_app_page_entry(
+ Entrypoint::AppPage { page, loader_tree } => get_app_page_entry(
rsc_context,
// TODO add edge support
rsc_context,
*loader_tree,
app_dir,
- pathname.clone(),
- original_name.clone(),
+ page.clone(),
project_root,
),
- Entrypoint::AppRoute {
- original_name,
- path,
- } => get_app_route_entry(
+ Entrypoint::AppRoute { page, path } => get_app_route_entry(
rsc_context,
// TODO add edge support
rsc_context,
Vc::upcast(FileSource::new(*path)),
- pathname.clone(),
- original_name.clone(),
+ page.clone(),
project_root,
),
})
diff --git a/packages/next-swc/crates/next-core/Cargo.toml b/packages/next-swc/crates/next-core/Cargo.toml
index 5b50aff1185cf..38bcb02a3cda6 100644
--- a/packages/next-swc/crates/next-core/Cargo.toml
+++ b/packages/next-swc/crates/next-core/Cargo.toml
@@ -39,6 +39,7 @@ turbopack-binding = { workspace = true, features = [
"__turbo_tasks_hash",
"__turbopack",
"__turbopack_build",
+ "__turbopack_cli_utils",
"__turbopack_core",
"__turbopack_dev",
"__turbopack_dev_server",
diff --git a/packages/next-swc/crates/next-core/js/src/entry/app-edge-renderer.tsx b/packages/next-swc/crates/next-core/js/src/entry/app-edge-renderer.tsx
index 38f27b3c1c7a3..fdec9ffc360fe 100644
--- a/packages/next-swc/crates/next-core/js/src/entry/app-edge-renderer.tsx
+++ b/packages/next-swc/crates/next-core/js/src/entry/app-edge-renderer.tsx
@@ -2,8 +2,6 @@
// the other imports
import startOperationStreamHandler from '../internal/operation-stream'
-import 'next/dist/server/node-polyfill-fetch'
-
import { join } from 'path'
import { parse as parseUrl } from 'node:url'
diff --git a/packages/next-swc/crates/next-core/js/src/entry/app-renderer.tsx b/packages/next-swc/crates/next-core/js/src/entry/app-renderer.tsx
index 25437fec08ef4..951f91570d92d 100644
--- a/packages/next-swc/crates/next-core/js/src/entry/app-renderer.tsx
+++ b/packages/next-swc/crates/next-core/js/src/entry/app-renderer.tsx
@@ -3,15 +3,13 @@
import startOperationStreamHandler from '../internal/operation-stream'
import '../polyfill/app-polyfills.ts'
-// TODO: when actions are supported, this should be removed/changed
-process.env.__NEXT_PRIVATE_PREBUNDLED_REACT = 'next'
-import 'next/dist/server/require-hook'
import type { IncomingMessage } from 'node:http'
import type { RenderData } from 'types/turbopack'
import type { RenderOpts } from 'next/dist/server/app-render/types'
+import { renderToHTMLOrFlight } from 'next/dist/server/app-render/app-render'
import { RSC_VARY_HEADER } from 'next/dist/client/components/app-router-headers'
import { headersFromEntries, initProxiedHeaders } from '../internal/headers'
import { parse, ParsedUrlQuery } from 'node:querystring'
@@ -25,10 +23,6 @@ import { join } from 'node:path'
import { nodeFs } from 'next/dist/server/lib/node-fs-methods'
import { IncrementalCache } from 'next/dist/server/lib/incremental-cache'
-const {
- renderToHTMLOrFlight,
-} = require('next/dist/compiled/next-server/app-page.runtime.dev')
-
installRequireAndChunkLoad()
const MIME_TEXT_HTML_UTF8 = 'text/html; charset=utf-8'
diff --git a/packages/next-swc/crates/next-core/js/src/entry/app/hydrate.tsx b/packages/next-swc/crates/next-core/js/src/entry/app/hydrate.tsx
index c4e1bce96aa5e..abdf23d0fd7d3 100644
--- a/packages/next-swc/crates/next-core/js/src/entry/app/hydrate.tsx
+++ b/packages/next-swc/crates/next-core/js/src/entry/app/hydrate.tsx
@@ -6,7 +6,7 @@ import { createFromReadableStream } from 'next/dist/compiled/react-server-dom-we
import { callServer } from 'next/dist/client/app-call-server'
import { linkGc } from 'next/dist/client/app-link-gc'
-import { HeadManagerContext } from 'next/dist/shared/lib/head-manager-context.shared-runtime'
+import { HeadManagerContext } from 'next/dist/shared/lib/head-manager-context'
import { initializeHMR } from '@vercel/turbopack-next/dev/client'
diff --git a/packages/next-swc/crates/next-core/js/src/internal/page-server-handler.tsx b/packages/next-swc/crates/next-core/js/src/internal/page-server-handler.tsx
index cecafb35f77a7..6182b2d7d4539 100644
--- a/packages/next-swc/crates/next-core/js/src/internal/page-server-handler.tsx
+++ b/packages/next-swc/crates/next-core/js/src/internal/page-server-handler.tsx
@@ -3,12 +3,11 @@
import { IPC } from '@vercel/turbopack-node/ipc/index'
import 'next/dist/server/node-polyfill-fetch.js'
-import 'next/dist/server/require-hook'
import './shims'
import type { IncomingMessage, ServerResponse } from 'node:http'
-import type { RenderOpts } from 'next/dist/server/render'
+import { renderToHTML, RenderOpts } from 'next/dist/server/render'
import { getRedirectStatus } from 'next/dist/lib/redirect-status'
import { PERMANENT_REDIRECT_STATUS } from 'next/dist/shared/lib/constants'
import { buildStaticPaths } from 'next/dist/build/utils'
@@ -22,9 +21,6 @@ import type { RenderData } from 'types/turbopack'
import type { ChunkGroup } from 'types/next'
import type { NextComponentType } from 'next/types'
import { parse } from 'node:querystring'
-const {
- renderToHTML,
-} = require('next/dist/compiled/next-server/pages.runtime.dev')
const ipc = IPC as Ipc
diff --git a/packages/next-swc/crates/next-core/js/tsconfig.json b/packages/next-swc/crates/next-core/js/tsconfig.json
index a10e864117372..f7c18306acf89 100644
--- a/packages/next-swc/crates/next-core/js/tsconfig.json
+++ b/packages/next-swc/crates/next-core/js/tsconfig.json
@@ -4,23 +4,19 @@
"strict": true,
"noFallthroughCasesInSwitch": true,
"skipLibCheck": true,
-
// interop constraints
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
-
// js support
"allowJs": true,
"checkJs": false,
-
// environment
"jsx": "react-jsx",
"lib": ["ESNext", "DOM"],
"target": "esnext",
-
// modules
"baseUrl": ".",
- "module": "esnext",
+ "module": "node16",
"moduleResolution": "node16",
"paths": {
"@vercel/turbopack-next/*": ["src/*"],
@@ -31,7 +27,6 @@
},
"resolveJsonModule": true,
"types": ["react/next"],
-
// emit
"noEmit": true,
"stripInternal": true
diff --git a/packages/next-swc/crates/next-core/src/app_source.rs b/packages/next-swc/crates/next-core/src/app_source.rs
index 738f5a4bf938f..cf35f3795f884 100644
--- a/packages/next-swc/crates/next-core/src/app_source.rs
+++ b/packages/next-swc/crates/next-core/src/app_source.rs
@@ -2,7 +2,7 @@ use std::{collections::HashMap, io::Write as _, iter::once};
use anyhow::{bail, Result};
use indexmap::indexmap;
-use indoc::formatdoc;
+use indoc::indoc;
use serde_json::Value as JsonValue;
use turbo_tasks::Vc;
use turbopack_binding::{
@@ -65,7 +65,7 @@ use crate::{
fallback::get_fallback_page,
loader_tree::{LoaderTreeModule, ServerComponentTransition},
mode::NextMode,
- next_app::UnsupportedDynamicMetadataIssue,
+ next_app::{AppPage, AppPath, PathSegment, UnsupportedDynamicMetadataIssue},
next_client::{
context::{
get_client_assets_path, get_client_module_options_context,
@@ -95,31 +95,28 @@ use crate::{
util::{render_data, NextRuntime},
};
-fn pathname_to_segments(pathname: &str) -> Result<(Vec, RouteType)> {
+fn app_path_to_segments(path: &AppPath) -> Result<(Vec, RouteType)> {
let mut segments = Vec::new();
- let mut split = pathname.split('/');
- while let Some(segment) = split.next() {
- if segment.is_empty()
- || (segment.starts_with('(') && segment.ends_with(')') || segment.starts_with('@'))
- {
- // ignore
- } else if segment.starts_with("[[...") && segment.ends_with("]]")
- || segment.starts_with("[...") && segment.ends_with(']')
- {
- // (optional) catch all segment
- if split.remainder().is_some() {
- bail!(
- "Invalid route {}, catch all segment must be the last segment",
- pathname
- )
+ let mut iter = path.iter().peekable();
+
+ while let Some(segment) = iter.next() {
+ match segment {
+ PathSegment::Static(s) => {
+ segments.push(BaseSegment::Static(s.to_string()));
+ }
+ PathSegment::Dynamic(_) => {
+ segments.push(BaseSegment::Dynamic);
+ }
+ PathSegment::CatchAll(_) | PathSegment::OptionalCatchAll(_) => {
+ if iter.peek().is_some() {
+ bail!(
+ "Invalid route {}, catch all segment must be the last segment",
+ path
+ )
+ }
+
+ return Ok((segments, RouteType::CatchAll));
}
- return Ok((segments, RouteType::CatchAll));
- } else if segment.starts_with('[') || segment.ends_with(']') {
- // dynamic segment
- segments.push(BaseSegment::Dynamic);
- } else {
- // normal segment
- segments.push(BaseSegment::Static(segment.to_string()));
}
}
Ok((segments, RouteType::Exact))
@@ -654,12 +651,12 @@ pub async fn create_app_source(
let entrypoints = entrypoints.await?;
let mut sources: Vec<_> = entrypoints
.iter()
- .map(|(pathname, entrypoint)| match *entrypoint {
+ .map(|(_, entrypoint)| match *entrypoint {
Entrypoint::AppPage {
- original_name: _,
+ ref page,
loader_tree,
} => create_app_page_source_for_route(
- pathname.clone(),
+ page.clone(),
loader_tree,
context_ssr,
context,
@@ -672,11 +669,8 @@ pub async fn create_app_source(
output_path,
render_data,
),
- Entrypoint::AppRoute {
- original_name: _,
- path,
- } => create_app_route_source_for_route(
- pathname.clone(),
+ Entrypoint::AppRoute { ref page, path } => create_app_route_source_for_route(
+ page.clone(),
path,
context_ssr,
project_path,
@@ -696,7 +690,7 @@ pub async fn create_app_source(
.collect();
if let Some(&Entrypoint::AppPage {
- original_name: _,
+ page: _,
loader_tree,
}) = entrypoints.get("/_not-found")
{
@@ -769,7 +763,7 @@ async fn create_global_metadata_source(
#[turbo_tasks::function]
async fn create_app_page_source_for_route(
- pathname: String,
+ page: AppPage,
loader_tree: Vc,
context_ssr: Vc,
context: Vc,
@@ -782,11 +776,12 @@ async fn create_app_page_source_for_route(
intermediate_output_path_root: Vc,
render_data: Vc,
) -> Result>> {
- let pathname_vc = Vc::cell(pathname.clone());
+ let app_path = AppPath::from(page.clone());
+ let pathname_vc = Vc::cell(app_path.to_string());
let params_matcher = NextParamsMatcher::new(pathname_vc);
- let (base_segments, route_type) = pathname_to_segments(&pathname)?;
+ let (base_segments, route_type) = app_path_to_segments(&app_path)?;
let source = create_node_rendered_source(
project_path,
@@ -814,7 +809,7 @@ async fn create_app_page_source_for_route(
should_debug("app_source"),
);
- Ok(source.issue_file_path(app_dir, format!("Next.js App Page Route {pathname}")))
+ Ok(source.issue_file_path(app_dir, format!("Next.js App Page Route {app_path}")))
}
#[turbo_tasks::function]
@@ -864,7 +859,7 @@ async fn create_app_not_found_page_source(
#[turbo_tasks::function]
async fn create_app_route_source_for_route(
- pathname: String,
+ page: AppPage,
entry_path: Vc,
context_ssr: Vc,
project_path: Vc,
@@ -875,11 +870,12 @@ async fn create_app_route_source_for_route(
intermediate_output_path_root: Vc,
render_data: Vc,
) -> Result>> {
- let pathname_vc = Vc::cell(pathname.to_string());
+ let app_path = AppPath::from(page.clone());
+ let pathname_vc = Vc::cell(app_path.to_string());
let params_matcher = NextParamsMatcher::new(pathname_vc);
- let (base_segments, route_type) = pathname_to_segments(&pathname)?;
+ let (base_segments, route_type) = app_path_to_segments(&app_path)?;
let source = create_node_api_source(
project_path,
@@ -906,7 +902,7 @@ async fn create_app_route_source_for_route(
should_debug("app_source"),
);
- Ok(source.issue_file_path(app_dir, format!("Next.js App Route {pathname}")))
+ Ok(source.issue_file_path(app_dir, format!("Next.js App Route {app_path}")))
}
/// The renderer for pages in app directory
@@ -968,18 +964,13 @@ impl AppRenderer {
.emit();
}
- let mut result = RopeBuilder::from(
- formatdoc!(
- "
- \"TURBOPACK {{ chunking-type: isolatedParallel; transition: {rsc_transition} }}\";
+ let mut result = RopeBuilder::from(indoc! {"
+ \"TURBOPACK { chunking-type: isolatedParallel; transition: next-edge-server-component }\";
import GlobalErrorMod from \"next/dist/client/components/error-boundary\"
- const {{ GlobalError }} = GlobalErrorMod;
- \"TURBOPACK {{ chunking-type: isolatedParallel; transition: {rsc_transition} }}\";
+ const { GlobalError } = GlobalErrorMod;
+ \"TURBOPACK { chunking-type: isolatedParallel; transition: next-edge-server-component }\";
import base from \"next/dist/server/app-render/entry-base\"\n
- "
- )
- .into_bytes(),
- );
+ "});
for import in loader_tree_module.imports {
writeln!(result, "{import}")?;
diff --git a/packages/next-swc/crates/next-core/src/app_structure.rs b/packages/next-swc/crates/next-core/src/app_structure.rs
index c09ccdc644c98..a3597079af6c0 100644
--- a/packages/next-swc/crates/next-core/src/app_structure.rs
+++ b/packages/next-swc/crates/next-core/src/app_structure.rs
@@ -1,7 +1,11 @@
use std::collections::{BTreeMap, HashMap};
use anyhow::{bail, Result};
-use indexmap::{indexmap, map::Entry, IndexMap};
+use indexmap::{
+ indexmap,
+ map::{Entry, OccupiedEntry},
+ IndexMap,
+};
use once_cell::sync::Lazy;
use regex::Regex;
use serde::{Deserialize, Serialize};
@@ -14,7 +18,11 @@ use turbopack_binding::{
turbopack::core::issue::{Issue, IssueExt, IssueSeverity},
};
-use crate::{next_config::NextConfig, next_import_map::get_next_package};
+use crate::{
+ next_app::{AppPage, AppPath},
+ next_config::NextConfig,
+ next_import_map::get_next_package,
+};
/// A final route in the app directory.
#[turbo_tasks::value]
@@ -447,11 +455,11 @@ async fn merge_loader_trees(
)]
pub enum Entrypoint {
AppPage {
- original_name: String,
+ page: AppPage,
loader_tree: Vc,
},
AppRoute {
- original_name: String,
+ page: AppPage,
path: Vc,
},
}
@@ -487,131 +495,119 @@ async fn add_parallel_route(
Ok(())
}
+fn conflict_issue(
+ app_dir: Vc,
+ e: &OccupiedEntry,
+ a: &str,
+ b: &str,
+ value_a: &AppPage,
+ value_b: &AppPage,
+) {
+ let item_names = if a == b {
+ format!("{}s", a)
+ } else {
+ format!("{} and {}", a, b)
+ };
+
+ DirectoryTreeIssue {
+ app_dir,
+ message: Vc::cell(format!(
+ "Conflicting {} at {}: {a} at {value_a} and {b} at {value_b}",
+ item_names,
+ e.key(),
+ )),
+ severity: IssueSeverity::Error.cell(),
+ }
+ .cell()
+ .emit();
+}
+
async fn add_app_page(
app_dir: Vc,
result: &mut IndexMap,
- key: String,
- original_name: String,
+ page: AppPage,
loader_tree: Vc,
) -> Result<()> {
- match result.entry(key) {
- Entry::Occupied(mut e) => {
- let value = e.get();
- match value {
- Entrypoint::AppPage {
- original_name: existing_original_name,
- ..
- } => {
- if *existing_original_name != original_name {
- DirectoryTreeIssue {
- app_dir,
- message: Vc::cell(format!(
- "Conflicting pages at {}: {existing_original_name} and \
- {original_name}",
- e.key()
- )),
- severity: IssueSeverity::Error.cell(),
- }
- .cell()
- .emit();
- return Ok(());
- }
- if let Entrypoint::AppPage {
- loader_tree: value, ..
- } = e.get_mut()
- {
- *value = merge_loader_trees(app_dir, *value, loader_tree)
- .resolve()
- .await?;
- }
- }
- Entrypoint::AppRoute {
- original_name: existing_original_name,
- ..
- } => {
- DirectoryTreeIssue {
- app_dir,
- message: Vc::cell(format!(
- "Conflicting page and route at {}: route at {existing_original_name} \
- and page at {original_name}",
- e.key()
- )),
- severity: IssueSeverity::Error.cell(),
- }
- .cell()
- .emit();
- return Ok(());
- }
+ let pathname = AppPath::from(page.clone());
+
+ let mut e = match result.entry(format!("{pathname}")) {
+ Entry::Occupied(e) => e,
+ Entry::Vacant(e) => {
+ e.insert(Entrypoint::AppPage { page, loader_tree });
+ return Ok(());
+ }
+ };
+
+ let conflict = |existing_name: &str, existing_page: &AppPage| {
+ conflict_issue(app_dir, &e, "page", existing_name, &page, existing_page);
+ };
+
+ let value = e.get();
+ match value {
+ Entrypoint::AppPage {
+ page: existing_page,
+ ..
+ } => {
+ if *existing_page != page {
+ conflict("page", existing_page);
+ return Ok(());
+ }
+
+ if let Entrypoint::AppPage {
+ loader_tree: value, ..
+ } = e.get_mut()
+ {
+ *value = merge_loader_trees(app_dir, *value, loader_tree)
+ .resolve()
+ .await?;
}
}
- Entry::Vacant(e) => {
- e.insert(Entrypoint::AppPage {
- original_name,
- loader_tree,
- });
+ Entrypoint::AppRoute {
+ page: existing_page,
+ ..
+ } => {
+ conflict("route", existing_page);
}
}
+
Ok(())
}
-async fn add_app_route(
+fn add_app_route(
app_dir: Vc,
result: &mut IndexMap,
- key: String,
- original_name: String,
+ page: AppPage,
path: Vc,
-) -> Result<()> {
- match result.entry(key) {
- Entry::Occupied(mut e) => {
- let value = e.get();
- match value {
- Entrypoint::AppPage {
- original_name: existing_original_name,
- ..
- } => {
- DirectoryTreeIssue {
- app_dir,
- message: Vc::cell(format!(
- "Conflicting route and page at {}: route at {original_name} and page \
- at {existing_original_name}",
- e.key()
- )),
- severity: IssueSeverity::Error.cell(),
- }
- .cell()
- .emit();
- }
- Entrypoint::AppRoute {
- original_name: existing_original_name,
- ..
- } => {
- DirectoryTreeIssue {
- app_dir,
- message: Vc::cell(format!(
- "Conflicting routes at {}: {existing_original_name} and \
- {original_name}",
- e.key()
- )),
- severity: IssueSeverity::Error.cell(),
- }
- .cell()
- .emit();
- return Ok(());
- }
- }
- *e.get_mut() = Entrypoint::AppRoute {
- original_name,
- path,
- };
- }
+) {
+ let pathname = AppPath::from(page.clone());
+
+ let e = match result.entry(format!("{pathname}")) {
+ Entry::Occupied(e) => e,
Entry::Vacant(e) => {
- e.insert(Entrypoint::AppRoute {
- original_name,
- path,
- });
+ e.insert(Entrypoint::AppRoute { page, path });
+ return;
+ }
+ };
+
+ let conflict = |existing_name: &str, existing_page: &AppPage| {
+ conflict_issue(app_dir, &e, "route", existing_name, &page, existing_page);
+ };
+
+ let value = e.get();
+ match value {
+ Entrypoint::AppPage {
+ page: existing_page,
+ ..
+ } => {
+ conflict("page", existing_page);
+ }
+ Entrypoint::AppRoute {
+ page: existing_page,
+ ..
+ } => {
+ conflict("route", existing_page);
}
}
- Ok(())
}
#[turbo_tasks::function]
@@ -627,13 +623,7 @@ fn directory_tree_to_entrypoints(
app_dir: Vc,
directory_tree: Vc,
) -> Vc {
- directory_tree_to_entrypoints_internal(
- app_dir,
- "".to_string(),
- directory_tree,
- "/".to_string(),
- "/".to_string(),
- )
+ directory_tree_to_entrypoints_internal(app_dir, "".to_string(), directory_tree, AppPage::new())
}
#[turbo_tasks::function]
@@ -641,8 +631,7 @@ async fn directory_tree_to_entrypoints_internal(
app_dir: Vc,
directory_name: String,
directory_tree: Vc,
- path_prefix: String,
- original_name_prefix: String,
+ app_page: AppPage,
) -> Result> {
let mut result = IndexMap::new();
@@ -657,8 +646,7 @@ async fn directory_tree_to_entrypoints_internal(
add_app_page(
app_dir,
&mut result,
- path_prefix.to_string(),
- original_name_prefix.to_string(),
+ app_page.clone(),
if current_level_is_parallel_route {
LoaderTree {
segment: "__PAGE__".to_string(),
@@ -697,8 +685,7 @@ async fn directory_tree_to_entrypoints_internal(
add_app_page(
app_dir,
&mut result,
- path_prefix.to_string(),
- original_name_prefix.to_string(),
+ app_page.clone(),
if current_level_is_parallel_route {
LoaderTree {
segment: "__DEFAULT__".to_string(),
@@ -734,17 +721,11 @@ async fn directory_tree_to_entrypoints_internal(
}
if let Some(route) = components.route {
- add_app_route(
- app_dir,
- &mut result,
- path_prefix.to_string(),
- original_name_prefix.to_string(),
- route,
- )
- .await?;
+ add_app_route(app_dir, &mut result, app_page.clone(), route);
}
- if path_prefix == "/" {
+ // root path: /
+ if app_page.len() == 0 {
// Next.js has this logic in "collect-app-paths", where the root not-found page
// is considered as its own entry point.
if let Some(_not_found) = components.not_found {
@@ -766,22 +747,14 @@ async fn directory_tree_to_entrypoints_internal(
}
.cell();
- add_app_page(
- app_dir,
- &mut result,
- "/not-found".to_string(),
- "/not-found".to_string(),
- dev_not_found_tree,
- )
- .await?;
- add_app_page(
- app_dir,
- &mut result,
- "/_not-found".to_string(),
- "/_not-found".to_string(),
- dev_not_found_tree,
- )
- .await?;
+ {
+ let app_page = app_page.clone_push_str("not-found")?;
+ add_app_page(app_dir, &mut result, app_page, dev_not_found_tree).await?;
+ }
+ {
+ let app_page = app_page.clone_push_str("_not-found")?;
+ add_app_page(app_dir, &mut result, app_page, dev_not_found_tree).await?;
+ }
} else {
// Create default not-found page for production if there's no customized
// not-found
@@ -803,55 +776,35 @@ async fn directory_tree_to_entrypoints_internal(
}
.cell();
- add_app_page(
- app_dir,
- &mut result,
- "/_not-found".to_string(),
- "/_not-found".to_string(),
- prod_not_found_tree,
- )
- .await?;
+ let app_page = app_page.clone_push_str("_not-found")?;
+ add_app_page(app_dir, &mut result, app_page, prod_not_found_tree).await?;
}
}
for (subdir_name, &subdirectory) in subdirectories.iter() {
- let is_route_group = subdir_name.starts_with('(') && subdir_name.ends_with(')');
let parallel_route_key = match_parallel_route(subdir_name);
+
+ let mut app_page = app_page.clone();
+ if parallel_route_key.is_none() {
+ app_page.push_str(subdir_name)?;
+ }
+
let map = directory_tree_to_entrypoints_internal(
app_dir,
subdir_name.to_string(),
subdirectory,
- if is_route_group || parallel_route_key.is_some() {
- path_prefix.clone()
- } else if path_prefix == "/" {
- format!("/{subdir_name}")
- } else {
- format!("{path_prefix}/{subdir_name}")
- },
- if parallel_route_key.is_some() {
- original_name_prefix.clone()
- } else if original_name_prefix == "/" {
- format!("/{subdir_name}")
- } else {
- format!("{original_name_prefix}/{subdir_name}")
- },
+ app_page,
)
.await?;
- for (full_path, entrypoint) in map.iter() {
+
+ for (_, entrypoint) in map.iter() {
match *entrypoint {
Entrypoint::AppPage {
- ref original_name,
+ ref page,
loader_tree,
} => {
if current_level_is_parallel_route {
- add_app_page(
- app_dir,
- &mut result,
- full_path.clone(),
- original_name.clone(),
- loader_tree,
- )
- .await?;
+ add_app_page(app_dir, &mut result, page.clone(), loader_tree).await?;
} else {
let key = parallel_route_key.unwrap_or("children").to_string();
let child_loader_tree = LoaderTree {
@@ -862,28 +815,11 @@ async fn directory_tree_to_entrypoints_internal(
components: components.without_leafs().cell(),
}
.cell();
- add_app_page(
- app_dir,
- &mut result,
- full_path.clone(),
- original_name.clone(),
- child_loader_tree,
- )
- .await?;
+ add_app_page(app_dir, &mut result, page.clone(), child_loader_tree).await?;
}
}
- Entrypoint::AppRoute {
- ref original_name,
- path,
- } => {
- add_app_route(
- app_dir,
- &mut result,
- full_path.clone(),
- original_name.clone(),
- path,
- )
- .await?;
+ Entrypoint::AppRoute { ref page, path } => {
+ add_app_route(app_dir, &mut result, page.clone(), path);
}
}
}
diff --git a/packages/next-swc/crates/next-core/src/next_app/app_favicon_entry.rs b/packages/next-swc/crates/next-core/src/next_app/app_favicon_entry.rs
index 0f4df5eb01f39..b72fc9af399ab 100644
--- a/packages/next-swc/crates/next-core/src/next_app/app_favicon_entry.rs
+++ b/packages/next-swc/crates/next-core/src/next_app/app_favicon_entry.rs
@@ -14,7 +14,10 @@ use turbopack_binding::{
};
use super::app_route_entry::get_app_route_entry;
-use crate::{app_structure::MetadataItem, next_app::AppEntry};
+use crate::{
+ app_structure::MetadataItem,
+ next_app::{AppEntry, AppPage, PageSegment},
+};
/// Computes the entry for a Next.js favicon file.
#[turbo_tasks::function]
@@ -57,7 +60,7 @@ pub async fn get_app_route_favicon_entry(
const contentType = {content_type}
const cacheControl = {cache_control}
const buffer = Buffer.from({original_file_content_b64}, 'base64')
-
+
export function GET() {{
return new NextResponse(buffer, {{
headers: {{
@@ -66,7 +69,7 @@ pub async fn get_app_route_favicon_entry(
}},
}})
}}
-
+
export const dynamic = 'force-static'
"#,
content_type = StringifyJs(&content_type),
@@ -84,8 +87,7 @@ pub async fn get_app_route_favicon_entry(
edge_context,
Vc::upcast(source),
// TODO(alexkirsz) Get this from the metadata?
- "/favicon.ico".to_string(),
- "/favicon.ico".to_string(),
+ AppPage(vec![PageSegment::Static("/favicon.ico".to_string())]),
project_root,
))
}
diff --git a/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs b/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs
index bde79e2c38b4d..fd99d25664678 100644
--- a/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs
+++ b/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs
@@ -19,7 +19,7 @@ use crate::{
app_structure::LoaderTree,
loader_tree::{LoaderTreeModule, ServerComponentTransition},
mode::NextMode,
- next_app::UnsupportedDynamicMetadataIssue,
+ next_app::{AppPage, AppPath, UnsupportedDynamicMetadataIssue},
next_server_component::NextServerComponentTransition,
parse_segment_config_from_loader_tree,
util::{load_next_js_template, virtual_next_js_template_path, NextRuntime},
@@ -32,8 +32,7 @@ pub async fn get_app_page_entry(
edge_context: Vc,
loader_tree: Vc,
app_dir: Vc,
- pathname: String,
- original_name: String,
+ page: AppPage,
project_root: Vc,
) -> Result> {
let config = parse_segment_config_from_loader_tree(loader_tree, Vc::upcast(nodejs_context));
@@ -79,6 +78,9 @@ pub async fn get_app_page_entry(
let pages = pages.iter().map(|page| page.to_string()).try_join().await?;
+ let original_name = page.to_string();
+ let pathname = AppPath::from(page.clone()).to_string();
+
let original_page_name = get_original_page_name(&original_name);
let template_file = "build/templates/app-page.js";
@@ -90,7 +92,7 @@ pub async fn get_app_page_entry(
.to_str()?
.replace(
"\"VAR_DEFINITION_PAGE\"",
- &StringifyJs(&original_name).to_string(),
+ &StringifyJs(&page.to_string()).to_string(),
)
.replace(
"\"VAR_DEFINITION_PATHNAME\"",
diff --git a/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs b/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs
index 45cf5470f40e1..e60c963e0ece0 100644
--- a/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs
+++ b/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs
@@ -21,7 +21,7 @@ use turbopack_binding::{
};
use crate::{
- next_app::AppEntry,
+ next_app::{AppEntry, AppPage, AppPath},
parse_segment_config_from_source,
util::{load_next_js_template, virtual_next_js_template_path, NextRuntime},
};
@@ -32,8 +32,7 @@ pub async fn get_app_route_entry(
nodejs_context: Vc,
edge_context: Vc,
source: Vc>,
- pathname: String,
- original_name: String,
+ page: AppPage,
project_root: Vc,
) -> Result> {
let config = parse_segment_config_from_source(
@@ -52,6 +51,9 @@ pub async fn get_app_route_entry(
let mut result = RopeBuilder::default();
+ let original_name = page.to_string();
+ let pathname = AppPath::from(page.clone()).to_string();
+
let original_page_name = get_original_route_name(&original_name);
let path = source.ident().path();
diff --git a/packages/next-swc/crates/next-core/src/next_app/mod.rs b/packages/next-swc/crates/next-core/src/next_app/mod.rs
index 7f40ca34fb94c..885ecdf4cd715 100644
--- a/packages/next-swc/crates/next-core/src/next_app/mod.rs
+++ b/packages/next-swc/crates/next-core/src/next_app/mod.rs
@@ -6,12 +6,283 @@ pub(crate) mod app_page_entry;
pub(crate) mod app_route_entry;
pub(crate) mod unsupported_dynamic_metadata_issue;
-pub use app_client_references_chunks::{
- get_app_client_references_chunks, ClientReferenceChunks, ClientReferencesChunks,
+use std::{
+ fmt::{Display, Formatter, Write},
+ ops::Deref,
};
-pub use app_client_shared_chunks::get_app_client_shared_chunks;
-pub use app_entry::AppEntry;
-pub use app_favicon_entry::get_app_route_favicon_entry;
-pub use app_page_entry::get_app_page_entry;
-pub use app_route_entry::get_app_route_entry;
-pub use unsupported_dynamic_metadata_issue::UnsupportedDynamicMetadataIssue;
+
+use anyhow::{bail, Result};
+use serde::{Deserialize, Serialize};
+use turbo_tasks::{trace::TraceRawVcs, TaskInput};
+
+pub use crate::next_app::{
+ app_client_references_chunks::{
+ get_app_client_references_chunks, ClientReferenceChunks, ClientReferencesChunks,
+ },
+ app_client_shared_chunks::get_app_client_shared_chunks,
+ app_entry::AppEntry,
+ app_favicon_entry::get_app_route_favicon_entry,
+ app_page_entry::get_app_page_entry,
+ app_route_entry::get_app_route_entry,
+ unsupported_dynamic_metadata_issue::UnsupportedDynamicMetadataIssue,
+};
+
+#[derive(Clone, Debug, Hash, Serialize, Deserialize, PartialEq, Eq, TaskInput, TraceRawVcs)]
+pub enum PageSegment {
+ Static(String),
+ Dynamic(String),
+ CatchAll(String),
+ OptionalCatchAll(String),
+ Group(String),
+ Parallel(String),
+ PageType(PageType),
+}
+
+impl PageSegment {
+ pub fn parse(segment: &str) -> Result {
+ if segment.is_empty() {
+ bail!("empty segments are not allowed");
+ }
+
+ if segment.contains('/') {
+ bail!("slashes are not allowed in segments");
+ }
+
+ if let Some(s) = segment.strip_prefix('(').and_then(|s| s.strip_suffix(')')) {
+ return Ok(PageSegment::Group(s.to_string()));
+ }
+
+ if let Some(s) = segment.strip_prefix('@') {
+ return Ok(PageSegment::Parallel(s.to_string()));
+ }
+
+ if let Some(s) = segment
+ .strip_prefix("[[...")
+ .and_then(|s| s.strip_suffix("]]"))
+ {
+ return Ok(PageSegment::OptionalCatchAll(s.to_string()));
+ }
+
+ if let Some(s) = segment
+ .strip_prefix("[...")
+ .and_then(|s| s.strip_suffix(']'))
+ {
+ return Ok(PageSegment::CatchAll(s.to_string()));
+ }
+
+ if let Some(s) = segment.strip_prefix('[').and_then(|s| s.strip_suffix(']')) {
+ return Ok(PageSegment::Dynamic(s.to_string()));
+ }
+
+ Ok(PageSegment::Static(segment.to_string()))
+ }
+}
+
+impl Display for PageSegment {
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+ match self {
+ PageSegment::Static(s) => f.write_str(s),
+ PageSegment::Dynamic(s) => {
+ f.write_char('[')?;
+ f.write_str(s)?;
+ f.write_char(']')
+ }
+ PageSegment::CatchAll(s) => {
+ f.write_str("[...")?;
+ f.write_str(s)?;
+ f.write_char(']')
+ }
+ PageSegment::OptionalCatchAll(s) => {
+ f.write_str("[[...")?;
+ f.write_str(s)?;
+ f.write_str("]]")
+ }
+ PageSegment::Group(s) => {
+ f.write_char('(')?;
+ f.write_str(s)?;
+ f.write_char(')')
+ }
+ PageSegment::Parallel(s) => {
+ f.write_char('@')?;
+ f.write_str(s)
+ }
+ PageSegment::PageType(s) => Display::fmt(s, f),
+ }
+ }
+}
+
+#[derive(Clone, Debug, Hash, Serialize, Deserialize, PartialEq, Eq, TaskInput, TraceRawVcs)]
+pub enum PageType {
+ Page,
+ Route,
+}
+
+impl Display for PageType {
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+ f.write_str(match self {
+ PageType::Page => "page",
+ PageType::Route => "route",
+ })
+ }
+}
+
+/// Describes the pathname including all internal modifiers such as
+/// intercepting routes, parallel routes and route/page suffixes that are not
+/// part of the pathname.
+#[derive(
+ Clone, Debug, Hash, PartialEq, Eq, Default, Serialize, Deserialize, TaskInput, TraceRawVcs,
+)]
+pub struct AppPage(pub Vec);
+
+impl AppPage {
+ pub fn new() -> Self {
+ Self::default()
+ }
+
+ pub fn push(&mut self, segment: PageSegment) -> Result<()> {
+ if matches!(
+ self.0.last(),
+ Some(PageSegment::CatchAll(..) | PageSegment::OptionalCatchAll(..))
+ ) && !matches!(segment, PageSegment::PageType(..))
+ {
+ bail!(
+ "Invalid segment {}, catch all segment must be the last segment",
+ segment
+ )
+ }
+
+ self.0.push(segment);
+ Ok(())
+ }
+
+ pub fn push_str(&mut self, segment: &str) -> Result<()> {
+ if segment.is_empty() {
+ return Ok(());
+ }
+
+ self.push(PageSegment::parse(segment)?)
+ }
+
+ pub fn clone_push(&self, segment: PageSegment) -> Result {
+ let mut cloned = self.clone();
+ cloned.push(segment)?;
+ Ok(cloned)
+ }
+
+ pub fn clone_push_str(&self, segment: &str) -> Result {
+ let mut cloned = self.clone();
+ cloned.push_str(segment)?;
+ Ok(cloned)
+ }
+
+ pub fn parse(page: &str) -> Result {
+ let mut app_page = Self::new();
+
+ for segment in page.split('/') {
+ app_page.push_str(segment)?;
+ }
+
+ Ok(app_page)
+ }
+}
+
+impl Display for AppPage {
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+ if self.0.is_empty() {
+ return f.write_char('/');
+ }
+
+ for segment in &self.0 {
+ f.write_char('/')?;
+ Display::fmt(segment, f)?;
+ }
+
+ Ok(())
+ }
+}
+
+impl Deref for AppPage {
+ type Target = [PageSegment];
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+#[derive(Clone, Debug, Hash, Serialize, Deserialize, PartialEq, Eq, TaskInput, TraceRawVcs)]
+pub enum PathSegment {
+ Static(String),
+ Dynamic(String),
+ CatchAll(String),
+ OptionalCatchAll(String),
+}
+
+impl Display for PathSegment {
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+ match self {
+ PathSegment::Static(s) => f.write_str(s),
+ PathSegment::Dynamic(s) => {
+ f.write_char('[')?;
+ f.write_str(s)?;
+ f.write_char(']')
+ }
+ PathSegment::CatchAll(s) => {
+ f.write_str("[...")?;
+ f.write_str(s)?;
+ f.write_char(']')
+ }
+ PathSegment::OptionalCatchAll(s) => {
+ f.write_str("[[...")?;
+ f.write_str(s)?;
+ f.write_str("]]")
+ }
+ }
+ }
+}
+
+/// The pathname (including dynamic placeholders) for a route to resolve.
+#[derive(
+ Clone, Debug, Hash, PartialEq, Eq, Default, Serialize, Deserialize, TaskInput, TraceRawVcs,
+)]
+pub struct AppPath(pub Vec);
+
+impl Deref for AppPath {
+ type Target = [PathSegment];
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+impl Display for AppPath {
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+ if self.0.is_empty() {
+ return f.write_char('/');
+ }
+
+ for segment in &self.0 {
+ f.write_char('/')?;
+ Display::fmt(segment, f)?;
+ }
+
+ Ok(())
+ }
+}
+
+impl From for AppPath {
+ fn from(value: AppPage) -> Self {
+ AppPath(
+ value
+ .0
+ .into_iter()
+ .filter_map(|segment| match segment {
+ PageSegment::Static(s) => Some(PathSegment::Static(s)),
+ PageSegment::Dynamic(s) => Some(PathSegment::Dynamic(s)),
+ PageSegment::CatchAll(s) => Some(PathSegment::CatchAll(s)),
+ PageSegment::OptionalCatchAll(s) => Some(PathSegment::OptionalCatchAll(s)),
+ _ => None,
+ })
+ .collect(),
+ )
+ }
+}
diff --git a/packages/next-swc/crates/next-core/src/next_edge/context.rs b/packages/next-swc/crates/next-core/src/next_edge/context.rs
index cfe9eebf19f94..54c7dd3331a63 100644
--- a/packages/next-swc/crates/next-core/src/next_edge/context.rs
+++ b/packages/next-swc/crates/next-core/src/next_edge/context.rs
@@ -96,9 +96,10 @@ pub async fn get_edge_resolve_options_context(
];
match ty {
- ServerContextType::AppRSC { .. } => custom_conditions.push("react-server".to_string()),
- ServerContextType::AppRoute { .. }
- | ServerContextType::Pages { .. }
+ ServerContextType::AppRSC { .. } | ServerContextType::AppRoute { .. } => {
+ custom_conditions.push("react-server".to_string())
+ }
+ ServerContextType::Pages { .. }
| ServerContextType::PagesData { .. }
| ServerContextType::AppSSR { .. }
| ServerContextType::Middleware { .. } => {}
diff --git a/packages/next-swc/crates/next-core/src/next_edge/route_transition.rs b/packages/next-swc/crates/next-core/src/next_edge/route_transition.rs
index 05326de255203..de0bd2f2e7bf7 100644
--- a/packages/next-swc/crates/next-core/src/next_edge/route_transition.rs
+++ b/packages/next-swc/crates/next-core/src/next_edge/route_transition.rs
@@ -58,26 +58,24 @@ impl Transition for NextEdgeRouteTransition {
#[turbo_tasks::function]
async fn process_module(
- self: Vc,
+ &self,
asset: Vc>,
context: Vc,
) -> Result>> {
- let new_context = self.process_context(context);
- let this = self.await?;
let new_asset = route_bootstrap(
asset,
- Vc::upcast(new_context),
- this.base_path,
- this.bootstrap_asset,
+ Vc::upcast(context),
+ self.base_path,
+ self.bootstrap_asset,
Vc::cell(indexmap! {
- "NAME".to_string() => this.entry_name.clone(),
+ "NAME".to_string() => self.entry_name.clone(),
}),
);
let asset = ChunkGroupFilesAsset {
module: Vc::upcast(new_asset),
- client_root: this.output_path,
- chunking_context: this.edge_chunking_context,
+ client_root: self.output_path,
+ chunking_context: self.edge_chunking_context,
runtime_entries: None,
};
diff --git a/packages/next-swc/crates/next-core/src/next_import_map.rs b/packages/next-swc/crates/next-core/src/next_import_map.rs
index c530f3bcb9290..e05ac926c139f 100644
--- a/packages/next-swc/crates/next-core/src/next_import_map.rs
+++ b/packages/next-swc/crates/next-core/src/next_import_map.rs
@@ -216,26 +216,25 @@ pub async fn get_next_server_import_map(
let ty = ty.into_value();
insert_next_server_special_aliases(&mut import_map, ty, mode, NextRuntime::NodeJs).await?;
- let external: Vc = ImportMapping::External(None).cell();
+ let external = ImportMapping::External(None).cell();
- import_map.insert_exact_alias("next/dist/server/require-hook", external);
match ty {
ServerContextType::Pages { .. } | ServerContextType::PagesData { .. } => {
+ import_map.insert_exact_alias("next", external);
+ import_map.insert_wildcard_alias("next/", external);
import_map.insert_exact_alias("react", external);
import_map.insert_wildcard_alias("react/", external);
import_map.insert_exact_alias("react-dom", external);
import_map.insert_wildcard_alias("react-dom/", external);
import_map.insert_exact_alias("styled-jsx", external);
import_map.insert_wildcard_alias("styled-jsx/", external);
- import_map.insert_wildcard_alias("react-server-dom-webpack/", external);
- // TODO: we should not bundle next/dist/build/utils in the pages renderer at all
- import_map.insert_wildcard_alias("next/dist/build/utils", external);
+ import_map.insert_exact_alias("react-server-dom-webpack/", external);
}
ServerContextType::AppSSR { .. }
| ServerContextType::AppRSC { .. }
| ServerContextType::AppRoute { .. } => {
match mode {
- NextMode::Build => {
+ NextMode::Development | NextMode::Build => {
import_map.insert_wildcard_alias("next/dist/server/", external);
import_map.insert_wildcard_alias("next/dist/shared/", external);
}
@@ -243,7 +242,6 @@ pub async fn get_next_server_import_map(
// The sandbox can't be bundled and needs to be external
import_map.insert_exact_alias("next/dist/server/web/sandbox", external);
}
- NextMode::Development => {}
}
import_map.insert_exact_alias(
"next/head",
@@ -379,11 +377,6 @@ async fn insert_next_server_special_aliases(
NextRuntime::Edge => request_to_import_mapping(context_dir, request),
NextRuntime::NodeJs => external_request_to_import_mapping(request),
};
- let passthrough_external_if_node =
- move |context_dir: Vc, request: &str| match runtime {
- NextRuntime::Edge => request_to_import_mapping(context_dir, request),
- NextRuntime::NodeJs => ImportMapping::External(None).cell(),
- };
match (mode, ty) {
(_, ServerContextType::Pages { pages_dir }) => {
import_map.insert_exact_alias(
@@ -420,7 +413,12 @@ async fn insert_next_server_special_aliases(
(_, ServerContextType::PagesData { .. }) => {}
// In development, we *always* use the bundled version of React, even in
// SSR, since we're bundling Next.js alongside it.
- (NextMode::DevServer, ServerContextType::AppSSR { app_dir }) => {
+ (
+ NextMode::DevServer,
+ ServerContextType::AppSSR { app_dir }
+ | ServerContextType::AppRSC { app_dir, .. }
+ | ServerContextType::AppRoute { app_dir },
+ ) => {
import_map.insert_exact_alias(
"@opentelemetry/api",
// TODO(WEB-625) this actually need to prefer the local version of
@@ -429,40 +427,28 @@ async fn insert_next_server_special_aliases(
);
import_map.insert_exact_alias(
"react",
- passthrough_external_if_node(app_dir, "next/dist/compiled/react"),
+ request_to_import_mapping(app_dir, "next/dist/compiled/react"),
);
import_map.insert_wildcard_alias(
"react/",
- passthrough_external_if_node(app_dir, "next/dist/compiled/react/*"),
+ request_to_import_mapping(app_dir, "next/dist/compiled/react/*"),
);
import_map.insert_exact_alias(
"react-dom",
- passthrough_external_if_node(
+ request_to_import_mapping(
app_dir,
"next/dist/compiled/react-dom/server-rendering-stub.js",
),
);
import_map.insert_wildcard_alias(
"react-dom/",
- passthrough_external_if_node(app_dir, "next/dist/compiled/react-dom/*"),
- );
- import_map.insert_exact_alias(
- "styled-jsx",
- passthrough_external_if_node(app_dir, "next/dist/compiled/styled-jsx"),
- );
- import_map.insert_wildcard_alias(
- "styled-jsx/",
- passthrough_external_if_node(app_dir, "next/dist/compiled/styled-jsx/*"),
+ request_to_import_mapping(app_dir, "next/dist/compiled/react-dom/*"),
);
import_map.insert_wildcard_alias(
"react-server-dom-webpack/",
- passthrough_external_if_node(
- app_dir,
- "next/dist/compiled/react-server-dom-webpack/*",
- ),
+ request_to_import_mapping(app_dir, "next/dist/compiled/react-server-dom-webpack/*"),
);
}
-
// NOTE(alexkirsz) This logic maps loosely to
// `next.js/packages/next/src/build/webpack-config.ts`, where:
//
@@ -474,7 +460,7 @@ async fn insert_next_server_special_aliases(
// * passes through (react|react-dom|react-server-dom-webpack)/(.*) to
// next/dist/compiled/$1/$2
(
- NextMode::Build | NextMode::Development | NextMode::DevServer,
+ NextMode::Build | NextMode::Development,
ServerContextType::AppRSC { app_dir, .. } | ServerContextType::AppRoute { app_dir },
) => {
import_map.insert_exact_alias(
@@ -483,20 +469,10 @@ async fn insert_next_server_special_aliases(
// @opentelemetry/api
request_to_import_mapping(app_dir, "next/dist/compiled/@opentelemetry/api"),
);
- if matches!(ty, ServerContextType::AppRSC { .. }) {
- import_map.insert_exact_alias(
- "react",
- request_to_import_mapping(
- app_dir,
- "next/dist/compiled/react/react.shared-subset",
- ),
- );
- } else {
- import_map.insert_exact_alias(
- "react",
- request_to_import_mapping(app_dir, "next/dist/compiled/react"),
- );
- }
+ import_map.insert_exact_alias(
+ "react",
+ request_to_import_mapping(app_dir, "next/dist/compiled/react/react.shared-subset"),
+ );
import_map.insert_exact_alias(
"react-dom",
request_to_import_mapping(
diff --git a/packages/next-swc/crates/next-core/src/next_server/context.rs b/packages/next-swc/crates/next-core/src/next_server/context.rs
index 1d242498b36df..e7485ff100ade 100644
--- a/packages/next-swc/crates/next-core/src/next_server/context.rs
+++ b/packages/next-swc/crates/next-core/src/next_server/context.rs
@@ -46,10 +46,7 @@ use crate::{
next_import_map::{get_next_server_import_map, mdx_import_source_file},
next_server::resolve::ExternalPredicate,
next_shared::{
- resolve::{
- ModuleFeatureReportResolvePlugin, NextExternalResolvePlugin,
- UnsupportedModulesResolvePlugin,
- },
+ resolve::{ModuleFeatureReportResolvePlugin, UnsupportedModulesResolvePlugin},
transforms::{
emotion::get_emotion_transform_plugin, get_relay_transform_plugin,
styled_components::get_styled_components_transform_plugin,
@@ -111,9 +108,10 @@ pub async fn get_server_resolve_options_context(
let mut custom_conditions = vec![mode.node_env().to_string(), "node".to_string()];
match ty {
- ServerContextType::AppRSC { .. } => custom_conditions.push("react-server".to_string()),
- ServerContextType::AppRoute { .. }
- | ServerContextType::Pages { .. }
+ ServerContextType::AppRSC { .. } | ServerContextType::AppRoute { .. } => {
+ custom_conditions.push("react-server".to_string())
+ }
+ ServerContextType::Pages { .. }
| ServerContextType::PagesData { .. }
| ServerContextType::AppSSR { .. }
| ServerContextType::Middleware { .. } => {}
@@ -123,15 +121,12 @@ pub async fn get_server_resolve_options_context(
ExternalPredicate::AllExcept(next_config.transpile_packages()).cell(),
);
- let next_external_plugin = NextExternalResolvePlugin::new(project_path);
-
let plugins = match ty {
ServerContextType::Pages { .. } | ServerContextType::PagesData { .. } => {
vec![
Vc::upcast(module_feature_report_resolve_plugin),
Vc::upcast(external_cjs_modules_plugin),
Vc::upcast(unsupported_modules_resolve_plugin),
- Vc::upcast(next_external_plugin),
]
}
ServerContextType::AppSSR { .. }
@@ -142,7 +137,6 @@ pub async fn get_server_resolve_options_context(
Vc::upcast(module_feature_report_resolve_plugin),
Vc::upcast(server_component_externals_plugin),
Vc::upcast(unsupported_modules_resolve_plugin),
- Vc::upcast(next_external_plugin),
]
}
};
diff --git a/packages/next-swc/crates/next-core/src/next_shared/resolve.rs b/packages/next-swc/crates/next-core/src/next_shared/resolve.rs
index ea7f044c12cc8..013f87f9fd5b6 100644
--- a/packages/next-swc/crates/next-core/src/next_shared/resolve.rs
+++ b/packages/next-swc/crates/next-core/src/next_shared/resolve.rs
@@ -13,7 +13,7 @@ use turbopack_binding::{
parse::Request,
pattern::Pattern,
plugin::{ResolvePlugin, ResolvePluginCondition},
- ResolveResult, ResolveResultItem, ResolveResultOption,
+ ResolveResultOption,
},
},
};
@@ -102,55 +102,6 @@ impl ResolvePlugin for UnsupportedModulesResolvePlugin {
}
}
-#[turbo_tasks::value]
-pub(crate) struct NextExternalResolvePlugin {
- root: Vc,
-}
-
-#[turbo_tasks::value_impl]
-impl NextExternalResolvePlugin {
- #[turbo_tasks::function]
- pub fn new(root: Vc) -> Vc {
- NextExternalResolvePlugin { root }.cell()
- }
-}
-
-#[turbo_tasks::value_impl]
-impl ResolvePlugin for NextExternalResolvePlugin {
- #[turbo_tasks::function]
- fn after_resolve_condition(&self) -> Vc {
- ResolvePluginCondition::new(
- self.root.root(),
- Glob::new(
- "**/next/dist/**/*.{external,shared-runtime,runtime.dev,runtime.prod}.js"
- .to_string(),
- ),
- )
- }
-
- #[turbo_tasks::function]
- async fn after_resolve(
- &self,
- fs_path: Vc,
- _context: Vc,
- _request: Vc,
- ) -> Result> {
- let raw_fs_path = &*fs_path.await?;
- let path = raw_fs_path.path.to_string();
- // Find the starting index of 'next/dist' and slice from that point. It should
- // always be found since the glob pattern above is specific enough.
- let starting_index = path.find("next/dist").unwrap();
- // Replace '/esm/' with '/' to match the CJS version of the file.
- let modified_path = &path[starting_index..].replace("/esm/", "/");
- Ok(Vc::cell(Some(
- ResolveResult::primary(ResolveResultItem::OriginalReferenceTypeExternal(
- modified_path.to_string(),
- ))
- .into(),
- )))
- }
-}
-
/// A resolver plugin tracks the usage of certain import paths, emit
/// telemetry events if there is a match.
#[turbo_tasks::value]
diff --git a/packages/next-swc/crates/next-dev-tests/tests/integration/next/api/basic/issues/lint TP1004 fs.readFile(__q____q____q____star__0__-3e4dd8.txt b/packages/next-swc/crates/next-dev-tests/tests/integration/next/api/basic/issues/lint TP1004 fs.readFile(__q____q____q____star__0__-3e4dd8.txt
deleted file mode 100644
index a5ad94c85fb0a..0000000000000
--- a/packages/next-swc/crates/next-dev-tests/tests/integration/next/api/basic/issues/lint TP1004 fs.readFile(__q____q____q____star__0__-3e4dd8.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-warning - [parse] [project]/packages/next/dist/server/web/sandbox/context.js /packages/next/dist/server/web/sandbox/context.js:64:56 lint TP1004 fs.readFile(???*0*) is very dynamic
- 60 | }
- 61 | async function loadWasm(wasm) {
- 62 | const modules = {};
- 63 | await Promise.all(wasm.map(async (binding)=>{
- + v
- 64 + const module1 = await WebAssembly.compile(await _fs.promises.readFile(binding.filePath));
- + ^
- 65 | modules[binding.name] = module1;
- 66 | }));
- 67 | return modules;
- 68 | }
-
- - *0* ???*1*["filePath"]
- ⚠️ unknown object
- - *1* binding
- ⚠️ pattern without value
\ No newline at end of file
diff --git a/packages/next-swc/crates/next-dev-tests/tests/integration/next/api/basic/issues/lint TP1004 fs.readFileSync(__q____q____q____star_-e11df4.txt b/packages/next-swc/crates/next-dev-tests/tests/integration/next/api/basic/issues/lint TP1004 fs.readFileSync(__q____q____q____star_-e11df4.txt
deleted file mode 100644
index c80db085946c2..0000000000000
--- a/packages/next-swc/crates/next-dev-tests/tests/integration/next/api/basic/issues/lint TP1004 fs.readFileSync(__q____q____q____star_-e11df4.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-warning - [parse] [project]/packages/next/dist/server/web/sandbox/context.js /packages/next/dist/server/web/sandbox/context.js:355:28 lint TP1004 fs.readFileSync(???*0*, "utf-8") is very dynamic
- 351 | }
- 352 | const moduleContext = lazyModuleContext;
- 353 | const evaluateInContext = (filepath)=>{
- 354 | if (!moduleContext.paths.has(filepath)) {
- + v
- 355 + const content = (0, _fs.readFileSync)(filepath, "utf-8");
- + ^
- 356 | try {
- 357 | (0, _vm.runInContext)(content, moduleContext.runtime.context, {
- 358 | filename: filepath
- 359 | });
-
- - *0* filepath
- ⚠️ pattern without value
\ No newline at end of file
diff --git a/packages/next-swc/crates/next-dev-tests/tests/integration/next/image/remotepattern/issues/Error during SSR Rendering-8ad1c9.txt b/packages/next-swc/crates/next-dev-tests/tests/integration/next/image/remotepattern/issues/Error during SSR Rendering-8ad1c9.txt
deleted file mode 100644
index 39e97b4ccc85e..0000000000000
--- a/packages/next-swc/crates/next-dev-tests/tests/integration/next/image/remotepattern/issues/Error during SSR Rendering-8ad1c9.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-error - [rendering] [root of the server]/invalid Error during SSR Rendering
- Error: Invalid src prop (https://image-optimization-test.vercel.app/test.webp) on `next/image`, hostname "image-optimization-test.vercel.app" is not configured under images in your `next.config.js`
-
- Debug info:
- - Error: Invalid src prop (https://image-optimization-test.vercel.app/test.webp) on `next/image`, hostname "image-optimization-test.vercel.app" is not configured under images in your `next.config.js`
- See more info: https://nextjs.org/docs/messages/next-image-unconfigured-host
- at defaultLoader (packages/next/dist/shared/lib/image-loader.js:41:27)
- 37 | process.env.NEXT_RUNTIME !== "edge") {
- 38 | // We use dynamic require because this should only error in development
- 39 | const { hasMatch } = require("./match-remote-pattern");
- 40 | if (!hasMatch(config.domains, config.remotePatterns, parsedSrc)) {
- | v
- 41 + throw new Error("Invalid src prop (" + src + ') on `next/image`, hostname "' + parsedSrc.hostname + '" i...xt.config.js`\n' + "See more info: https://nextjs.org/docs/messages/next-image-unconfigured-host");
- | ^
- 42 | }
- 43 | }
- 44 | }
- 45 | }
-
- at (packages/next/dist/shared/lib/get-img-props.js:101:36)
- 97 | const { widths , kind } = getWidths(config, width, sizes);
- 98 | const last = widths.length - 1;
- 99 | return {
- 100 | sizes: !sizes && kind === "w" ? "100vw" : sizes,
- | v
- 101 + srcSet: widths.map((w, i)=>loader({
- | ^
- 102 | config,
- 103 | src,
- 104 | quality,
- 105 | width: w
-
- at generateImgAttrs (packages/next/dist/shared/lib/get-img-props.js:101:24)
- 97 | const { widths , kind } = getWidths(config, width, sizes);
- 98 | const last = widths.length - 1;
- 99 | return {
- 100 | sizes: !sizes && kind === "w" ? "100vw" : sizes,
- | v
- 101 + srcSet: widths.map((w, i)=>loader({
- | ^
- 102 | config,
- 103 | src,
- 104 | quality,
- 105 | width: w
-
- at getImgProps (packages/next/dist/shared/lib/get-img-props.js:392:27)
- at (packages/next/dist/client/image-component.js:275:82)
\ No newline at end of file
diff --git a/packages/next-swc/crates/next-dev-tests/tests/integration/next/image/remotepattern/issues/Error during SSR Rendering-d9114a.txt b/packages/next-swc/crates/next-dev-tests/tests/integration/next/image/remotepattern/issues/Error during SSR Rendering-d9114a.txt
new file mode 100644
index 0000000000000..ce775cb8df7e8
--- /dev/null
+++ b/packages/next-swc/crates/next-dev-tests/tests/integration/next/image/remotepattern/issues/Error during SSR Rendering-d9114a.txt
@@ -0,0 +1,6 @@
+error - [rendering] [root of the server]/invalid Error during SSR Rendering
+ Error: Invalid src prop (https://image-optimization-test.vercel.app/test.webp) on `next/image`, hostname "image-optimization-test.vercel.app" is not configured under images in your `next.config.js`
+
+ Debug info:
+ - Error: Invalid src prop (https://image-optimization-test.vercel.app/test.webp) on `next/image`, hostname "image-optimization-test.vercel.app" is not configured under images in your `next.config.js`
+ See more info: https://nextjs.org/docs/messages/next-image-unconfigured-host
\ No newline at end of file
diff --git a/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/input/app/test.js b/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/input/app/test.js
index 108b763da879c..e2c2f40a06dd7 100644
--- a/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/input/app/test.js
+++ b/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/input/app/test.js
@@ -120,7 +120,7 @@ function runTests() {
expect(json).toMatchObject({
edgeThenNode: 'node',
nodeThenEdge: 'node',
- reactServer: 'default',
+ reactServer: 'react-server',
})
})
@@ -129,7 +129,7 @@ function runTests() {
expect(json).toMatchObject({
edgeThenNode: 'edge',
nodeThenEdge: 'edge',
- reactServer: 'default',
+ reactServer: 'react-server',
})
})
diff --git a/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/issues/Error resolving commonjs request-b2593b.txt b/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/issues/Error resolving commonjs request-b2593b.txt
new file mode 100644
index 0000000000000..72c048d7b6481
--- /dev/null
+++ b/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/issues/Error resolving commonjs request-b2593b.txt
@@ -0,0 +1,13 @@
+error - [resolve] [project]/packages/next/dist/compiled/nanoid/index.cjs /packages/next/dist/compiled/nanoid/index.cjs:1:45 Error resolving commonjs request
+ + v---------------v
+ 1 + (()=>{var e={113:e=>{"use strict";e.exports=require("crypto")},660:(e,r,t)=>{let l=t(113);let{urlAlphabet:a}=t(591);const n=128;let _,u;let fillPool=e=>{if(!_||...ndefined")__nccwpck_require__.ab=__dirname+"/";var t=__nccwpck_require__(660);module.exports=t})();
+ + ^---------------^
+
+ unable to resolve module "crypto"
+
+ | It was not possible to find the requested file.
+ | Parsed request as written in source code: module "crypto"
+ | Path where resolving has started: [project]/packages/next/dist/compiled/nanoid/index.cjs
+ | Type of request: commonjs request
+ | Import map: No import map entry
+ |
\ No newline at end of file
diff --git a/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/issues/Error resolving commonjs request-dd84e7.txt b/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/issues/Error resolving commonjs request-dd84e7.txt
new file mode 100644
index 0000000000000..72c048d7b6481
--- /dev/null
+++ b/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/issues/Error resolving commonjs request-dd84e7.txt
@@ -0,0 +1,13 @@
+error - [resolve] [project]/packages/next/dist/compiled/nanoid/index.cjs /packages/next/dist/compiled/nanoid/index.cjs:1:45 Error resolving commonjs request
+ + v---------------v
+ 1 + (()=>{var e={113:e=>{"use strict";e.exports=require("crypto")},660:(e,r,t)=>{let l=t(113);let{urlAlphabet:a}=t(591);const n=128;let _,u;let fillPool=e=>{if(!_||...ndefined")__nccwpck_require__.ab=__dirname+"/";var t=__nccwpck_require__(660);module.exports=t})();
+ + ^---------------^
+
+ unable to resolve module "crypto"
+
+ | It was not possible to find the requested file.
+ | Parsed request as written in source code: module "crypto"
+ | Path where resolving has started: [project]/packages/next/dist/compiled/nanoid/index.cjs
+ | Type of request: commonjs request
+ | Import map: No import map entry
+ |
\ No newline at end of file
diff --git a/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/issues/lint TP1004 fs.readFile(__q____q____q____star__0__-76c34b.txt b/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/issues/lint TP1004 fs.readFile(__q____q____q____star__0__-76c34b.txt
deleted file mode 100644
index a5ad94c85fb0a..0000000000000
--- a/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/issues/lint TP1004 fs.readFile(__q____q____q____star__0__-76c34b.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-warning - [parse] [project]/packages/next/dist/server/web/sandbox/context.js /packages/next/dist/server/web/sandbox/context.js:64:56 lint TP1004 fs.readFile(???*0*) is very dynamic
- 60 | }
- 61 | async function loadWasm(wasm) {
- 62 | const modules = {};
- 63 | await Promise.all(wasm.map(async (binding)=>{
- + v
- 64 + const module1 = await WebAssembly.compile(await _fs.promises.readFile(binding.filePath));
- + ^
- 65 | modules[binding.name] = module1;
- 66 | }));
- 67 | return modules;
- 68 | }
-
- - *0* ???*1*["filePath"]
- ⚠️ unknown object
- - *1* binding
- ⚠️ pattern without value
\ No newline at end of file
diff --git a/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/issues/lint TP1004 fs.readFileSync(__q____q____q____star_-f7e52c.txt b/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/issues/lint TP1004 fs.readFileSync(__q____q____q____star_-f7e52c.txt
deleted file mode 100644
index c80db085946c2..0000000000000
--- a/packages/next-swc/crates/next-dev-tests/tests/integration/next/import/conditions/issues/lint TP1004 fs.readFileSync(__q____q____q____star_-f7e52c.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-warning - [parse] [project]/packages/next/dist/server/web/sandbox/context.js /packages/next/dist/server/web/sandbox/context.js:355:28 lint TP1004 fs.readFileSync(???*0*, "utf-8") is very dynamic
- 351 | }
- 352 | const moduleContext = lazyModuleContext;
- 353 | const evaluateInContext = (filepath)=>{
- 354 | if (!moduleContext.paths.has(filepath)) {
- + v
- 355 + const content = (0, _fs.readFileSync)(filepath, "utf-8");
- + ^
- 356 | try {
- 357 | (0, _vm.runInContext)(content, moduleContext.runtime.context, {
- 358 | filename: filepath
- 359 | });
-
- - *0* filepath
- ⚠️ pattern without value
\ No newline at end of file
diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json
index 87ac07c84398a..47906ad8c2f6c 100644
--- a/packages/next-swc/package.json
+++ b/packages/next-swc/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/swc",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"private": true,
"scripts": {
"clean": "node ../../scripts/rm.mjs native",
diff --git a/packages/next/config.d.ts b/packages/next/config.d.ts
index 2da1ee3c4029c..78fe148a8dc9b 100644
--- a/packages/next/config.d.ts
+++ b/packages/next/config.d.ts
@@ -1,3 +1,3 @@
-import getConfig from './dist/shared/lib/runtime-config.shared-runtime'
-export * from './dist/shared/lib/runtime-config.shared-runtime'
+import getConfig from './dist/shared/lib/runtime-config'
+export * from './dist/shared/lib/runtime-config'
export default getConfig
diff --git a/packages/next/config.js b/packages/next/config.js
index 6510748638097..2da980d8b0065 100644
--- a/packages/next/config.js
+++ b/packages/next/config.js
@@ -1 +1 @@
-module.exports = require('./dist/shared/lib/runtime-config.shared-runtime')
+module.exports = require('./dist/shared/lib/runtime-config')
diff --git a/packages/next/package.json b/packages/next/package.json
index b80b6eb520902..058280c68b63f 100644
--- a/packages/next/package.json
+++ b/packages/next/package.json
@@ -1,6 +1,6 @@
{
"name": "next",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"description": "The React Framework",
"main": "./dist/server/next.js",
"license": "MIT",
@@ -83,14 +83,13 @@
},
"taskr": {
"requires": [
- "./taskfile-webpack.js",
"./taskfile-ncc.js",
"./taskfile-swc.js",
"./taskfile-watch.js"
]
},
"dependencies": {
- "@next/env": "13.4.20-canary.20",
+ "@next/env": "13.4.20-canary.21",
"@swc/helpers": "0.5.1",
"busboy": "1.6.0",
"caniuse-lite": "^1.0.30001406",
@@ -145,11 +144,11 @@
"@mswjs/interceptors": "0.23.0",
"@napi-rs/cli": "2.16.2",
"@napi-rs/triples": "1.1.0",
- "@next/polyfill-module": "13.4.20-canary.20",
- "@next/polyfill-nomodule": "13.4.20-canary.20",
- "@next/react-dev-overlay": "13.4.20-canary.20",
- "@next/react-refresh-utils": "13.4.20-canary.20",
- "@next/swc": "13.4.20-canary.20",
+ "@next/polyfill-module": "13.4.20-canary.21",
+ "@next/polyfill-nomodule": "13.4.20-canary.21",
+ "@next/react-dev-overlay": "13.4.20-canary.21",
+ "@next/react-refresh-utils": "13.4.20-canary.21",
+ "@next/swc": "13.4.20-canary.21",
"@opentelemetry/api": "1.4.1",
"@playwright/test": "^1.35.1",
"@segment/ajv-human-errors": "2.1.2",
@@ -173,7 +172,7 @@
"@types/fresh": "0.5.0",
"@types/glob": "7.1.1",
"@types/jsonwebtoken": "9.0.0",
- "@types/lodash": "4.14.149",
+ "@types/lodash": "4.14.198",
"@types/lodash.curry": "4.1.6",
"@types/lru-cache": "5.1.0",
"@types/micromatch": "4.0.2",
@@ -254,7 +253,7 @@
"lru-cache": "5.1.1",
"micromatch": "4.0.4",
"mini-css-extract-plugin": "2.4.3",
- "msw": "^1.2.2",
+ "msw": "1.3.0",
"nanoid": "3.1.32",
"native-url": "0.3.4",
"neo-async": "2.6.1",
@@ -300,7 +299,6 @@
"tar": "6.1.15",
"taskr": "1.1.0",
"terser": "5.14.1",
- "terser-webpack-plugin": "5.3.9",
"text-table": "0.2.0",
"timers-browserify": "2.0.12",
"tty-browserify": "0.0.1",
diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts
index b0e0870ca1392..8ad7407b4be45 100644
--- a/packages/next/src/build/index.ts
+++ b/packages/next/src/build/index.ts
@@ -143,13 +143,8 @@ import { createClientRouterFilter } from '../lib/create-client-router-filter'
import { createValidFileMatcher } from '../server/lib/find-page-file'
import { startTypeChecking } from './type-check'
import { generateInterceptionRoutesRewrites } from '../lib/generate-interception-routes-rewrites'
-
import { buildDataRoute } from '../server/lib/router-utils/build-data-route'
-import {
- baseOverrides,
- defaultOverrides,
- experimentalOverrides,
-} from '../server/require-hook'
+import { baseOverrides, experimentalOverrides } from '../server/require-hook'
import { initialize } from '../server/lib/incremental-cache-server'
import { nodeFs } from '../server/lib/node-fs-methods'
@@ -1248,7 +1243,6 @@ export default async function build(
forkOptions: {
env: {
...process.env,
- __NEXT_PRIVATE_RENDER_RUNTIME: type,
__NEXT_INCREMENTAL_CACHE_IPC_PORT: ipcPort + '',
__NEXT_INCREMENTAL_CACHE_IPC_KEY: ipcValidationKey,
__NEXT_PRIVATE_PREBUNDLED_REACT:
@@ -2090,25 +2084,6 @@ export default async function build(
...Object.values(experimentalOverrides).map((override) =>
require.resolve(override)
),
- ...(config.experimental.turbotrace
- ? []
- : Object.keys(defaultOverrides).map((value) =>
- require.resolve(value, {
- paths: [require.resolve('next/dist/server/require-hook')],
- })
- )),
- require.resolve(
- 'next/dist/compiled/next-server/app-page.runtime.prod'
- ),
- require.resolve(
- 'next/dist/compiled/next-server/app-route.runtime.prod'
- ),
- require.resolve(
- 'next/dist/compiled/next-server/pages.runtime.prod'
- ),
- require.resolve(
- 'next/dist/compiled/next-server/pages-api.runtime.prod'
- ),
]
// ensure we trace any dependencies needed for custom
@@ -2134,7 +2109,10 @@ export default async function build(
const minimalServerEntries = [
...sharedEntriesSet,
require.resolve(
- 'next/dist/compiled/next-server/server.runtime.prod'
+ 'next/dist/compiled/minimal-next-server/next-server-cached.js'
+ ),
+ require.resolve(
+ 'next/dist/compiled/minimal-next-server/next-server.js'
),
].filter(Boolean)
diff --git a/packages/next/src/build/templates/app-page.ts b/packages/next/src/build/templates/app-page.ts
index f0d2ab692e2aa..c75509904c3a8 100644
--- a/packages/next/src/build/templates/app-page.ts
+++ b/packages/next/src/build/templates/app-page.ts
@@ -1,7 +1,7 @@
import type { LoaderTree } from '../../server/lib/app-dir-module'
// @ts-ignore this need to be imported from next/dist to be external
-import * as module from 'next/dist/server/future/route-modules/app-page/module.compiled'
+import * as module from 'next/dist/server/future/route-modules/app-page/module'
import { RouteKind } from '../../server/future/route-kind'
const AppPageRouteModule =
diff --git a/packages/next/src/build/templates/app-route.ts b/packages/next/src/build/templates/app-route.ts
index b4b8e5b0fe6cd..50a8b6165a747 100644
--- a/packages/next/src/build/templates/app-route.ts
+++ b/packages/next/src/build/templates/app-route.ts
@@ -1,8 +1,7 @@
import '../../server/node-polyfill-headers'
// @ts-ignore this need to be imported from next/dist to be external
-import * as module from 'next/dist/server/future/route-modules/app-route/module.compiled'
-
+import * as module from 'next/dist/server/future/route-modules/app-route/module'
import type { AppRouteRouteModuleOptions } from '../../server/future/route-modules/app-route/module'
import { RouteKind } from '../../server/future/route-kind'
diff --git a/packages/next/src/build/templates/pages-api.ts b/packages/next/src/build/templates/pages-api.ts
index eaeec836cb61e..a48822f9ed75a 100644
--- a/packages/next/src/build/templates/pages-api.ts
+++ b/packages/next/src/build/templates/pages-api.ts
@@ -1,6 +1,5 @@
// @ts-ignore this need to be imported from next/dist to be external
-import * as module from 'next/dist/server/future/route-modules/pages-api/module.compiled'
-
+import * as module from 'next/dist/server/future/route-modules/pages-api/module'
import { RouteKind } from '../../server/future/route-kind'
import { hoist } from './helpers'
diff --git a/packages/next/src/build/templates/pages.ts b/packages/next/src/build/templates/pages.ts
index b5def5d13c552..3f3527e6650d6 100644
--- a/packages/next/src/build/templates/pages.ts
+++ b/packages/next/src/build/templates/pages.ts
@@ -1,5 +1,5 @@
// @ts-ignore this need to be imported from next/dist to be external
-import * as module from 'next/dist/server/future/route-modules/pages/module.compiled'
+import * as module from 'next/dist/server/future/route-modules/pages/module'
import { RouteKind } from '../../server/future/route-kind'
import { hoist } from './helpers'
diff --git a/packages/next/src/build/utils.ts b/packages/next/src/build/utils.ts
index 423beb27f6dca..867429c2ba901 100644
--- a/packages/next/src/build/utils.ts
+++ b/packages/next/src/build/utils.ts
@@ -14,7 +14,7 @@ import type {
EdgeFunctionDefinition,
MiddlewareManifest,
} from './webpack/plugins/middleware-plugin'
-import type { StaticGenerationAsyncStorage } from '../client/components/static-generation-async-storage.external'
+import type { StaticGenerationAsyncStorage } from '../client/components/static-generation-async-storage'
import '../server/require-hook'
import '../server/node-polyfill-fetch'
@@ -65,9 +65,7 @@ import { nodeFs } from '../server/lib/node-fs-methods'
import * as ciEnvironment from '../telemetry/ci-info'
import { normalizeAppPath } from '../shared/lib/router/utils/app-paths'
import { denormalizeAppPagePath } from '../shared/lib/page-path/denormalize-app-path'
-// import { AppRouteRouteModule } from '../server/future/route-modules/app-route/module'
-const { AppRouteRouteModule } =
- require('../server/future/route-modules/app-route/module.compiled') as typeof import('../server/future/route-modules/app-route/module')
+import { AppRouteRouteModule } from '../server/future/route-modules/app-route/module'
export type ROUTER_TYPE = 'pages' | 'app'
@@ -1391,9 +1389,7 @@ export async function isPageStatic({
const isPageStaticSpan = trace('is-page-static-utils', parentId)
return isPageStaticSpan
.traceAsyncFn(async () => {
- require('../shared/lib/runtime-config.shared-runtime').setConfig(
- runtimeEnvConfig
- )
+ require('../shared/lib/runtime-config').setConfig(runtimeEnvConfig)
setHttpClientAndAgentOptions({
httpAgentOptions,
})
@@ -1677,9 +1673,7 @@ export async function hasCustomGetInitialProps(
runtimeEnvConfig: any,
checkingApp: boolean
): Promise {
- require('../shared/lib/runtime-config.shared-runtime').setConfig(
- runtimeEnvConfig
- )
+ require('../shared/lib/runtime-config').setConfig(runtimeEnvConfig)
const components = await loadComponents({
distDir,
@@ -1702,9 +1696,7 @@ export async function getDefinedNamedExports(
distDir: string,
runtimeEnvConfig: any
): Promise> {
- require('../shared/lib/runtime-config.shared-runtime').setConfig(
- runtimeEnvConfig
- )
+ require('../shared/lib/runtime-config').setConfig(runtimeEnvConfig)
const components = await loadComponents({
distDir,
pathname: page,
diff --git a/packages/next/src/build/webpack-config.ts b/packages/next/src/build/webpack-config.ts
index d1b7487618fe2..f1f053d05eb9b 100644
--- a/packages/next/src/build/webpack-config.ts
+++ b/packages/next/src/build/webpack-config.ts
@@ -103,19 +103,6 @@ const reactPackagesRegex = /^(react|react-dom|react-server-dom-webpack)($|\/)/
const asyncStoragesRegex =
/next[\\/]dist[\\/](esm[\\/])?client[\\/]components[\\/](static-generation-async-storage|action-async-storage|request-async-storage)/
-const pathSeparators = '[/\\\\]'
-const optionalEsmPart = `((${pathSeparators}esm)?${pathSeparators})`
-const sharedRuntimeFileEnd = '(\\.shared-runtime(\\.js)?)$'
-const externalFileEnd = '(\\.external(\\.js)?)$'
-const nextDist = `next${pathSeparators}dist`
-
-const sharedRuntimePattern = new RegExp(
- `${nextDist}${optionalEsmPart}.*${sharedRuntimeFileEnd}`
-)
-const externalPattern = new RegExp(
- `${nextDist}${optionalEsmPart}.*${externalFileEnd}`
-)
-
// exports.
const edgeConditionNames = [
'edge-light',
@@ -1024,7 +1011,7 @@ export default async function getBaseWebpackConfig(
const customRootAliases: { [key: string]: string[] } = {}
if (dev) {
- const nextDistPath = 'next/dist/' + (isEdgeServer ? 'esm/' : '')
+ const nextDist = 'next/dist/' + (isEdgeServer ? 'esm/' : '')
customAppAliases[`${PAGES_DIR_ALIAS}/_app`] = [
...(pagesDir
? pageExtensions.reduce((prev, ext) => {
@@ -1032,7 +1019,7 @@ export default async function getBaseWebpackConfig(
return prev
}, [] as string[])
: []),
- `${nextDistPath}pages/_app.js`,
+ `${nextDist}pages/_app.js`,
]
customAppAliases[`${PAGES_DIR_ALIAS}/_error`] = [
...(pagesDir
@@ -1041,7 +1028,7 @@ export default async function getBaseWebpackConfig(
return prev
}, [] as string[])
: []),
- `${nextDistPath}pages/_error.js`,
+ `${nextDist}pages/_error.js`,
]
customDocumentAliases[`${PAGES_DIR_ALIAS}/_document`] = [
...(pagesDir
@@ -1050,7 +1037,7 @@ export default async function getBaseWebpackConfig(
return prev
}, [] as string[])
: []),
- `${nextDistPath}pages/_document.js`,
+ `${nextDist}pages/_document.js`,
]
}
@@ -1324,7 +1311,6 @@ export default async function getBaseWebpackConfig(
WEBPACK_LAYERS.serverSideRendering,
WEBPACK_LAYERS.appPagesBrowser,
WEBPACK_LAYERS.actionBrowser,
- WEBPACK_LAYERS.appRouteHandler,
].includes(layer!)
if (
@@ -1381,7 +1367,7 @@ export default async function getBaseWebpackConfig(
}
const notExternalModules =
- /^(?:private-next-pages\/|next\/(?:dist\/pages\/|(?:app|document|link|image|legacy\/image|constants|dynamic|script|navigation|headers|router)$)|string-hash|private-next-rsc-action-validate|private-next-rsc-action-client-wrapper|private-next-rsc-action-proxy$)/
+ /^(?:private-next-pages\/|next\/(?:dist\/pages\/|(?:app|document|link|image|legacy\/image|constants|dynamic|script|navigation|headers)$)|string-hash|private-next-rsc-action-validate|private-next-rsc-action-client-wrapper|private-next-rsc-action-proxy$)/
if (notExternalModules.test(request)) {
return
}
@@ -1404,59 +1390,41 @@ export default async function getBaseWebpackConfig(
// Also disable esm request when appDir is enabled
const isEsmRequested = dependencyType === 'esm'
- /**
- * @param localRes the full path to the file
- * @returns the externalized path
- * @description returns an externalized path if the file is a Next.js file and ends with either `.shared-runtime.js` or `.external.js`
- * This is used to ensure that files used across the rendering runtime(s) and the user code are one and the same. The logic in this function
- * will rewrite the require to the correct bundle location depending on the layer at which the file is being used.
- */
const isLocalCallback = (localRes: string) => {
- const isSharedRuntime = sharedRuntimePattern.test(localRes)
- const isExternal = externalPattern.test(localRes)
-
- // if the file ends with .external, we need to make it a commonjs require in all cases
- // this is used mainly to share the async local storage across the routing, rendering and user layers.
- if (isExternal) {
- // it's important we return the path that starts with `next/dist/` here instead of the absolute path
- // otherwise NFT will get tripped up
- return `commonjs ${localRes.replace(/.*?next[/\\]dist/, 'next/dist')}`
- }
- // if the file ends with .shared-runtime, we need to make it point to the correct bundle depending on the layer
- // this is because each shared-runtime files are unique per bundle, so if you use app-router context in pages,
- // it'll be a different instance than the one used in the app-router runtime.
- if (isSharedRuntime) {
- if (dev) {
- return `commonjs ${localRes}`
- }
+ // Makes sure dist/shared and dist/server are not bundled
+ // we need to process shared `router/router`, `head` and `dynamic`,
+ // so that the DefinePlugin can inject process.env values.
- const name = path.parse(localRes).name.replace('.shared-runtime', '')
+ // Treat next internals as non-external for server layer
+ if (isWebpackServerLayer(layer)) {
+ return
+ }
- const camelCaseName = name.replace(/-([a-z])/g, (_, w) =>
- w.toUpperCase()
+ const isNextExternal =
+ /next[/\\]dist[/\\](esm[\\/])?(shared|server)[/\\](?!lib[/\\](router[/\\]router|dynamic|app-dynamic|image-external|lazy-dynamic|head[^-]))/.test(
+ localRes
+ ) ||
+ // There's no need to bundle the dev overlay
+ (process.env.NODE_ENV === 'development' &&
+ /next[/\\]dist[/\\](esm[/\\])?client[/\\]components[/\\]react-dev-overlay[/\\]/.test(
+ localRes
+ ))
+
+ if (isNextExternal) {
+ // Generate Next.js external import
+ const externalRequest = path.posix.join(
+ 'next',
+ 'dist',
+ path
+ .relative(
+ // Root of Next.js package:
+ path.join(__dirname, '..'),
+ localRes
+ )
+ // Windows path normalization
+ .replace(/\\/g, '/')
)
-
- // there's no externals for API routes but if need be, they'll need to be added here and have
- // their own layer
- const runtime =
- layer === 'app-route-handler'
- ? 'app-route'
- : isAppLayer
- ? 'app-page'
- : 'pages'
- return [
- 'commonjs ' +
- path.posix.join(
- 'next',
- 'dist',
- 'compiled',
- 'next-server',
- `${runtime}.runtime.${dev ? 'dev' : 'prod'}`
- ),
- 'default',
- 'sharedModules',
- camelCaseName,
- ]
+ return `commonjs ${externalRequest}`
}
}
@@ -1477,10 +1445,6 @@ export default async function getBaseWebpackConfig(
return
}
- if (/^next\/dist\/compiled\/next-server/.test(request)) {
- return `commonjs ${request}`
- }
-
if (
/^next\/dist\/shared\/(?!lib\/router\/router)/.test(request) ||
/^next\/dist\/compiled\/.*\.c?js$/.test(request)
@@ -2067,14 +2031,6 @@ export default async function getBaseWebpackConfig(
},
...(hasAppDir
? [
- {
- layer: WEBPACK_LAYERS.appRouteHandler,
- test: new RegExp(
- `private-next-app-dir\\/.*\\/route\\.(${pageExtensions.join(
- '|'
- )})$`
- ),
- },
{
// Make sure that AsyncLocalStorage module instance is shared between server and client
// layers.
@@ -2283,7 +2239,7 @@ export default async function getBaseWebpackConfig(
WEBPACK_LAYERS.appPagesBrowser,
],
},
- exclude: [codeCondition.exclude],
+ exclude: [asyncStoragesRegex, codeCondition.exclude],
use: [
...(dev && isClient
? [
diff --git a/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts b/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts
index c2b1089df5b3f..2be12daecdbc6 100644
--- a/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts
+++ b/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts
@@ -442,7 +442,7 @@ declare module 'next/link' {
declare module 'next/navigation' {
export * from 'next/dist/client/components/navigation.js'
- import type { NavigateOptions, AppRouterInstance as OriginalAppRouterInstance } from 'next/dist/shared/lib/app-router-context.shared-runtime.js'
+ import type { NavigateOptions, AppRouterInstance as OriginalAppRouterInstance } from 'next/dist/shared/lib/app-router-context.js'
interface AppRouterInstance extends OriginalAppRouterInstance {
/**
* Navigate to the provided href.
@@ -575,11 +575,8 @@ export class NextTypesPlugin {
}
return
}
- if (
- mod.layer !== WEBPACK_LAYERS.reactServerComponents &&
- mod.layer !== WEBPACK_LAYERS.appRouteHandler
- )
- return
+
+ if (mod.layer !== WEBPACK_LAYERS.reactServerComponents) return
const IS_LAYOUT = /[/\\]layout\.[^./\\]+$/.test(mod.resource)
const IS_PAGE = !IS_LAYOUT && /[/\\]page\.[^.]+$/.test(mod.resource)
diff --git a/packages/next/src/client/app-index.tsx b/packages/next/src/client/app-index.tsx
index 47c0bd13f369e..8f82d244837e6 100644
--- a/packages/next/src/client/app-index.tsx
+++ b/packages/next/src/client/app-index.tsx
@@ -7,8 +7,8 @@ import React, { use } from 'react'
// eslint-disable-next-line import/no-extraneous-dependencies
import { createFromReadableStream } from 'react-server-dom-webpack/client'
-import { HeadManagerContext } from '../shared/lib/head-manager-context.shared-runtime'
-import { GlobalLayoutRouterContext } from '../shared/lib/app-router-context.shared-runtime'
+import { HeadManagerContext } from '../shared/lib/head-manager-context'
+import { GlobalLayoutRouterContext } from '../shared/lib/app-router-context'
import onRecoverableError from './on-recoverable-error'
import { callServer } from './app-call-server'
import { isNextRouterError } from './components/is-next-router-error'
diff --git a/packages/next/src/client/compat/router.ts b/packages/next/src/client/compat/router.ts
index e9143c4117bd7..58b1b9f02ed05 100644
--- a/packages/next/src/client/compat/router.ts
+++ b/packages/next/src/client/compat/router.ts
@@ -1,5 +1,5 @@
import { useContext } from 'react'
-import { RouterContext } from '../../shared/lib/router-context.shared-runtime'
+import { RouterContext } from '../../shared/lib/router-context'
import { NextRouter } from '../router'
/**
diff --git a/packages/next/src/client/components/action-async-storage.external.ts b/packages/next/src/client/components/action-async-storage.ts
similarity index 100%
rename from packages/next/src/client/components/action-async-storage.external.ts
rename to packages/next/src/client/components/action-async-storage.ts
diff --git a/packages/next/src/client/components/app-router.tsx b/packages/next/src/client/components/app-router.tsx
index 2c3c541e02b8e..db181118a674a 100644
--- a/packages/next/src/client/components/app-router.tsx
+++ b/packages/next/src/client/components/app-router.tsx
@@ -14,11 +14,11 @@ import {
LayoutRouterContext,
GlobalLayoutRouterContext,
CacheStates,
-} from '../../shared/lib/app-router-context.shared-runtime'
+} from '../../shared/lib/app-router-context'
import type {
CacheNode,
AppRouterInstance,
-} from '../../shared/lib/app-router-context.shared-runtime'
+} from '../../shared/lib/app-router-context'
import type {
FlightRouterState,
FlightData,
@@ -33,18 +33,18 @@ import {
ACTION_RESTORE,
ACTION_SERVER_ACTION,
ACTION_SERVER_PATCH,
+ Mutable,
PrefetchKind,
ReducerActions,
RouterChangeByServerResponse,
RouterNavigate,
ServerActionDispatcher,
- ServerActionMutable,
} from './router-reducer/router-reducer-types'
import { createHrefFromUrl } from './router-reducer/create-href-from-url'
import {
SearchParamsContext,
PathnameContext,
-} from '../../shared/lib/hooks-client-context.shared-runtime'
+} from '../../shared/lib/hooks-client-context'
import { useReducerWithReduxDevtools } from './use-reducer-with-devtools'
import { ErrorBoundary } from './error-boundary'
import {
@@ -73,7 +73,7 @@ export function getServerActionDispatcher() {
return globalServerActionDispatcher
}
-let globalServerActionMutable: ServerActionMutable['globalMutable'] = {
+let globalMutable: Mutable['globalMutable'] = {
refresh: () => {}, // noop until the router is initialized
}
@@ -145,7 +145,7 @@ function useServerActionDispatcher(dispatch: React.Dispatch) {
dispatch({
...actionPayload,
type: ACTION_SERVER_ACTION,
- mutable: { globalMutable: globalServerActionMutable },
+ mutable: { globalMutable },
cache: createEmptyCacheNode(),
})
})
@@ -174,7 +174,7 @@ function useChangeByServerResponse(
previousTree,
overrideCanonicalUrl,
cache: createEmptyCacheNode(),
- mutable: {},
+ mutable: { globalMutable },
})
})
},
@@ -186,7 +186,7 @@ function useNavigate(dispatch: React.Dispatch): RouterNavigate {
return useCallback(
(href, navigateType, forceOptimisticNavigation, shouldScroll) => {
const url = new URL(addBasePath(href), location.href)
- globalServerActionMutable.pendingNavigatePath = href
+ globalMutable.pendingNavigatePath = href
return dispatch({
type: ACTION_NAVIGATE,
@@ -197,7 +197,7 @@ function useNavigate(dispatch: React.Dispatch): RouterNavigate {
shouldScroll: shouldScroll ?? true,
navigateType,
cache: createEmptyCacheNode(),
- mutable: {},
+ mutable: { globalMutable },
})
},
[dispatch]
@@ -322,7 +322,7 @@ function Router({
dispatch({
type: ACTION_REFRESH,
cache: createEmptyCacheNode(),
- mutable: {},
+ mutable: { globalMutable },
origin: window.location.origin,
})
})
@@ -338,7 +338,7 @@ function Router({
dispatch({
type: ACTION_FAST_REFRESH,
cache: createEmptyCacheNode(),
- mutable: {},
+ mutable: { globalMutable },
origin: window.location.origin,
})
})
@@ -357,7 +357,7 @@ function Router({
}, [appRouter])
useEffect(() => {
- globalServerActionMutable.refresh = appRouter.refresh
+ globalMutable.refresh = appRouter.refresh
}, [appRouter.refresh])
if (process.env.NODE_ENV !== 'production') {
@@ -409,11 +409,16 @@ function Router({
// in . At least I hope so. (It will run twice in dev strict mode,
// but that's... fine?)
if (pushRef.mpaNavigation) {
- const location = window.location
- if (pushRef.pendingPush) {
- location.assign(canonicalUrl)
- } else {
- location.replace(canonicalUrl)
+ // if there's a re-render, we don't want to trigger another redirect if one is already in flight to the same URL
+ if (globalMutable.pendingMpaPath !== canonicalUrl) {
+ const location = window.location
+ if (pushRef.pendingPush) {
+ location.assign(canonicalUrl)
+ } else {
+ location.replace(canonicalUrl)
+ }
+
+ globalMutable.pendingMpaPath = canonicalUrl
}
// TODO-APP: Should we listen to navigateerror here to catch failed
// navigations somehow? And should we call window.stop() if a SPA navigation
diff --git a/packages/next/src/client/components/bailout-to-client-rendering.ts b/packages/next/src/client/components/bailout-to-client-rendering.ts
index 799398b5f300c..76356e05304a8 100644
--- a/packages/next/src/client/components/bailout-to-client-rendering.ts
+++ b/packages/next/src/client/components/bailout-to-client-rendering.ts
@@ -1,5 +1,5 @@
import { suspense } from '../../shared/lib/lazy-dynamic/dynamic-no-ssr'
-import { staticGenerationAsyncStorage } from './static-generation-async-storage.external'
+import { staticGenerationAsyncStorage } from './static-generation-async-storage'
export function bailoutToClientRendering(): boolean | never {
const staticGenerationStore = staticGenerationAsyncStorage.getStore()
diff --git a/packages/next/src/client/components/headers.ts b/packages/next/src/client/components/headers.ts
index a0a27a184cbfe..d090264391e7c 100644
--- a/packages/next/src/client/components/headers.ts
+++ b/packages/next/src/client/components/headers.ts
@@ -4,8 +4,8 @@ import {
} from '../../server/web/spec-extension/adapters/request-cookies'
import { HeadersAdapter } from '../../server/web/spec-extension/adapters/headers'
import { RequestCookies } from '../../server/web/spec-extension/cookies'
-import { requestAsyncStorage } from './request-async-storage.external'
-import { actionAsyncStorage } from './action-async-storage.external'
+import { requestAsyncStorage } from './request-async-storage'
+import { actionAsyncStorage } from './action-async-storage'
import { staticGenerationBailout } from './static-generation-bailout'
import { DraftMode } from './draft-mode'
@@ -17,6 +17,7 @@ export function headers() {
) {
return HeadersAdapter.seal(new Headers({}))
}
+
const requestStore = requestAsyncStorage.getStore()
if (!requestStore) {
throw new Error(
diff --git a/packages/next/src/client/components/layout-router.tsx b/packages/next/src/client/components/layout-router.tsx
index 1f0ffff7e2de8..3e410a93fb0ca 100644
--- a/packages/next/src/client/components/layout-router.tsx
+++ b/packages/next/src/client/components/layout-router.tsx
@@ -1,6 +1,6 @@
'use client'
-import type { ChildSegmentMap } from '../../shared/lib/app-router-context.shared-runtime'
+import type { ChildSegmentMap } from '../../shared/lib/app-router-context'
import type {
FlightRouterState,
FlightSegmentPath,
@@ -17,7 +17,7 @@ import {
LayoutRouterContext,
GlobalLayoutRouterContext,
TemplateContext,
-} from '../../shared/lib/app-router-context.shared-runtime'
+} from '../../shared/lib/app-router-context'
import { fetchServerResponse } from './router-reducer/fetch-server-response'
import { createInfinitePromise } from './infinite-promise'
import { ErrorBoundary } from './error-boundary'
diff --git a/packages/next/src/client/components/navigation.ts b/packages/next/src/client/components/navigation.ts
index b3d69dcb065e8..bf6a56100080d 100644
--- a/packages/next/src/client/components/navigation.ts
+++ b/packages/next/src/client/components/navigation.ts
@@ -4,11 +4,11 @@ import {
AppRouterContext,
GlobalLayoutRouterContext,
LayoutRouterContext,
-} from '../../shared/lib/app-router-context.shared-runtime'
+} from '../../shared/lib/app-router-context'
import {
SearchParamsContext,
PathnameContext,
-} from '../../shared/lib/hooks-client-context.shared-runtime'
+} from '../../shared/lib/hooks-client-context'
import { clientHookInServerComponentError } from './client-hook-in-server-component-error'
import { getSegmentValue } from './router-reducer/reducers/get-segment-value'
@@ -111,12 +111,12 @@ export function usePathname(): string {
export {
ServerInsertedHTMLContext,
useServerInsertedHTML,
-} from '../../shared/lib/server-inserted-html.shared-runtime'
+} from '../../shared/lib/server-inserted-html'
/**
* Get the router methods. For example router.push('/dashboard')
*/
-export function useRouter(): import('../../shared/lib/app-router-context.shared-runtime').AppRouterInstance {
+export function useRouter(): import('../../shared/lib/app-router-context').AppRouterInstance {
clientHookInServerComponentError('useRouter')
const router = useContext(AppRouterContext)
if (router === null) {
diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-websocket.ts b/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-websocket.ts
index d37fce9851e91..4d92a279c3ed5 100644
--- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-websocket.ts
+++ b/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-websocket.ts
@@ -1,5 +1,5 @@
import { useCallback, useContext, useEffect, useRef } from 'react'
-import { GlobalLayoutRouterContext } from '../../../../../shared/lib/app-router-context.shared-runtime'
+import { GlobalLayoutRouterContext } from '../../../../../shared/lib/app-router-context'
import { getSocketUrl } from './get-socket-url'
export function useWebsocket(assetPrefix: string) {
diff --git a/packages/next/src/client/components/redirect-boundary.tsx b/packages/next/src/client/components/redirect-boundary.tsx
index 8d407fd6e9d6e..23e5493ae83fb 100644
--- a/packages/next/src/client/components/redirect-boundary.tsx
+++ b/packages/next/src/client/components/redirect-boundary.tsx
@@ -1,6 +1,6 @@
'use client'
import React, { useEffect } from 'react'
-import { AppRouterInstance } from '../../shared/lib/app-router-context.shared-runtime'
+import { AppRouterInstance } from '../../shared/lib/app-router-context'
import { useRouter } from './navigation'
import {
RedirectType,
diff --git a/packages/next/src/client/components/redirect.ts b/packages/next/src/client/components/redirect.ts
index b9a2cfebd883f..10e72bc1ccbef 100644
--- a/packages/next/src/client/components/redirect.ts
+++ b/packages/next/src/client/components/redirect.ts
@@ -1,4 +1,4 @@
-import { requestAsyncStorage } from './request-async-storage.external'
+import { requestAsyncStorage } from './request-async-storage'
import type { ResponseCookies } from '../../server/web/spec-extension/cookies'
const REDIRECT_ERROR_CODE = 'NEXT_REDIRECT'
diff --git a/packages/next/src/client/components/render-from-template-context.tsx b/packages/next/src/client/components/render-from-template-context.tsx
index c1755cc5056bf..be486842c4f33 100644
--- a/packages/next/src/client/components/render-from-template-context.tsx
+++ b/packages/next/src/client/components/render-from-template-context.tsx
@@ -1,7 +1,7 @@
'use client'
import React, { useContext } from 'react'
-import { TemplateContext } from '../../shared/lib/app-router-context.shared-runtime'
+import { TemplateContext } from '../../shared/lib/app-router-context'
export default function RenderFromTemplateContext(): JSX.Element {
const children = useContext(TemplateContext)
diff --git a/packages/next/src/client/components/request-async-storage.external.ts b/packages/next/src/client/components/request-async-storage.ts
similarity index 100%
rename from packages/next/src/client/components/request-async-storage.external.ts
rename to packages/next/src/client/components/request-async-storage.ts
diff --git a/packages/next/src/client/components/router-reducer/apply-flight-data.ts b/packages/next/src/client/components/router-reducer/apply-flight-data.ts
index 003d0a5cde9e4..e7a2f11a84f48 100644
--- a/packages/next/src/client/components/router-reducer/apply-flight-data.ts
+++ b/packages/next/src/client/components/router-reducer/apply-flight-data.ts
@@ -1,7 +1,4 @@
-import {
- CacheNode,
- CacheStates,
-} from '../../../shared/lib/app-router-context.shared-runtime'
+import { CacheNode, CacheStates } from '../../../shared/lib/app-router-context'
import { FlightDataPath } from '../../../server/app-render/types'
import { fillLazyItemsTillLeafWithHead } from './fill-lazy-items-till-leaf-with-head'
import { fillCacheWithNewSubTreeData } from './fill-cache-with-new-subtree-data'
diff --git a/packages/next/src/client/components/router-reducer/create-initial-router-state.test.tsx b/packages/next/src/client/components/router-reducer/create-initial-router-state.test.tsx
index 414b553c63249..a6052636ef256 100644
--- a/packages/next/src/client/components/router-reducer/create-initial-router-state.test.tsx
+++ b/packages/next/src/client/components/router-reducer/create-initial-router-state.test.tsx
@@ -1,9 +1,6 @@
import React from 'react'
import type { FlightRouterState } from '../../../server/app-render/types'
-import {
- CacheNode,
- CacheStates,
-} from '../../../shared/lib/app-router-context.shared-runtime'
+import { CacheNode, CacheStates } from '../../../shared/lib/app-router-context'
import { createInitialRouterState } from './create-initial-router-state'
const buildId = 'development'
diff --git a/packages/next/src/client/components/router-reducer/create-initial-router-state.ts b/packages/next/src/client/components/router-reducer/create-initial-router-state.ts
index 94fdabb9b577a..7f7cca2003b0b 100644
--- a/packages/next/src/client/components/router-reducer/create-initial-router-state.ts
+++ b/packages/next/src/client/components/router-reducer/create-initial-router-state.ts
@@ -1,8 +1,8 @@
import type { ReactNode } from 'react'
-import type { CacheNode } from '../../../shared/lib/app-router-context.shared-runtime'
+import type { CacheNode } from '../../../shared/lib/app-router-context'
import type { FlightRouterState } from '../../../server/app-render/types'
-import { CacheStates } from '../../../shared/lib/app-router-context.shared-runtime'
+import { CacheStates } from '../../../shared/lib/app-router-context'
import { createHrefFromUrl } from './create-href-from-url'
import { fillLazyItemsTillLeafWithHead } from './fill-lazy-items-till-leaf-with-head'
import { extractPathFromFlightRouterState } from './compute-changed-path'
diff --git a/packages/next/src/client/components/router-reducer/fill-cache-with-data-property.test.tsx b/packages/next/src/client/components/router-reducer/fill-cache-with-data-property.test.tsx
index 648069ea76986..28f8c3412ab3a 100644
--- a/packages/next/src/client/components/router-reducer/fill-cache-with-data-property.test.tsx
+++ b/packages/next/src/client/components/router-reducer/fill-cache-with-data-property.test.tsx
@@ -1,10 +1,7 @@
import React from 'react'
import { fetchServerResponse } from './fetch-server-response'
import { fillCacheWithDataProperty } from './fill-cache-with-data-property'
-import {
- CacheStates,
- CacheNode,
-} from '../../../shared/lib/app-router-context.shared-runtime'
+import { CacheStates, CacheNode } from '../../../shared/lib/app-router-context'
describe('fillCacheWithDataProperty', () => {
it('should add data property', () => {
const fetchServerResponseMock: jest.Mock<
diff --git a/packages/next/src/client/components/router-reducer/fill-cache-with-data-property.ts b/packages/next/src/client/components/router-reducer/fill-cache-with-data-property.ts
index 42df61a952af5..81df295dba302 100644
--- a/packages/next/src/client/components/router-reducer/fill-cache-with-data-property.ts
+++ b/packages/next/src/client/components/router-reducer/fill-cache-with-data-property.ts
@@ -1,8 +1,5 @@
import { FlightSegmentPath } from '../../../server/app-render/types'
-import {
- CacheNode,
- CacheStates,
-} from '../../../shared/lib/app-router-context.shared-runtime'
+import { CacheNode, CacheStates } from '../../../shared/lib/app-router-context'
import { createRouterCacheKey } from './create-router-cache-key'
import { fetchServerResponse } from './fetch-server-response'
diff --git a/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.test.tsx b/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.test.tsx
index ac888a3ede0ff..187f86a478751 100644
--- a/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.test.tsx
+++ b/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.test.tsx
@@ -1,9 +1,6 @@
import React from 'react'
import { fillCacheWithNewSubTreeData } from './fill-cache-with-new-subtree-data'
-import {
- CacheStates,
- CacheNode,
-} from '../../../shared/lib/app-router-context.shared-runtime'
+import { CacheStates, CacheNode } from '../../../shared/lib/app-router-context'
import type { FlightData } from '../../../server/app-render/types'
const getFlightData = (): FlightData => {
diff --git a/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.ts b/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.ts
index 7e9a93699fb65..5d48eaee9ef9f 100644
--- a/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.ts
+++ b/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.ts
@@ -1,7 +1,4 @@
-import {
- CacheNode,
- CacheStates,
-} from '../../../shared/lib/app-router-context.shared-runtime'
+import { CacheNode, CacheStates } from '../../../shared/lib/app-router-context'
import type { FlightDataPath } from '../../../server/app-render/types'
import { invalidateCacheByRouterState } from './invalidate-cache-by-router-state'
import { fillLazyItemsTillLeafWithHead } from './fill-lazy-items-till-leaf-with-head'
diff --git a/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.test.tsx b/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.test.tsx
index 1edbeffd7b3e9..606440a96f9c9 100644
--- a/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.test.tsx
+++ b/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.test.tsx
@@ -1,9 +1,6 @@
import React from 'react'
import { fillLazyItemsTillLeafWithHead } from './fill-lazy-items-till-leaf-with-head'
-import {
- CacheStates,
- CacheNode,
-} from '../../../shared/lib/app-router-context.shared-runtime'
+import { CacheStates, CacheNode } from '../../../shared/lib/app-router-context'
import type { FlightData } from '../../../server/app-render/types'
const getFlightData = (): FlightData => {
diff --git a/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.ts b/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.ts
index f558edfab2f1e..c5ddedd52351e 100644
--- a/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.ts
+++ b/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.ts
@@ -1,7 +1,4 @@
-import {
- CacheNode,
- CacheStates,
-} from '../../../shared/lib/app-router-context.shared-runtime'
+import { CacheNode, CacheStates } from '../../../shared/lib/app-router-context'
import type { FlightRouterState } from '../../../server/app-render/types'
import { createRouterCacheKey } from './create-router-cache-key'
diff --git a/packages/next/src/client/components/router-reducer/invalidate-cache-below-flight-segmentpath.test.tsx b/packages/next/src/client/components/router-reducer/invalidate-cache-below-flight-segmentpath.test.tsx
index 8c23c47d42d74..915f09cae0cae 100644
--- a/packages/next/src/client/components/router-reducer/invalidate-cache-below-flight-segmentpath.test.tsx
+++ b/packages/next/src/client/components/router-reducer/invalidate-cache-below-flight-segmentpath.test.tsx
@@ -1,10 +1,7 @@
import React from 'react'
import type { FlightData } from '../../../server/app-render/types'
import { invalidateCacheBelowFlightSegmentPath } from './invalidate-cache-below-flight-segmentpath'
-import {
- CacheStates,
- CacheNode,
-} from '../../../shared/lib/app-router-context.shared-runtime'
+import { CacheStates, CacheNode } from '../../../shared/lib/app-router-context'
import { fillCacheWithNewSubTreeData } from './fill-cache-with-new-subtree-data'
const getFlightData = (): FlightData => {
diff --git a/packages/next/src/client/components/router-reducer/invalidate-cache-below-flight-segmentpath.ts b/packages/next/src/client/components/router-reducer/invalidate-cache-below-flight-segmentpath.ts
index d637d850b145a..ac343f8d79679 100644
--- a/packages/next/src/client/components/router-reducer/invalidate-cache-below-flight-segmentpath.ts
+++ b/packages/next/src/client/components/router-reducer/invalidate-cache-below-flight-segmentpath.ts
@@ -1,4 +1,4 @@
-import type { CacheNode } from '../../../shared/lib/app-router-context.shared-runtime'
+import type { CacheNode } from '../../../shared/lib/app-router-context'
import type { FlightSegmentPath } from '../../../server/app-render/types'
import { createRouterCacheKey } from './create-router-cache-key'
diff --git a/packages/next/src/client/components/router-reducer/invalidate-cache-by-router-state.test.tsx b/packages/next/src/client/components/router-reducer/invalidate-cache-by-router-state.test.tsx
index bdd819b0614d9..65ce9e42c05ee 100644
--- a/packages/next/src/client/components/router-reducer/invalidate-cache-by-router-state.test.tsx
+++ b/packages/next/src/client/components/router-reducer/invalidate-cache-by-router-state.test.tsx
@@ -1,9 +1,6 @@
import React from 'react'
import { invalidateCacheByRouterState } from './invalidate-cache-by-router-state'
-import {
- CacheStates,
- CacheNode,
-} from '../../../shared/lib/app-router-context.shared-runtime'
+import { CacheStates, CacheNode } from '../../../shared/lib/app-router-context'
import type { FlightRouterState } from '../../../server/app-render/types'
describe('invalidateCacheByRouterState', () => {
diff --git a/packages/next/src/client/components/router-reducer/invalidate-cache-by-router-state.ts b/packages/next/src/client/components/router-reducer/invalidate-cache-by-router-state.ts
index 1ec39ae9e35fd..820e5909bf031 100644
--- a/packages/next/src/client/components/router-reducer/invalidate-cache-by-router-state.ts
+++ b/packages/next/src/client/components/router-reducer/invalidate-cache-by-router-state.ts
@@ -1,4 +1,4 @@
-import type { CacheNode } from '../../../shared/lib/app-router-context.shared-runtime'
+import type { CacheNode } from '../../../shared/lib/app-router-context'
import type { FlightRouterState } from '../../../server/app-render/types'
import { createRouterCacheKey } from './create-router-cache-key'
diff --git a/packages/next/src/client/components/router-reducer/reducers/find-head-in-cache.test.tsx b/packages/next/src/client/components/router-reducer/reducers/find-head-in-cache.test.tsx
index 2d4cdef348b1e..807374c855577 100644
--- a/packages/next/src/client/components/router-reducer/reducers/find-head-in-cache.test.tsx
+++ b/packages/next/src/client/components/router-reducer/reducers/find-head-in-cache.test.tsx
@@ -3,7 +3,7 @@ import type { FlightRouterState } from '../../../../server/app-render/types'
import {
CacheNode,
CacheStates,
-} from '../../../../shared/lib/app-router-context.shared-runtime'
+} from '../../../../shared/lib/app-router-context'
import { findHeadInCache } from './find-head-in-cache'
describe('findHeadInCache', () => {
diff --git a/packages/next/src/client/components/router-reducer/reducers/find-head-in-cache.ts b/packages/next/src/client/components/router-reducer/reducers/find-head-in-cache.ts
index 08dcefc65f2ce..f4d5e768b9808 100644
--- a/packages/next/src/client/components/router-reducer/reducers/find-head-in-cache.ts
+++ b/packages/next/src/client/components/router-reducer/reducers/find-head-in-cache.ts
@@ -1,5 +1,5 @@
import type { FlightRouterState } from '../../../../server/app-render/types'
-import type { CacheNode } from '../../../../shared/lib/app-router-context.shared-runtime'
+import type { CacheNode } from '../../../../shared/lib/app-router-context'
import { createRouterCacheKey } from '../create-router-cache-key'
export function findHeadInCache(
diff --git a/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.test.tsx b/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.test.tsx
index 4ed01fed08c83..db40adfa3c5b1 100644
--- a/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.test.tsx
+++ b/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.test.tsx
@@ -79,7 +79,7 @@ import { FlightRouterState } from '../../../../server/app-render/types'
import {
CacheNode,
CacheStates,
-} from '../../../../shared/lib/app-router-context.shared-runtime'
+} from '../../../../shared/lib/app-router-context'
import { createInitialRouterState } from '../create-initial-router-state'
import {
NavigateAction,
@@ -106,6 +106,10 @@ const getInitialRouterStateTree = (): FlightRouterState => [
true,
]
+const globalMutable = {
+ refresh: () => {},
+}
+
async function runPromiseThrowChain(fn: any): Promise {
try {
return await fn()
@@ -194,7 +198,7 @@ describe('navigateReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
}
const newState = await runPromiseThrowChain(() =>
@@ -438,7 +442,7 @@ describe('navigateReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
}
await runPromiseThrowChain(() => navigateReducer(state, action))
@@ -633,7 +637,7 @@ describe('navigateReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
}
await runPromiseThrowChain(() => navigateReducer(state, action))
@@ -792,7 +796,7 @@ describe('navigateReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
}
await runPromiseThrowChain(() => navigateReducer(state, action))
@@ -948,7 +952,7 @@ describe('navigateReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
}
await runPromiseThrowChain(() => navigateReducer(state, action))
@@ -1147,7 +1151,7 @@ describe('navigateReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
}
await runPromiseThrowChain(() => navigateReducer(state, action))
@@ -1317,7 +1321,7 @@ describe('navigateReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
}
await runPromiseThrowChain(() => navigateReducer(state, action))
@@ -1630,7 +1634,7 @@ describe('navigateReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
}
await runPromiseThrowChain(() => navigateReducer(state, action))
@@ -1841,6 +1845,7 @@ describe('navigateReducer', () => {
hashFragment: '#hash',
pendingPush: true,
shouldScroll: true,
+ globalMutable,
},
}
@@ -1983,7 +1988,7 @@ describe('navigateReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
}
const newState = await runPromiseThrowChain(() =>
diff --git a/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.ts b/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.ts
index e47c42b2aa60a..fe8a4a24c4b8b 100644
--- a/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.ts
+++ b/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.ts
@@ -1,7 +1,7 @@
import {
CacheNode,
CacheStates,
-} from '../../../../shared/lib/app-router-context.shared-runtime'
+} from '../../../../shared/lib/app-router-context'
import type {
FlightRouterState,
FlightSegmentPath,
diff --git a/packages/next/src/client/components/router-reducer/reducers/prefetch-reducer.test.tsx b/packages/next/src/client/components/router-reducer/reducers/prefetch-reducer.test.tsx
index bbbee6ff5f2a4..8055123367a94 100644
--- a/packages/next/src/client/components/router-reducer/reducers/prefetch-reducer.test.tsx
+++ b/packages/next/src/client/components/router-reducer/reducers/prefetch-reducer.test.tsx
@@ -36,7 +36,7 @@ import { FlightRouterState } from '../../../../server/app-render/types'
import {
CacheNode,
CacheStates,
-} from '../../../../shared/lib/app-router-context.shared-runtime'
+} from '../../../../shared/lib/app-router-context'
import { createInitialRouterState } from '../create-initial-router-state'
import {
PrefetchAction,
diff --git a/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.test.tsx b/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.test.tsx
index 9ed54e8994d2e..90ce7dc9423a3 100644
--- a/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.test.tsx
+++ b/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.test.tsx
@@ -46,7 +46,7 @@ import { FlightRouterState } from '../../../../server/app-render/types'
import {
CacheNode,
CacheStates,
-} from '../../../../shared/lib/app-router-context.shared-runtime'
+} from '../../../../shared/lib/app-router-context'
import { createInitialRouterState } from '../create-initial-router-state'
import { RefreshAction, ACTION_REFRESH } from '../router-reducer-types'
import { refreshReducer } from './refresh-reducer'
@@ -66,6 +66,10 @@ const getInitialRouterStateTree = (): FlightRouterState => [
true,
]
+const globalMutable = {
+ refresh: () => {},
+}
+
async function runPromiseThrowChain(fn: any): Promise {
try {
return await fn()
@@ -139,7 +143,7 @@ describe('refreshReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
origin: new URL('/linking', 'https://localhost').origin,
}
@@ -300,7 +304,7 @@ describe('refreshReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
origin: new URL('/linking', 'https://localhost').origin,
}
@@ -487,7 +491,7 @@ describe('refreshReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
origin: new URL('/linking', 'https://localhost').origin,
}
@@ -723,7 +727,7 @@ describe('refreshReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
origin: new URL('/linking', 'https://localhost').origin,
}
diff --git a/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.ts b/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.ts
index bd6dfc4ef9047..cd87ef3802b00 100644
--- a/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.ts
+++ b/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.ts
@@ -11,7 +11,7 @@ import {
} from '../router-reducer-types'
import { handleExternalUrl } from './navigate-reducer'
import { handleMutable } from '../handle-mutable'
-import { CacheStates } from '../../../../shared/lib/app-router-context.shared-runtime'
+import { CacheStates } from '../../../../shared/lib/app-router-context'
import { fillLazyItemsTillLeafWithHead } from '../fill-lazy-items-till-leaf-with-head'
export function refreshReducer(
diff --git a/packages/next/src/client/components/router-reducer/reducers/restore-reducer.test.tsx b/packages/next/src/client/components/router-reducer/reducers/restore-reducer.test.tsx
index 36c978926517f..b11f39b141ccf 100644
--- a/packages/next/src/client/components/router-reducer/reducers/restore-reducer.test.tsx
+++ b/packages/next/src/client/components/router-reducer/reducers/restore-reducer.test.tsx
@@ -3,7 +3,7 @@ import type { FlightRouterState } from '../../../../server/app-render/types'
import {
CacheNode,
CacheStates,
-} from '../../../../shared/lib/app-router-context.shared-runtime'
+} from '../../../../shared/lib/app-router-context'
import { createInitialRouterState } from '../create-initial-router-state'
import { RestoreAction, ACTION_RESTORE } from '../router-reducer-types'
import { restoreReducer } from './restore-reducer'
diff --git a/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts b/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts
index 0c6caaba746ca..3b8fa6acb4013 100644
--- a/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts
+++ b/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts
@@ -27,7 +27,7 @@ import { createHrefFromUrl } from '../create-href-from-url'
import { handleExternalUrl } from './navigate-reducer'
import { applyRouterStatePatchToTree } from '../apply-router-state-patch-to-tree'
import { isNavigatingToNewRootLayout } from '../is-navigating-to-new-root-layout'
-import { CacheStates } from '../../../../shared/lib/app-router-context.shared-runtime'
+import { CacheStates } from '../../../../shared/lib/app-router-context'
import { handleMutable } from '../handle-mutable'
import { fillLazyItemsTillLeafWithHead } from '../fill-lazy-items-till-leaf-with-head'
diff --git a/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.test.tsx b/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.test.tsx
index 0540c02079cb1..db72a92fce743 100644
--- a/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.test.tsx
+++ b/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.test.tsx
@@ -7,6 +7,10 @@ import type {
const buildId = 'development'
+const globalMutable = {
+ refresh: () => {},
+}
+
jest.mock('../fetch-server-response', () => {
const flightData: FlightData = [
[
@@ -41,7 +45,7 @@ jest.mock('../fetch-server-response', () => {
import {
CacheNode,
CacheStates,
-} from '../../../../shared/lib/app-router-context.shared-runtime'
+} from '../../../../shared/lib/app-router-context'
import { createInitialRouterState } from '../create-initial-router-state'
import {
ServerPatchAction,
@@ -184,7 +188,7 @@ describe('serverPatchReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
}
const newState = await runPromiseThrowChain(() =>
@@ -375,7 +379,7 @@ describe('serverPatchReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
}
await runPromiseThrowChain(() => serverPatchReducer(state, action))
@@ -514,7 +518,7 @@ describe('serverPatchReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
}
const state = createInitialRouterState({
@@ -556,7 +560,7 @@ describe('serverPatchReducer', () => {
subTreeData: null,
parallelRoutes: new Map(),
},
- mutable: {},
+ mutable: { globalMutable },
}
const newState = await runPromiseThrowChain(() =>
diff --git a/packages/next/src/client/components/router-reducer/router-reducer-types.ts b/packages/next/src/client/components/router-reducer/router-reducer-types.ts
index defbb657c7c42..284628dbf9098 100644
--- a/packages/next/src/client/components/router-reducer/router-reducer-types.ts
+++ b/packages/next/src/client/components/router-reducer/router-reducer-types.ts
@@ -1,4 +1,4 @@
-import type { CacheNode } from '../../../shared/lib/app-router-context.shared-runtime'
+import type { CacheNode } from '../../../shared/lib/app-router-context'
import type {
FlightRouterState,
FlightData,
@@ -38,11 +38,15 @@ export interface Mutable {
prefetchCache?: AppRouterState['prefetchCache']
hashFragment?: string
shouldScroll?: boolean
+ globalMutable: {
+ pendingNavigatePath?: string
+ pendingMpaPath?: string
+ refresh: () => void
+ }
}
export interface ServerActionMutable extends Mutable {
inFlightServerAction?: Promise | null
- globalMutable: { pendingNavigatePath?: string; refresh: () => void }
actionResultResolved?: boolean
}
diff --git a/packages/next/src/client/components/static-generation-async-storage.external.ts b/packages/next/src/client/components/static-generation-async-storage.ts
similarity index 100%
rename from packages/next/src/client/components/static-generation-async-storage.external.ts
rename to packages/next/src/client/components/static-generation-async-storage.ts
diff --git a/packages/next/src/client/components/static-generation-bailout.ts b/packages/next/src/client/components/static-generation-bailout.ts
index 4d35150664251..c5072218f035c 100644
--- a/packages/next/src/client/components/static-generation-bailout.ts
+++ b/packages/next/src/client/components/static-generation-bailout.ts
@@ -1,5 +1,5 @@
import { DynamicServerError } from './hooks-server-context'
-import { staticGenerationAsyncStorage } from './static-generation-async-storage.external'
+import { staticGenerationAsyncStorage } from './static-generation-async-storage'
class StaticGenBailoutError extends Error {
code = 'NEXT_STATIC_GEN_BAILOUT'
diff --git a/packages/next/src/client/image-component.tsx b/packages/next/src/client/image-component.tsx
index 321b07ecd0a5f..3f2183c004b10 100644
--- a/packages/next/src/client/image-component.tsx
+++ b/packages/next/src/client/image-component.tsx
@@ -25,9 +25,9 @@ import type {
ImageLoaderProps,
} from '../shared/lib/image-config'
import { imageConfigDefault } from '../shared/lib/image-config'
-import { ImageConfigContext } from '../shared/lib/image-config-context.shared-runtime'
+import { ImageConfigContext } from '../shared/lib/image-config-context'
import { warnOnce } from '../shared/lib/utils/warn-once'
-import { RouterContext } from '../shared/lib/router-context.shared-runtime'
+import { RouterContext } from '../shared/lib/router-context'
// @ts-ignore - This is replaced by webpack alias
import defaultLoader from 'next/dist/shared/lib/image-loader'
diff --git a/packages/next/src/client/index.tsx b/packages/next/src/client/index.tsx
index 0f8a95c93746e..f7c163f020d31 100644
--- a/packages/next/src/client/index.tsx
+++ b/packages/next/src/client/index.tsx
@@ -10,16 +10,16 @@ import type {
import React from 'react'
import ReactDOM from 'react-dom/client'
-import { HeadManagerContext } from '../shared/lib/head-manager-context.shared-runtime'
+import { HeadManagerContext } from '../shared/lib/head-manager-context'
import mitt, { MittEmitter } from '../shared/lib/mitt'
-import { RouterContext } from '../shared/lib/router-context.shared-runtime'
+import { RouterContext } from '../shared/lib/router-context'
import { handleSmoothScroll } from '../shared/lib/router/utils/handle-smooth-scroll'
import { isDynamicRoute } from '../shared/lib/router/utils/is-dynamic'
import {
urlQueryToSearchParams,
assign,
} from '../shared/lib/router/utils/querystring'
-import { setConfig } from '../shared/lib/runtime-config.shared-runtime'
+import { setConfig } from '../shared/lib/runtime-config'
import {
getURL,
loadGetInitialProps,
@@ -34,17 +34,17 @@ import measureWebVitals from './performance-relayer'
import { RouteAnnouncer } from './route-announcer'
import { createRouter, makePublicRouterInstance } from './router'
import { getProperError } from '../lib/is-error'
-import { ImageConfigContext } from '../shared/lib/image-config-context.shared-runtime'
+import { ImageConfigContext } from '../shared/lib/image-config-context'
import { ImageConfigComplete } from '../shared/lib/image-config'
import { removeBasePath } from './remove-base-path'
import { hasBasePath } from './has-base-path'
-import { AppRouterContext } from '../shared/lib/app-router-context.shared-runtime'
+import { AppRouterContext } from '../shared/lib/app-router-context'
import {
adaptForAppRouterInstance,
adaptForSearchParams,
PathnameContextProviderAdapter,
-} from '../shared/lib/router/adapters.shared-runtime'
-import { SearchParamsContext } from '../shared/lib/hooks-client-context.shared-runtime'
+} from '../shared/lib/router/adapters'
+import { SearchParamsContext } from '../shared/lib/hooks-client-context'
import onRecoverableError from './on-recoverable-error'
import tracer from './tracing/tracer'
import reportToSocket from './tracing/report-to-socket'
diff --git a/packages/next/src/client/legacy/image.tsx b/packages/next/src/client/legacy/image.tsx
index 07ec2e217c200..d1456477bacf6 100644
--- a/packages/next/src/client/legacy/image.tsx
+++ b/packages/next/src/client/legacy/image.tsx
@@ -16,7 +16,7 @@ import {
VALID_LOADERS,
} from '../../shared/lib/image-config'
import { useIntersection } from '../use-intersection'
-import { ImageConfigContext } from '../../shared/lib/image-config-context.shared-runtime'
+import { ImageConfigContext } from '../../shared/lib/image-config-context'
import { warnOnce } from '../../shared/lib/utils/warn-once'
import { normalizePathTrailingSlash } from '../normalize-trailing-slash'
diff --git a/packages/next/src/client/link.tsx b/packages/next/src/client/link.tsx
index 7a15dee249e26..94226c8caa5c0 100644
--- a/packages/next/src/client/link.tsx
+++ b/packages/next/src/client/link.tsx
@@ -12,12 +12,12 @@ import { isLocalURL } from '../shared/lib/router/utils/is-local-url'
import { formatUrl } from '../shared/lib/router/utils/format-url'
import { isAbsoluteUrl } from '../shared/lib/utils'
import { addLocale } from './add-locale'
-import { RouterContext } from '../shared/lib/router-context.shared-runtime'
+import { RouterContext } from '../shared/lib/router-context'
import {
AppRouterContext,
AppRouterInstance,
PrefetchOptions as AppRouterPrefetchOptions,
-} from '../shared/lib/app-router-context.shared-runtime'
+} from '../shared/lib/app-router-context'
import { useIntersection } from './use-intersection'
import { getDomainLocale } from './get-domain-locale'
import { addBasePath } from './add-base-path'
diff --git a/packages/next/src/client/router.ts b/packages/next/src/client/router.ts
index f43126691e5e5..342ecb623df74 100644
--- a/packages/next/src/client/router.ts
+++ b/packages/next/src/client/router.ts
@@ -2,7 +2,7 @@
import React from 'react'
import Router from '../shared/lib/router/router'
import type { NextRouter } from '../shared/lib/router/router'
-import { RouterContext } from '../shared/lib/router-context.shared-runtime'
+import { RouterContext } from '../shared/lib/router-context'
import isError from '../lib/is-error'
type SingletonRouterBase = {
diff --git a/packages/next/src/client/script.tsx b/packages/next/src/client/script.tsx
index f695e691c482d..a4b2c6dcd3184 100644
--- a/packages/next/src/client/script.tsx
+++ b/packages/next/src/client/script.tsx
@@ -3,7 +3,7 @@
import ReactDOM from 'react-dom'
import React, { useEffect, useContext, useRef } from 'react'
import { ScriptHTMLAttributes } from 'react'
-import { HeadManagerContext } from '../shared/lib/head-manager-context.shared-runtime'
+import { HeadManagerContext } from '../shared/lib/head-manager-context'
import { DOMAttributeNames } from './head-manager'
import { requestIdleCallback } from './request-idle-callback'
diff --git a/packages/next/src/compiled/debug/index.js b/packages/next/src/compiled/debug/index.js
index 0bdf3d36ef5d3..853a1a2db7873 100644
--- a/packages/next/src/compiled/debug/index.js
+++ b/packages/next/src/compiled/debug/index.js
@@ -1 +1 @@
-(()=>{var e={237:(e,t,r)=>{t.log=log;t.formatArgs=formatArgs;t.save=save;t.load=load;t.useColors=useColors;t.storage=localstorage();t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"];function useColors(){if(typeof window!=="undefined"&&window.process&&(window.process.type==="renderer"||window.process.__nwjs)){return true}if(typeof navigator!=="undefined"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)){return false}return typeof document!=="undefined"&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||typeof window!=="undefined"&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||typeof navigator!=="undefined"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||typeof navigator!=="undefined"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}function formatArgs(t){t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff);if(!this.useColors){return}const r="color: "+this.color;t.splice(1,0,r,"color: inherit");let s=0;let n=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{if(e==="%%"){return}s++;if(e==="%c"){n=s}}));t.splice(n,0,r)}function log(...e){return typeof console==="object"&&console.log&&console.log(...e)}function save(e){try{if(e){t.storage.setItem("debug",e)}else{t.storage.removeItem("debug")}}catch(e){}}function load(){let e;try{e=t.storage.getItem("debug")}catch(e){}if(!e&&typeof process!=="undefined"&&"env"in process){e=process.env.DEBUG}return e}function localstorage(){try{return localStorage}catch(e){}}e.exports=r(573)(t);const{formatters:s}=e.exports;s.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}},573:(e,t,r)=>{function setup(e){createDebug.debug=createDebug;createDebug.default=createDebug;createDebug.coerce=coerce;createDebug.disable=disable;createDebug.enable=enable;createDebug.enabled=enabled;createDebug.humanize=r(79);Object.keys(e).forEach((t=>{createDebug[t]=e[t]}));createDebug.instances=[];createDebug.names=[];createDebug.skips=[];createDebug.formatters={};function selectColor(e){let t=0;for(let r=0;r{if(t==="%%"){return t}o++;const n=createDebug.formatters[s];if(typeof n==="function"){const s=e[o];t=n.call(r,s);e.splice(o,1);o--}return t}));createDebug.formatArgs.call(r,e);const c=r.log||createDebug.log;c.apply(r,e)}debug.namespace=e;debug.enabled=createDebug.enabled(e);debug.useColors=createDebug.useColors();debug.color=selectColor(e);debug.destroy=destroy;debug.extend=extend;if(typeof createDebug.init==="function"){createDebug.init(debug)}createDebug.instances.push(debug);return debug}function destroy(){const e=createDebug.instances.indexOf(this);if(e!==-1){createDebug.instances.splice(e,1);return true}return false}function extend(e,t){const r=createDebug(this.namespace+(typeof t==="undefined"?":":t)+e);r.log=this.log;return r}function enable(e){createDebug.save(e);createDebug.names=[];createDebug.skips=[];let t;const r=(typeof e==="string"?e:"").split(/[\s,]+/);const s=r.length;for(t=0;t"-"+e))].join(",");createDebug.enable("");return e}function enabled(e){if(e[e.length-1]==="*"){return true}let t;let r;for(t=0,r=createDebug.skips.length;t{if(typeof process==="undefined"||process.type==="renderer"||process.browser===true||process.__nwjs){e.exports=r(237)}else{e.exports=r(354)}},354:(e,t,r)=>{const s=r(224);const n=r(837);t.init=init;t.log=log;t.formatArgs=formatArgs;t.save=save;t.load=load;t.useColors=useColors;t.colors=[6,2,3,4,5,1];try{const e=r(220);if(e&&(e.stderr||e).level>=2){t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221]}}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const r=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let s=process.env[t];if(/^(yes|on|true|enabled)$/i.test(s)){s=true}else if(/^(no|off|false|disabled)$/i.test(s)){s=false}else if(s==="null"){s=null}else{s=Number(s)}e[r]=s;return e}),{});function useColors(){return"colors"in t.inspectOpts?Boolean(t.inspectOpts.colors):s.isatty(process.stderr.fd)}function formatArgs(t){const{namespace:r,useColors:s}=this;if(s){const s=this.color;const n="[3"+(s<8?s:"8;5;"+s);const o=` ${n};1m${r} [0m`;t[0]=o+t[0].split("\n").join("\n"+o);t.push(n+"m+"+e.exports.humanize(this.diff)+"[0m")}else{t[0]=getDate()+r+" "+t[0]}}function getDate(){if(t.inspectOpts.hideDate){return""}return(new Date).toISOString()+" "}function log(...e){return process.stderr.write(n.format(...e)+"\n")}function save(e){if(e){process.env.DEBUG=e}else{delete process.env.DEBUG}}function load(){return process.env.DEBUG}function init(e){e.inspectOpts={};const r=Object.keys(t.inspectOpts);for(let s=0;s{"use strict";e.exports=(e,t)=>{t=t||process.argv;const r=e.startsWith("-")?"":e.length===1?"-":"--";const s=t.indexOf(r+e);const n=t.indexOf("--");return s!==-1&&(n===-1?true:s{var t=1e3;var r=t*60;var s=r*60;var n=s*24;var o=n*7;var c=n*365.25;e.exports=function(e,t){t=t||{};var r=typeof e;if(r==="string"&&e.length>0){return parse(e)}else if(r==="number"&&isFinite(e)){return t.long?fmtLong(e):fmtShort(e)}throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(e))};function parse(e){e=String(e);if(e.length>100){return}var a=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(e);if(!a){return}var u=parseFloat(a[1]);var i=(a[2]||"ms").toLowerCase();switch(i){case"years":case"year":case"yrs":case"yr":case"y":return u*c;case"weeks":case"week":case"w":return u*o;case"days":case"day":case"d":return u*n;case"hours":case"hour":case"hrs":case"hr":case"h":return u*s;case"minutes":case"minute":case"mins":case"min":case"m":return u*r;case"seconds":case"second":case"secs":case"sec":case"s":return u*t;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return u;default:return undefined}}function fmtShort(e){var o=Math.abs(e);if(o>=n){return Math.round(e/n)+"d"}if(o>=s){return Math.round(e/s)+"h"}if(o>=r){return Math.round(e/r)+"m"}if(o>=t){return Math.round(e/t)+"s"}return e+"ms"}function fmtLong(e){var o=Math.abs(e);if(o>=n){return plural(e,o,n,"day")}if(o>=s){return plural(e,o,s,"hour")}if(o>=r){return plural(e,o,r,"minute")}if(o>=t){return plural(e,o,t,"second")}return e+" ms"}function plural(e,t,r,s){var n=t>=r*1.5;return Math.round(e/r)+" "+s+(n?"s":"")}},220:(e,t,r)=>{"use strict";const s=r(37);const n=r(343);const o=process.env;let c;if(n("no-color")||n("no-colors")||n("color=false")){c=false}else if(n("color")||n("colors")||n("color=true")||n("color=always")){c=true}if("FORCE_COLOR"in o){c=o.FORCE_COLOR.length===0||parseInt(o.FORCE_COLOR,10)!==0}function translateLevel(e){if(e===0){return false}return{level:e,hasBasic:true,has256:e>=2,has16m:e>=3}}function supportsColor(e){if(c===false){return 0}if(n("color=16m")||n("color=full")||n("color=truecolor")){return 3}if(n("color=256")){return 2}if(e&&!e.isTTY&&c!==true){return 0}const t=c?1:0;if(process.platform==="win32"){const e=s.release().split(".");if(Number(process.versions.node.split(".")[0])>=8&&Number(e[0])>=10&&Number(e[2])>=10586){return Number(e[2])>=14931?3:2}return 1}if("CI"in o){if(["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some((e=>e in o))||o.CI_NAME==="codeship"){return 1}return t}if("TEAMCITY_VERSION"in o){return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(o.TEAMCITY_VERSION)?1:0}if(o.COLORTERM==="truecolor"){return 3}if("TERM_PROGRAM"in o){const e=parseInt((o.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(o.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}if(/-256(color)?$/i.test(o.TERM)){return 2}if(/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(o.TERM)){return 1}if("COLORTERM"in o){return 1}if(o.TERM==="dumb"){return t}return t}function getSupportLevel(e){const t=supportsColor(e);return translateLevel(t)}e.exports={supportsColor:getSupportLevel,stdout:getSupportLevel(process.stdout),stderr:getSupportLevel(process.stderr)}},37:e=>{"use strict";e.exports=require("os")},224:e=>{"use strict";e.exports=require("tty")},837:e=>{"use strict";e.exports=require("util")}};var t={};function __nccwpck_require__(r){var s=t[r];if(s!==undefined){return s.exports}var n=t[r]={exports:{}};var o=true;try{e[r](n,n.exports,__nccwpck_require__);o=false}finally{if(o)delete t[r]}return n.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var r=__nccwpck_require__(792);module.exports=r})();
\ No newline at end of file
+(()=>{var e={237:(e,t,r)=>{t.log=log;t.formatArgs=formatArgs;t.save=save;t.load=load;t.useColors=useColors;t.storage=localstorage();t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"];function useColors(){if(typeof window!=="undefined"&&window.process&&(window.process.type==="renderer"||window.process.__nwjs)){return true}if(typeof navigator!=="undefined"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)){return false}return typeof document!=="undefined"&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||typeof window!=="undefined"&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||typeof navigator!=="undefined"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||typeof navigator!=="undefined"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}function formatArgs(t){t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff);if(!this.useColors){return}const r="color: "+this.color;t.splice(1,0,r,"color: inherit");let s=0;let n=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{if(e==="%%"){return}s++;if(e==="%c"){n=s}}));t.splice(n,0,r)}function log(...e){return typeof console==="object"&&console.log&&console.log(...e)}function save(e){try{if(e){t.storage.setItem("debug",e)}else{t.storage.removeItem("debug")}}catch(e){}}function load(){let e;try{e=t.storage.getItem("debug")}catch(e){}if(!e&&typeof process!=="undefined"&&"env"in process){e=process.env.DEBUG}return e}function localstorage(){try{return localStorage}catch(e){}}e.exports=r(573)(t);const{formatters:s}=e.exports;s.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}},573:(e,t,r)=>{function setup(e){createDebug.debug=createDebug;createDebug.default=createDebug;createDebug.coerce=coerce;createDebug.disable=disable;createDebug.enable=enable;createDebug.enabled=enabled;createDebug.humanize=r(958);Object.keys(e).forEach((t=>{createDebug[t]=e[t]}));createDebug.instances=[];createDebug.names=[];createDebug.skips=[];createDebug.formatters={};function selectColor(e){let t=0;for(let r=0;r{if(t==="%%"){return t}o++;const n=createDebug.formatters[s];if(typeof n==="function"){const s=e[o];t=n.call(r,s);e.splice(o,1);o--}return t}));createDebug.formatArgs.call(r,e);const c=r.log||createDebug.log;c.apply(r,e)}debug.namespace=e;debug.enabled=createDebug.enabled(e);debug.useColors=createDebug.useColors();debug.color=selectColor(e);debug.destroy=destroy;debug.extend=extend;if(typeof createDebug.init==="function"){createDebug.init(debug)}createDebug.instances.push(debug);return debug}function destroy(){const e=createDebug.instances.indexOf(this);if(e!==-1){createDebug.instances.splice(e,1);return true}return false}function extend(e,t){const r=createDebug(this.namespace+(typeof t==="undefined"?":":t)+e);r.log=this.log;return r}function enable(e){createDebug.save(e);createDebug.names=[];createDebug.skips=[];let t;const r=(typeof e==="string"?e:"").split(/[\s,]+/);const s=r.length;for(t=0;t"-"+e))].join(",");createDebug.enable("");return e}function enabled(e){if(e[e.length-1]==="*"){return true}let t;let r;for(t=0,r=createDebug.skips.length;t{if(typeof process==="undefined"||process.type==="renderer"||process.browser===true||process.__nwjs){e.exports=r(237)}else{e.exports=r(354)}},354:(e,t,r)=>{const s=r(224);const n=r(837);t.init=init;t.log=log;t.formatArgs=formatArgs;t.save=save;t.load=load;t.useColors=useColors;t.colors=[6,2,3,4,5,1];try{const e=r(220);if(e&&(e.stderr||e).level>=2){t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221]}}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const r=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let s=process.env[t];if(/^(yes|on|true|enabled)$/i.test(s)){s=true}else if(/^(no|off|false|disabled)$/i.test(s)){s=false}else if(s==="null"){s=null}else{s=Number(s)}e[r]=s;return e}),{});function useColors(){return"colors"in t.inspectOpts?Boolean(t.inspectOpts.colors):s.isatty(process.stderr.fd)}function formatArgs(t){const{namespace:r,useColors:s}=this;if(s){const s=this.color;const n="[3"+(s<8?s:"8;5;"+s);const o=` ${n};1m${r} [0m`;t[0]=o+t[0].split("\n").join("\n"+o);t.push(n+"m+"+e.exports.humanize(this.diff)+"[0m")}else{t[0]=getDate()+r+" "+t[0]}}function getDate(){if(t.inspectOpts.hideDate){return""}return(new Date).toISOString()+" "}function log(...e){return process.stderr.write(n.format(...e)+"\n")}function save(e){if(e){process.env.DEBUG=e}else{delete process.env.DEBUG}}function load(){return process.env.DEBUG}function init(e){e.inspectOpts={};const r=Object.keys(t.inspectOpts);for(let s=0;s{"use strict";e.exports=(e,t)=>{t=t||process.argv;const r=e.startsWith("-")?"":e.length===1?"-":"--";const s=t.indexOf(r+e);const n=t.indexOf("--");return s!==-1&&(n===-1?true:s{var t=1e3;var r=t*60;var s=r*60;var n=s*24;var o=n*7;var c=n*365.25;e.exports=function(e,t){t=t||{};var r=typeof e;if(r==="string"&&e.length>0){return parse(e)}else if(r==="number"&&isFinite(e)){return t.long?fmtLong(e):fmtShort(e)}throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(e))};function parse(e){e=String(e);if(e.length>100){return}var a=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(e);if(!a){return}var u=parseFloat(a[1]);var i=(a[2]||"ms").toLowerCase();switch(i){case"years":case"year":case"yrs":case"yr":case"y":return u*c;case"weeks":case"week":case"w":return u*o;case"days":case"day":case"d":return u*n;case"hours":case"hour":case"hrs":case"hr":case"h":return u*s;case"minutes":case"minute":case"mins":case"min":case"m":return u*r;case"seconds":case"second":case"secs":case"sec":case"s":return u*t;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return u;default:return undefined}}function fmtShort(e){var o=Math.abs(e);if(o>=n){return Math.round(e/n)+"d"}if(o>=s){return Math.round(e/s)+"h"}if(o>=r){return Math.round(e/r)+"m"}if(o>=t){return Math.round(e/t)+"s"}return e+"ms"}function fmtLong(e){var o=Math.abs(e);if(o>=n){return plural(e,o,n,"day")}if(o>=s){return plural(e,o,s,"hour")}if(o>=r){return plural(e,o,r,"minute")}if(o>=t){return plural(e,o,t,"second")}return e+" ms"}function plural(e,t,r,s){var n=t>=r*1.5;return Math.round(e/r)+" "+s+(n?"s":"")}},220:(e,t,r)=>{"use strict";const s=r(37);const n=r(343);const o=process.env;let c;if(n("no-color")||n("no-colors")||n("color=false")){c=false}else if(n("color")||n("colors")||n("color=true")||n("color=always")){c=true}if("FORCE_COLOR"in o){c=o.FORCE_COLOR.length===0||parseInt(o.FORCE_COLOR,10)!==0}function translateLevel(e){if(e===0){return false}return{level:e,hasBasic:true,has256:e>=2,has16m:e>=3}}function supportsColor(e){if(c===false){return 0}if(n("color=16m")||n("color=full")||n("color=truecolor")){return 3}if(n("color=256")){return 2}if(e&&!e.isTTY&&c!==true){return 0}const t=c?1:0;if(process.platform==="win32"){const e=s.release().split(".");if(Number(process.versions.node.split(".")[0])>=8&&Number(e[0])>=10&&Number(e[2])>=10586){return Number(e[2])>=14931?3:2}return 1}if("CI"in o){if(["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some((e=>e in o))||o.CI_NAME==="codeship"){return 1}return t}if("TEAMCITY_VERSION"in o){return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(o.TEAMCITY_VERSION)?1:0}if(o.COLORTERM==="truecolor"){return 3}if("TERM_PROGRAM"in o){const e=parseInt((o.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(o.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}if(/-256(color)?$/i.test(o.TERM)){return 2}if(/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(o.TERM)){return 1}if("COLORTERM"in o){return 1}if(o.TERM==="dumb"){return t}return t}function getSupportLevel(e){const t=supportsColor(e);return translateLevel(t)}e.exports={supportsColor:getSupportLevel,stdout:getSupportLevel(process.stdout),stderr:getSupportLevel(process.stderr)}},37:e=>{"use strict";e.exports=require("os")},224:e=>{"use strict";e.exports=require("tty")},837:e=>{"use strict";e.exports=require("util")}};var t={};function __nccwpck_require__(r){var s=t[r];if(s!==undefined){return s.exports}var n=t[r]={exports:{}};var o=true;try{e[r](n,n.exports,__nccwpck_require__);o=false}finally{if(o)delete t[r]}return n.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var r=__nccwpck_require__(792);module.exports=r})();
\ No newline at end of file
diff --git a/packages/next/src/export/worker.ts b/packages/next/src/export/worker.ts
index b9fb7b9afd60a..31f58755996a4 100644
--- a/packages/next/src/export/worker.ts
+++ b/packages/next/src/export/worker.ts
@@ -59,7 +59,7 @@ import {
RSC,
} from '../client/components/app-router-headers'
-const envConfig = require('../shared/lib/runtime-config.shared-runtime')
+const envConfig = require('../shared/lib/runtime-config')
;(globalThis as any).__NEXT_DATA__ = {
nextExport: true,
@@ -307,10 +307,8 @@ export default async function exportPage({
await promises.mkdir(baseDir, { recursive: true })
let renderResult: RenderResult | undefined
let curRenderOpts: RenderOpts = {}
- const renderToHTML =
- require('../server/future/route-modules/pages/module.compiled')
- .renderToHTML as typeof import('../server/render').renderToHTML
-
+ const { renderToHTML } =
+ require('../server/render') as typeof import('../server/render')
let renderMethod = renderToHTML
let inAmpMode = false,
hybridAmp = false
@@ -481,6 +479,7 @@ export default async function exportPage({
const module = await RouteModuleLoader.load(
filename
)
+
// Call the handler with the request and context from the module.
const response = await module.handle(request, context)
@@ -536,9 +535,8 @@ export default async function exportPage({
results.fromBuildExportRevalidate = 0
}
} else {
- const renderToHTMLOrFlight =
- require('../server/future/route-modules/app-page/module.compiled')
- .renderToHTMLOrFlight as typeof import('../server/app-render/app-render').renderToHTMLOrFlight
+ const { renderToHTMLOrFlight } =
+ require('../server/app-render/app-render') as typeof import('../server/app-render/app-render')
try {
curRenderOpts.params ||= {}
diff --git a/packages/next/src/lib/chalk.ts b/packages/next/src/lib/chalk.ts
index d0939d9148b97..8e40472953f8f 100644
--- a/packages/next/src/lib/chalk.ts
+++ b/packages/next/src/lib/chalk.ts
@@ -1,6 +1,6 @@
let chalk: typeof import('next/dist/compiled/chalk')
-if (process.env.NEXT_RUNTIME === 'edge' || process.env.NEXT_MINIMAL) {
+if (process.env.NEXT_RUNTIME === 'edge') {
chalk = require('./web/chalk').default
} else {
chalk = require('next/dist/compiled/chalk')
diff --git a/packages/next/src/lib/constants.ts b/packages/next/src/lib/constants.ts
index 46f85311a9f0a..fc94397c6aca7 100644
--- a/packages/next/src/lib/constants.ts
+++ b/packages/next/src/lib/constants.ts
@@ -132,10 +132,6 @@ const WEBPACK_LAYERS_NAMES = {
* The server bundle layer for metadata routes.
*/
appMetadataRoute: 'app-metadata-route',
- /**
- * The layer for the server bundle for App Route handlers.
- */
- appRouteHandler: 'app-route-handler',
}
export const WEBPACK_LAYERS = {
@@ -145,7 +141,6 @@ export const WEBPACK_LAYERS = {
WEBPACK_LAYERS_NAMES.reactServerComponents,
WEBPACK_LAYERS_NAMES.actionBrowser,
WEBPACK_LAYERS_NAMES.appMetadataRoute,
- WEBPACK_LAYERS_NAMES.appRouteHandler,
],
},
}
diff --git a/packages/next/src/pages/_document.tsx b/packages/next/src/pages/_document.tsx
index f0a29cb15d1fc..a8526011c5d33 100644
--- a/packages/next/src/pages/_document.tsx
+++ b/packages/next/src/pages/_document.tsx
@@ -17,11 +17,8 @@ import { BuildManifest, getPageFiles } from '../server/get-page-files'
import { htmlEscapeJsonString } from '../server/htmlescape'
import isError from '../lib/is-error'
-import {
- HtmlContext,
- useHtmlContext,
-} from '../shared/lib/html-context.shared-runtime'
-import type { HtmlProps } from '../shared/lib/html-context.shared-runtime'
+import { HtmlContext, useHtmlContext } from '../shared/lib/html-context'
+import type { HtmlProps } from '../shared/lib/html-context'
export { DocumentContext, DocumentInitialProps, DocumentProps }
diff --git a/packages/next/src/server/app-render/action-handler.ts b/packages/next/src/server/app-render/action-handler.ts
index 9f6059ec48f5a..6b8bc3228a005 100644
--- a/packages/next/src/server/app-render/action-handler.ts
+++ b/packages/next/src/server/app-render/action-handler.ts
@@ -19,10 +19,10 @@ import {
isRedirectError,
} from '../../client/components/redirect'
import RenderResult from '../render-result'
-import { StaticGenerationStore } from '../../client/components/static-generation-async-storage.external'
+import { StaticGenerationStore } from '../../client/components/static-generation-async-storage'
import { FlightRenderResult } from './flight-render-result'
import { ActionResult } from './types'
-import { ActionAsyncStorage } from '../../client/components/action-async-storage.external'
+import { ActionAsyncStorage } from '../../client/components/action-async-storage'
import {
filterReqHeaders,
actionsForbiddenHeaders,
@@ -31,8 +31,7 @@ import {
appendMutableCookies,
getModifiedCookieValues,
} from '../web/spec-extension/adapters/request-cookies'
-
-import { RequestStore } from '../../client/components/request-async-storage.external'
+import { RequestStore } from '../../client/components/request-async-storage'
import {
NEXT_CACHE_REVALIDATED_TAGS_HEADER,
NEXT_CACHE_REVALIDATE_TAG_TOKEN_HEADER,
diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx
index 1dd2eb8f7c639..30749ac66a83d 100644
--- a/packages/next/src/server/app-render/app-render.tsx
+++ b/packages/next/src/server/app-render/app-render.tsx
@@ -11,9 +11,9 @@ import type {
Segment,
} from './types'
-import type { StaticGenerationAsyncStorage } from '../../client/components/static-generation-async-storage.external'
+import type { StaticGenerationAsyncStorage } from '../../client/components/static-generation-async-storage'
import type { StaticGenerationBailout } from '../../client/components/static-generation-bailout'
-import type { RequestAsyncStorage } from '../../client/components/request-async-storage.external'
+import type { RequestAsyncStorage } from '../../client/components/request-async-storage'
import React from 'react'
import { createServerComponentRenderer } from './create-server-components-renderer'
@@ -286,13 +286,10 @@ export async function renderToHTMLOrFlight(
* that we need to resolve the final metadata.
*/
- let requestId: string
-
- if (process.env.NEXT_RUNTIME === 'edge') {
- requestId = crypto.randomUUID()
- } else {
- requestId = require('next/dist/compiled/nanoid').nanoid()
- }
+ const requestId =
+ process.env.NEXT_RUNTIME === 'edge'
+ ? crypto.randomUUID()
+ : require('next/dist/compiled/nanoid').nanoid()
const LayoutRouter =
ComponentMod.LayoutRouter as typeof import('../../client/components/layout-router').default
@@ -1395,7 +1392,7 @@ export async function renderToHTMLOrFlight(
)
const { HeadManagerContext } =
- require('../../shared/lib/head-manager-context.shared-runtime') as typeof import('../../shared/lib/head-manager-context.shared-runtime')
+ require('../../shared/lib/head-manager-context') as typeof import('../../shared/lib/head-manager-context')
// On each render, create a new `ServerInsertedHTML` context to capture
// injected nodes from user code (`useServerInsertedHTML`).
diff --git a/packages/next/src/server/app-render/entry-base.ts b/packages/next/src/server/app-render/entry-base.ts
index 0cc53e0214d86..6bc5fd7e7ace1 100644
--- a/packages/next/src/server/app-render/entry-base.ts
+++ b/packages/next/src/server/app-render/entry-base.ts
@@ -1,26 +1,36 @@
+const { default: AppRouter } =
+ require('next/dist/client/components/app-router') as typeof import('../../client/components/app-router')
+const { default: LayoutRouter } =
+ require('next/dist/client/components/layout-router') as typeof import('../../client/components/layout-router')
+const { default: RenderFromTemplateContext } =
+ require('next/dist/client/components/render-from-template-context') as typeof import('../../client/components/render-from-template-context')
+
+const { staticGenerationAsyncStorage } =
+ require('next/dist/client/components/static-generation-async-storage') as typeof import('../../client/components/static-generation-async-storage')
+
+const { requestAsyncStorage } =
+ require('next/dist/client/components/request-async-storage') as typeof import('../../client/components/request-async-storage')
+const { actionAsyncStorage } =
+ require('next/dist/client/components/action-async-storage') as typeof import('../../client/components/action-async-storage')
+
+const { staticGenerationBailout } =
+ require('next/dist/client/components/static-generation-bailout') as typeof import('../../client/components/static-generation-bailout')
+const { default: StaticGenerationSearchParamsBailoutProvider } =
+ require('next/dist/client/components/static-generation-searchparams-bailout-provider') as typeof import('../../client/components/static-generation-searchparams-bailout-provider')
+const { createSearchParamsBailoutProxy } =
+ require('next/dist/client/components/searchparams-bailout-proxy') as typeof import('../../client/components/searchparams-bailout-proxy')
+
+const serverHooks =
+ require('next/dist/client/components/hooks-server-context') as typeof import('../../client/components/hooks-server-context')
+
const {
renderToReadableStream,
decodeReply,
decodeAction,
// eslint-disable-next-line import/no-extraneous-dependencies
} = require('react-server-dom-webpack/server.edge')
-
-import AppRouter from '../../client/components/app-router'
-import LayoutRouter from '../../client/components/layout-router'
-import RenderFromTemplateContext from '../../client/components/render-from-template-context'
-import { staticGenerationAsyncStorage } from '../../client/components/static-generation-async-storage.external'
-import { requestAsyncStorage } from '../../client/components/request-async-storage.external'
-import { actionAsyncStorage } from '../../client/components/action-async-storage.external'
-import { staticGenerationBailout } from '../../client/components/static-generation-bailout'
-import StaticGenerationSearchParamsBailoutProvider from '../../client/components/static-generation-searchparams-bailout-provider'
-import { createSearchParamsBailoutProxy } from '../../client/components/searchparams-bailout-proxy'
-import * as serverHooks from '../../client/components/hooks-server-context'
-
-import {
- preloadStyle,
- preloadFont,
- preconnect,
-} from '../../server/app-render/rsc/preloads'
+const { preloadStyle, preloadFont, preconnect } =
+ require('next/dist/server/app-render/rsc/preloads') as typeof import('../../server/app-render/rsc/preloads')
const { NotFoundBoundary } =
require('next/dist/client/components/not-found-boundary') as typeof import('../../client/components/not-found-boundary')
diff --git a/packages/next/src/server/app-render/server-inserted-html.tsx b/packages/next/src/server/app-render/server-inserted-html.tsx
index 764dc62792077..f044c24feaba3 100644
--- a/packages/next/src/server/app-render/server-inserted-html.tsx
+++ b/packages/next/src/server/app-render/server-inserted-html.tsx
@@ -2,7 +2,7 @@
// elements into the HTML stream.
import React from 'react'
-import { ServerInsertedHTMLContext } from '../../shared/lib/server-inserted-html.shared-runtime'
+import { ServerInsertedHTMLContext } from '../../shared/lib/server-inserted-html'
export function createServerInsertedHTML() {
const serverInsertedHTMLCallbacks: (() => React.ReactNode)[] = []
diff --git a/packages/next/src/server/async-storage/request-async-storage-wrapper.ts b/packages/next/src/server/async-storage/request-async-storage-wrapper.ts
index 1376ecfb197cd..50795855c53d4 100644
--- a/packages/next/src/server/async-storage/request-async-storage-wrapper.ts
+++ b/packages/next/src/server/async-storage/request-async-storage-wrapper.ts
@@ -1,7 +1,7 @@
import type { BaseNextRequest, BaseNextResponse } from '../base-http'
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from 'http'
import type { AsyncLocalStorage } from 'async_hooks'
-import type { RequestStore } from '../../client/components/request-async-storage.external'
+import type { RequestStore } from '../../client/components/request-async-storage'
import type { RenderOpts } from '../app-render/types'
import type { AsyncStorageWrapper } from './async-storage-wrapper'
import type { NextRequest } from '../web/spec-extension/request'
diff --git a/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts b/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts
index d5adfc9de38b4..a28ac0e8ecb2a 100644
--- a/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts
+++ b/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts
@@ -1,5 +1,5 @@
import type { AsyncStorageWrapper } from './async-storage-wrapper'
-import type { StaticGenerationStore } from '../../client/components/static-generation-async-storage.external'
+import type { StaticGenerationStore } from '../../client/components/static-generation-async-storage'
import type { AsyncLocalStorage } from 'async_hooks'
import type { IncrementalCache } from '../lib/incremental-cache'
diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts
index fab999db35ddc..bacb1cc38e4ff 100644
--- a/packages/next/src/server/base-server.ts
+++ b/packages/next/src/server/base-server.ts
@@ -55,7 +55,7 @@ import {
getCookieParser,
checkIsOnDemandRevalidate,
} from './api-utils'
-import { setConfig } from '../shared/lib/runtime-config.shared-runtime'
+import { setConfig } from '../shared/lib/runtime-config'
import { setRevalidateHeaders } from './send-payload/revalidate-headers'
import { execOnce } from '../shared/lib/utils'
@@ -124,6 +124,7 @@ import {
} from './web/spec-extension/adapters/next-request'
import { matchNextDataPathname } from './lib/match-next-data-pathname'
import getRouteFromAssetPath from '../shared/lib/router/utils/get-route-from-asset-path'
+import { stripInternalHeaders } from './internal-utils'
export type FindComponentsResult = {
components: LoadComponentsReturnType
@@ -427,11 +428,7 @@ export default abstract class Server {
} = this.nextConfig
this.buildId = this.getBuildId()
- // this is a hack to avoid Webpack knowing this is equal to this.minimalMode
- // because we replace this.minimalMode to true in production bundles.
- const minimalModeKey = 'minimalMode'
- this[minimalModeKey] =
- minimalMode || !!process.env.NEXT_PRIVATE_MINIMAL_MODE
+ this.minimalMode = minimalMode || !!process.env.NEXT_PRIVATE_MINIMAL_MODE
this.hasAppDir = this.getHasAppDir(dev)
const serverComponents = this.hasAppDir
@@ -1542,6 +1539,28 @@ export default abstract class Server {
)
}
+ protected stripInternalHeaders(req: BaseNextRequest): void {
+ // Skip stripping internal headers in test mode while the header stripping
+ // has been explicitly disabled. This allows tests to verify internal
+ // routing behavior.
+ if (
+ process.env.__NEXT_TEST_MODE &&
+ process.env.__NEXT_NO_STRIP_INTERNAL_HEADERS === '1'
+ ) {
+ return
+ }
+
+ // Strip the internal headers from both the request and the original
+ // request.
+ stripInternalHeaders(req.headers)
+ if (
+ 'originalRequest' in req &&
+ 'headers' in (req as NodeNextRequest).originalRequest
+ ) {
+ stripInternalHeaders((req as NodeNextRequest).originalRequest.headers)
+ }
+ }
+
private async renderToResponseWithComponentsImpl(
{ req, res, pathname, renderOpts: opts }: RequestContext,
{ components, query }: FindComponentsResult
@@ -1550,6 +1569,10 @@ export default abstract class Server {
// For edge runtime 404 page, /_not-found needs to be treated as 404 page
(process.env.NEXT_RUNTIME === 'edge' && pathname === '/_not-found') ||
pathname === '/404'
+
+ // Strip the internal headers.
+ this.stripInternalHeaders(req)
+
const is500Page = pathname === '/500'
const isAppPath = components.isAppPath
const hasServerProps = !!components.getServerSideProps
diff --git a/packages/next/src/server/dev/next-dev-server.ts b/packages/next/src/server/dev/next-dev-server.ts
index 839fa1b13c0e4..1eca11b7358cb 100644
--- a/packages/next/src/server/dev/next-dev-server.ts
+++ b/packages/next/src/server/dev/next-dev-server.ts
@@ -41,7 +41,7 @@ import {
UnwrapPromise,
withCoalescedInvoke,
} from '../../lib/coalesced-function'
-import { loadDefaultErrorComponents } from '../load-default-error-components'
+import { loadDefaultErrorComponents } from '../load-components'
import { DecodeError, MiddlewareNotFoundError } from '../../shared/lib/utils'
import * as Log from '../../build/output/log'
import isError, { getProperError } from '../../lib/is-error'
diff --git a/packages/next/src/server/dev/static-paths-worker.ts b/packages/next/src/server/dev/static-paths-worker.ts
index ddd6526e52f23..68932df7a36b0 100644
--- a/packages/next/src/server/dev/static-paths-worker.ts
+++ b/packages/next/src/server/dev/static-paths-worker.ts
@@ -14,10 +14,8 @@ import { loadComponents } from '../load-components'
import { setHttpClientAndAgentOptions } from '../setup-http-agent-env'
import { IncrementalCache } from '../lib/incremental-cache'
import * as serverHooks from '../../client/components/hooks-server-context'
-import { staticGenerationAsyncStorage } from '../../client/components/static-generation-async-storage.external'
-
-const { AppRouteRouteModule } =
- require('../future/route-modules/app-route/module.compiled') as typeof import('../future/route-modules/app-route/module')
+import { staticGenerationAsyncStorage } from '../../client/components/static-generation-async-storage'
+import { AppRouteRouteModule } from '../future/route-modules/app-route/module'
type RuntimeConfig = any
@@ -58,7 +56,7 @@ export async function loadStaticPaths({
fallback?: boolean | 'blocking'
}> {
// update work memory runtime-config
- require('../../shared/lib/runtime-config.shared-runtime').setConfig(config)
+ require('../../shared/lib/runtime-config').setConfig(config)
setHttpClientAndAgentOptions({
httpAgentOptions,
})
diff --git a/packages/next/src/server/future/helpers/module-loader/node-module-loader.ts b/packages/next/src/server/future/helpers/module-loader/node-module-loader.ts
index 6f70685df7e75..3283eb00a53f5 100644
--- a/packages/next/src/server/future/helpers/module-loader/node-module-loader.ts
+++ b/packages/next/src/server/future/helpers/module-loader/node-module-loader.ts
@@ -7,10 +7,7 @@ export class NodeModuleLoader implements ModuleLoader {
public async load(id: string): Promise {
if (process.env.NEXT_RUNTIME !== 'edge') {
// Need to `await` to cover the case that route is marked ESM modules by ESM escalation.
- return await (process.env.NEXT_MINIMAL
- ? // @ts-ignore
- __non_webpack_require__(id)
- : require(id))
+ return await require(id)
}
throw new Error('NodeModuleLoader is not supported in edge runtime.')
diff --git a/packages/next/src/server/future/route-modules/app-page/module.compiled.ts b/packages/next/src/server/future/route-modules/app-page/module.compiled.ts
deleted file mode 100644
index 78601739acbe5..0000000000000
--- a/packages/next/src/server/future/route-modules/app-page/module.compiled.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-if (process.env.NEXT_RUNTIME === 'edge') {
- module.exports = require('next/dist/server/future/route-modules/app-page/module.js')
-} else {
- if (process.env.NODE_ENV === 'development') {
- module.exports = require('next/dist/compiled/next-server/app-page.runtime.dev.js')
- } else if (process.env.TURBOPACK) {
- module.exports = require('next/dist/compiled/next-server/app-page-turbo.runtime.prod.js')
- } else {
- module.exports = require('next/dist/compiled/next-server/app-page.runtime.prod.js')
- }
-}
diff --git a/packages/next/src/server/future/route-modules/app-page/module.ts b/packages/next/src/server/future/route-modules/app-page/module.ts
index daa0291a1c8b4..418e37420d7e9 100644
--- a/packages/next/src/server/future/route-modules/app-page/module.ts
+++ b/packages/next/src/server/future/route-modules/app-page/module.ts
@@ -11,7 +11,6 @@ import {
type RouteModuleOptions,
type RouteModuleHandleContext,
} from '../route-module'
-import * as sharedModules from './shared-modules'
type AppPageUserlandModule = {
/**
@@ -35,8 +34,6 @@ export class AppPageRouteModule extends RouteModule<
AppPageRouteDefinition,
AppPageUserlandModule
> {
- static readonly sharedModules = sharedModules
-
public render(
req: IncomingMessage,
res: ServerResponse,
@@ -52,6 +49,4 @@ export class AppPageRouteModule extends RouteModule<
}
}
-export { renderToHTMLOrFlight }
-
export default AppPageRouteModule
diff --git a/packages/next/src/server/future/route-modules/app-page/shared-modules.ts b/packages/next/src/server/future/route-modules/app-page/shared-modules.ts
deleted file mode 100644
index e986c1bad3894..0000000000000
--- a/packages/next/src/server/future/route-modules/app-page/shared-modules.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-// the name of the export has to be the camelCase version of the file name (without the extension)
-export * as headManagerContext from '../../../../shared/lib/head-manager-context.shared-runtime'
-export * as serverInsertedHtml from '../../../../shared/lib/server-inserted-html.shared-runtime'
-export * as appRouterContext from '../../../../shared/lib/app-router-context.shared-runtime'
-export * as hooksClientContext from '../../../../shared/lib/hooks-client-context.shared-runtime'
-export * as routerContext from '../../../../shared/lib/router-context.shared-runtime'
-export * as htmlContext from '../../../../shared/lib/html-context.shared-runtime'
-export * as ampContext from '../../../../shared/lib/amp-context.shared-runtime'
-export * as adapters from '../../../../shared/lib/router/adapters.shared-runtime'
-export * as loadableContext from '../../../../shared/lib/loadable-context.shared-runtime'
-export * as imageConfigContext from '../../../../shared/lib/image-config-context.shared-runtime'
-export * as runtimeConfig from '../../../../shared/lib/runtime-config.shared-runtime'
-export * as loadable from '../../../../shared/lib/loadable.shared-runtime'
diff --git a/packages/next/src/server/future/route-modules/app-route/module.compiled.ts b/packages/next/src/server/future/route-modules/app-route/module.compiled.ts
deleted file mode 100644
index f5909104bc772..0000000000000
--- a/packages/next/src/server/future/route-modules/app-route/module.compiled.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-if (process.env.NEXT_RUNTIME === 'edge') {
- module.exports = require('next/dist/server/future/route-modules/app-route/module.js')
-} else {
- if (process.env.NODE_ENV === 'development') {
- module.exports = require('next/dist/compiled/next-server/app-route.runtime.dev.js')
- } else if (process.env.TURBOPACK) {
- module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.prod.js')
- } else {
- module.exports = require('next/dist/compiled/next-server/app-route.runtime.prod.js')
- }
-}
diff --git a/packages/next/src/server/future/route-modules/app-route/module.ts b/packages/next/src/server/future/route-modules/app-route/module.ts
index d1d36d31501e4..bf47738d35fea 100644
--- a/packages/next/src/server/future/route-modules/app-route/module.ts
+++ b/packages/next/src/server/future/route-modules/app-route/module.ts
@@ -35,14 +35,22 @@ import { appendMutableCookies } from '../../../web/spec-extension/adapters/reque
import { RouteKind } from '../../route-kind'
import { parsedUrlQueryToParams } from './helpers/parsed-url-query-to-params'
-import * as serverHooks from '../../../../client/components/hooks-server-context'
-import * as headerHooks from '../../../../client/components/headers'
-import { staticGenerationBailout } from '../../../../client/components/static-generation-bailout'
-
-import { requestAsyncStorage } from '../../../../client/components/request-async-storage.external'
-import { staticGenerationAsyncStorage } from '../../../../client/components/static-generation-async-storage.external'
-import { actionAsyncStorage } from '../../../../client/components/action-async-storage.external'
-import * as sharedModules from './shared-modules'
+// These are imported weirdly like this because of the way that the bundling
+// works. We need to import the built files from the dist directory, but we
+// can't do that directly because we need types from the source files. So we
+// import the types from the source files and then import the built files.
+const { requestAsyncStorage } =
+ require('next/dist/client/components/request-async-storage') as typeof import('../../../../client/components/request-async-storage')
+const { staticGenerationAsyncStorage } =
+ require('next/dist/client/components/static-generation-async-storage') as typeof import('../../../../client/components/static-generation-async-storage')
+const serverHooks =
+ require('next/dist/client/components/hooks-server-context') as typeof import('../../../../client/components/hooks-server-context')
+const headerHooks =
+ require('next/dist/client/components/headers') as typeof import('../../../../client/components/headers')
+const { staticGenerationBailout } =
+ require('next/dist/client/components/static-generation-bailout') as typeof import('../../../../client/components/static-generation-bailout')
+const { actionAsyncStorage } =
+ require('next/dist/client/components/action-async-storage') as typeof import('../../../../client/components/action-async-storage')
/**
* AppRouteRouteHandlerContext is the context that is passed to the route
@@ -139,8 +147,6 @@ export class AppRouteRouteModule extends RouteModule<
*/
public readonly staticGenerationBailout = staticGenerationBailout
- public static readonly sharedModules = sharedModules
-
/**
* A reference to the mutation related async storage, such as mutations of
* cookies.
diff --git a/packages/next/src/server/future/route-modules/app-route/shared-modules.ts b/packages/next/src/server/future/route-modules/app-route/shared-modules.ts
deleted file mode 100644
index e6139d5a69404..0000000000000
--- a/packages/next/src/server/future/route-modules/app-route/shared-modules.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-// the name of the export has to be the camelCase version of the file name (without the extension)
-// TODO: remove this. We need it because using notFound from next/navigation imports this file :(
-export * as appRouterContext from '../../../../shared/lib/app-router-context.shared-runtime'
diff --git a/packages/next/src/server/future/route-modules/pages-api/module.compiled.ts b/packages/next/src/server/future/route-modules/pages-api/module.compiled.ts
deleted file mode 100644
index ed74c41adb918..0000000000000
--- a/packages/next/src/server/future/route-modules/pages-api/module.compiled.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-if (process.env.NEXT_RUNTIME === 'edge') {
- module.exports = require('next/dist/server/future/route-modules/pages-api/module.js')
-} else {
- if (process.env.NODE_ENV === 'development') {
- module.exports = require('next/dist/compiled/next-server/pages-api.runtime.dev.js')
- } else if (process.env.TURBOPACK) {
- module.exports = require('next/dist/compiled/next-server/pages-api-turbo.runtime.prod.js')
- } else {
- module.exports = require('next/dist/compiled/next-server/pages-api.runtime.prod.js')
- }
-}
diff --git a/packages/next/src/server/future/route-modules/pages-api/module.ts b/packages/next/src/server/future/route-modules/pages-api/module.ts
index 976daeeec4a87..88dbda73b464c 100644
--- a/packages/next/src/server/future/route-modules/pages-api/module.ts
+++ b/packages/next/src/server/future/route-modules/pages-api/module.ts
@@ -100,16 +100,6 @@ export class PagesAPIRouteModule extends RouteModule<
PagesAPIRouteDefinition,
PagesAPIUserlandModule
> {
- constructor(options: PagesAPIRouteModuleOptions) {
- super(options)
-
- if (typeof options.userland.default !== 'function') {
- throw new Error(
- `Page ${options.definition.page} does not export a default function.`
- )
- }
- }
-
/**
*
* @param req the incoming server request
diff --git a/packages/next/src/server/future/route-modules/pages/module.compiled.ts b/packages/next/src/server/future/route-modules/pages/module.compiled.ts
deleted file mode 100644
index a935b62abdcad..0000000000000
--- a/packages/next/src/server/future/route-modules/pages/module.compiled.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-if (process.env.NEXT_RUNTIME === 'edge') {
- module.exports = require('next/dist/server/future/route-modules/pages/module.js')
-} else {
- if (process.env.NODE_ENV === 'development') {
- module.exports = require('next/dist/compiled/next-server/pages.runtime.dev.js')
- } else if (process.env.TURBOPACK) {
- module.exports = require('next/dist/compiled/next-server/pages-turbo.runtime.prod.js')
- } else {
- module.exports = require('next/dist/compiled/next-server/pages.runtime.prod.js')
- }
-}
diff --git a/packages/next/src/server/future/route-modules/pages/module.ts b/packages/next/src/server/future/route-modules/pages/module.ts
index e2730ef668901..dac8ae5546441 100644
--- a/packages/next/src/server/future/route-modules/pages/module.ts
+++ b/packages/next/src/server/future/route-modules/pages/module.ts
@@ -17,8 +17,7 @@ import {
type RouteModuleHandleContext,
type RouteModuleOptions,
} from '../route-module'
-import { renderToHTMLImpl, renderToHTML } from '../../../render'
-import * as sharedModules from './shared-modules'
+import { renderToHTMLImpl } from '../../../render'
/**
* The userland module for a page. This is the module that is exported from the
@@ -105,8 +104,6 @@ export class PagesRouteModule extends RouteModule<
> {
private readonly components: PagesComponents
- static readonly sharedModules = sharedModules
-
constructor(options: PagesRouteModuleOptions) {
super(options)
@@ -132,7 +129,4 @@ export class PagesRouteModule extends RouteModule<
}
}
-// needed for the static build
-export { renderToHTML }
-
export default PagesRouteModule
diff --git a/packages/next/src/server/future/route-modules/pages/shared-modules.ts b/packages/next/src/server/future/route-modules/pages/shared-modules.ts
deleted file mode 100644
index 55cdfbdeca37c..0000000000000
--- a/packages/next/src/server/future/route-modules/pages/shared-modules.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-// the name of the export has to be the camelCase version of the file name (without the extension)
-export * as htmlContext from '../../../../shared/lib/html-context.shared-runtime'
-export * as routerContext from '../../../../shared/lib/router-context.shared-runtime'
-export * as ampContext from '../../../../shared/lib/amp-context.shared-runtime'
-export * as headManagerContext from '../../../../shared/lib/head-manager-context.shared-runtime'
-export * as adapters from '../../../../shared/lib/router/adapters.shared-runtime'
-export * as loadableContext from '../../../../shared/lib/loadable-context.shared-runtime'
-export * as appRouterContext from '../../../../shared/lib/app-router-context.shared-runtime'
-export * as hooksClientContext from '../../../../shared/lib/hooks-client-context.shared-runtime'
-export * as imageConfigContext from '../../../../shared/lib/image-config-context.shared-runtime'
-export * as runtimeConfig from '../../../../shared/lib/runtime-config.shared-runtime'
-export * as loadable from '../../../../shared/lib/loadable.shared-runtime'
diff --git a/packages/next/src/server/future/route-modules/route-module.ts b/packages/next/src/server/future/route-modules/route-module.ts
index a8e5dd6c5945a..52188ed506dff 100644
--- a/packages/next/src/server/future/route-modules/route-module.ts
+++ b/packages/next/src/server/future/route-modules/route-module.ts
@@ -44,11 +44,6 @@ export abstract class RouteModule<
*/
public readonly definition: Readonly
- /**
- * The shared modules that are exposed and required for the route module.
- */
- public static readonly sharedModules: any
-
constructor({ userland, definition }: RouteModuleOptions) {
this.userland = userland
this.definition = definition
diff --git a/packages/next/src/server/internal-utils.ts b/packages/next/src/server/internal-utils.ts
index 1ae559ea09db8..1e712b16379a4 100644
--- a/packages/next/src/server/internal-utils.ts
+++ b/packages/next/src/server/internal-utils.ts
@@ -1,6 +1,8 @@
-import { NEXT_RSC_UNION_QUERY } from '../client/components/app-router-headers'
+import type { IncomingHttpHeaders } from 'http'
import type { NextParsedUrlQuery } from './request-meta'
+import { NEXT_RSC_UNION_QUERY } from '../client/components/app-router-headers'
+
const INTERNAL_QUERY_NAMES = [
'__nextFallback',
'__nextLocale',
@@ -36,3 +38,27 @@ export function stripInternalSearchParams(
return (isStringUrl ? instance.toString() : instance) as T
}
+
+/**
+ * Headers that are set by the Next.js server and should be stripped from the
+ * request headers going to the user's application.
+ */
+const INTERNAL_HEADERS = [
+ 'x-invoke-path',
+ 'x-invoke-status',
+ 'x-invoke-error',
+ 'x-invoke-query',
+ 'x-invoke-output',
+ 'x-middleware-invoke',
+] as const
+
+/**
+ * Strip internal headers from the request headers.
+ *
+ * @param headers the headers to strip of internal headers
+ */
+export function stripInternalHeaders(headers: IncomingHttpHeaders) {
+ for (const key of INTERNAL_HEADERS) {
+ delete headers[key]
+ }
+}
diff --git a/packages/next/src/server/lib/incremental-cache/index.ts b/packages/next/src/server/lib/incremental-cache/index.ts
index 3032aa685300b..ae2b11b4dc00f 100644
--- a/packages/next/src/server/lib/incremental-cache/index.ts
+++ b/packages/next/src/server/lib/incremental-cache/index.ts
@@ -131,10 +131,7 @@ export class IncrementalCache {
maxMemoryCacheSize = parseInt(process.env.__NEXT_TEST_MAX_ISR_CACHE, 10)
}
this.dev = dev
- // this is a hack to avoid Webpack knowing this is equal to this.minimalMode
- // because we replace this.minimalMode to true in production bundles.
- const minimalModeKey = 'minimalMode'
- this[minimalModeKey] = minimalMode
+ this.minimalMode = minimalMode
this.requestHeaders = requestHeaders
this.requestProtocol = requestProtocol
this.allowedRevalidateHeaderKeys = allowedRevalidateHeaderKeys
diff --git a/packages/next/src/server/lib/patch-fetch.ts b/packages/next/src/server/lib/patch-fetch.ts
index 080361704b718..fb4d02c97b251 100644
--- a/packages/next/src/server/lib/patch-fetch.ts
+++ b/packages/next/src/server/lib/patch-fetch.ts
@@ -1,4 +1,4 @@
-import type { StaticGenerationAsyncStorage } from '../../client/components/static-generation-async-storage.external'
+import type { StaticGenerationAsyncStorage } from '../../client/components/static-generation-async-storage'
import type * as ServerHooks from '../../client/components/hooks-server-context'
import { AppRenderSpan, NextNodeServerSpan } from './trace/constants'
diff --git a/packages/next/src/server/lib/router-utils/filesystem.ts b/packages/next/src/server/lib/router-utils/filesystem.ts
index d442b87fff858..270580f1f81a7 100644
--- a/packages/next/src/server/lib/router-utils/filesystem.ts
+++ b/packages/next/src/server/lib/router-utils/filesystem.ts
@@ -249,7 +249,7 @@ export async function setupFsCheck(opts: {
? new RegExp(
route.dataRouteRegex.replace(
`/${escapedBuildId}/`,
- `/${escapedBuildId}/(?.+?)/`
+ `/${escapedBuildId}/(?[^/]+?)/`
)
)
: new RegExp(route.dataRouteRegex),
diff --git a/packages/next/src/server/lib/router-utils/setup-dev.ts b/packages/next/src/server/lib/router-utils/setup-dev.ts
index 2faaf385fa393..cf17fb2d7d9e6 100644
--- a/packages/next/src/server/lib/router-utils/setup-dev.ts
+++ b/packages/next/src/server/lib/router-utils/setup-dev.ts
@@ -1784,7 +1784,7 @@ async function startWatcher(opts: SetupOpts) {
? new RegExp(
route.dataRouteRegex.replace(
`/development/`,
- `/development/(?.+?)/`
+ `/development/(?[^/]+?)/`
)
)
: new RegExp(route.dataRouteRegex),
diff --git a/packages/next/src/server/lib/server-ipc/index.ts b/packages/next/src/server/lib/server-ipc/index.ts
index 023cbde2d25d8..8e7bd60a8855d 100644
--- a/packages/next/src/server/lib/server-ipc/index.ts
+++ b/packages/next/src/server/lib/server-ipc/index.ts
@@ -115,7 +115,6 @@ export const createWorker = async (
__NEXT_PRIVATE_STANDALONE_CONFIG:
process.env.__NEXT_PRIVATE_STANDALONE_CONFIG,
NODE_ENV: process.env.NODE_ENV,
- __NEXT_PRIVATE_RENDER_RUNTIME: type,
__NEXT_PRIVATE_PREBUNDLED_REACT:
type === 'app' ? (useServerActions ? 'experimental' : 'next') : '',
...(process.env.NEXT_CPU_PROF
diff --git a/packages/next/src/server/lib/trace/constants.ts b/packages/next/src/server/lib/trace/constants.ts
index 1b45358bdf8ed..50eb4528c7dec 100644
--- a/packages/next/src/server/lib/trace/constants.ts
+++ b/packages/next/src/server/lib/trace/constants.ts
@@ -43,6 +43,7 @@ enum NextNodeServerSpan {
generatePublicRoutes = 'NextNodeServer.generatePublicRoutes',
generateImageRoutes = 'NextNodeServer.generateImageRoutes.route',
sendRenderResult = 'NextNodeServer.sendRenderResult',
+ sendStatic = 'NextNodeServer.sendStatic',
proxyRequest = 'NextNodeServer.proxyRequest',
runApi = 'NextNodeServer.runApi',
render = 'NextNodeServer.render',
diff --git a/packages/next/src/server/load-components.ts b/packages/next/src/server/load-components.ts
index 39da802ff39b1..d2b563493ebe6 100644
--- a/packages/next/src/server/load-components.ts
+++ b/packages/next/src/server/load-components.ts
@@ -55,7 +55,7 @@ export type LoadComponentsReturnType = {
/**
* Load manifest file with retries, defaults to 3 attempts.
*/
-export async function loadManifestWithRetries(
+async function loadManifestWithRetries(
manifestPath: string,
attempts = 3
): Promise {
@@ -87,6 +87,34 @@ async function loadJSManifest(
}
}
+async function loadDefaultErrorComponentsImpl(
+ distDir: string
+): Promise {
+ const Document = interopDefault(require('next/dist/pages/_document'))
+ const AppMod = require('next/dist/pages/_app')
+ const App = interopDefault(AppMod)
+
+ // Load the compiled route module for this builtin error.
+ // TODO: (wyattjoh) replace this with just exporting the route module when the transition is complete
+ const ComponentMod =
+ require('./future/route-modules/pages/builtin/_error') as typeof import('./future/route-modules/pages/builtin/_error')
+ const Component = ComponentMod.routeModule.userland.default
+
+ return {
+ App,
+ Document,
+ Component,
+ pageConfig: {},
+ buildManifest: await loadManifestWithRetries(
+ join(distDir, `fallback-${BUILD_MANIFEST}`)
+ ),
+ reactLoadableManifest: {},
+ ComponentMod,
+ pathname: '/_error',
+ routeModule: ComponentMod.routeModule,
+ }
+}
+
async function loadComponentsImpl({
distDir,
pathname,
@@ -177,3 +205,8 @@ export const loadComponents = getTracer().wrap(
LoadComponentsSpan.loadComponents,
loadComponentsImpl
)
+
+export const loadDefaultErrorComponents = getTracer().wrap(
+ LoadComponentsSpan.loadDefaultErrorComponents,
+ loadDefaultErrorComponentsImpl
+)
diff --git a/packages/next/src/server/load-default-error-components.ts b/packages/next/src/server/load-default-error-components.ts
deleted file mode 100644
index c390e9180b3d9..0000000000000
--- a/packages/next/src/server/load-default-error-components.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import type {
- AppType,
- DocumentType,
- NextComponentType,
-} from '../shared/lib/utils'
-import type { ClientReferenceManifest } from '../build/webpack/plugins/flight-manifest-plugin'
-import type {
- PageConfig,
- GetStaticPaths,
- GetServerSideProps,
- GetStaticProps,
-} from 'next/types'
-import type { RouteModule } from './future/route-modules/route-module'
-
-import { BUILD_MANIFEST } from '../shared/lib/constants'
-import { join } from 'path'
-import { BuildManifest } from './get-page-files'
-import { interopDefault } from '../lib/interop-default'
-import { getTracer } from './lib/trace/tracer'
-import { LoadComponentsSpan } from './lib/trace/constants'
-import { loadManifestWithRetries } from './load-components'
-export type ManifestItem = {
- id: number | string
- files: string[]
-}
-
-export type ReactLoadableManifest = { [moduleId: string]: ManifestItem }
-
-export type LoadComponentsReturnType = {
- Component: NextComponentType
- pageConfig: PageConfig
- buildManifest: BuildManifest
- subresourceIntegrityManifest?: Record
- reactLoadableManifest: ReactLoadableManifest
- clientReferenceManifest?: ClientReferenceManifest
- serverActionsManifest?: any
- Document: DocumentType
- App: AppType
- getStaticProps?: GetStaticProps
- getStaticPaths?: GetStaticPaths
- getServerSideProps?: GetServerSideProps
- ComponentMod: any
- routeModule?: RouteModule
- isAppPath?: boolean
- pathname: string
-}
-
-async function loadDefaultErrorComponentsImpl(
- distDir: string
-): Promise {
- const Document = interopDefault(require('next/dist/pages/_document'))
- const AppMod = require('next/dist/pages/_app')
- const App = interopDefault(AppMod)
-
- // Load the compiled route module for this builtin error.
- // TODO: (wyattjoh) replace this with just exporting the route module when the transition is complete
- const ComponentMod =
- require('./future/route-modules/pages/builtin/_error') as typeof import('./future/route-modules/pages/builtin/_error')
- const Component = ComponentMod.routeModule.userland.default
-
- return {
- App,
- Document,
- Component,
- pageConfig: {},
- buildManifest: await loadManifestWithRetries(
- join(distDir, `fallback-${BUILD_MANIFEST}`)
- ),
- reactLoadableManifest: {},
- ComponentMod,
- pathname: '/_error',
- routeModule: ComponentMod.routeModule,
- }
-}
-export const loadDefaultErrorComponents = getTracer().wrap(
- LoadComponentsSpan.loadDefaultErrorComponents,
- loadDefaultErrorComponentsImpl
-)
diff --git a/packages/next/src/server/next-server.ts b/packages/next/src/server/next-server.ts
index fe13482eb8b76..d6ad6edaea41d 100644
--- a/packages/next/src/server/next-server.ts
+++ b/packages/next/src/server/next-server.ts
@@ -15,7 +15,7 @@ import {
import type { MiddlewareManifest } from '../build/webpack/plugins/middleware-plugin'
import type RenderResult from './render-result'
import type { FetchEventResult } from './web/types'
-import type { PrerenderManifest } from '../build'
+import type { PrerenderManifest, RoutesManifest } from '../build'
import { BaseNextRequest, BaseNextResponse } from './base-http'
import type { PagesManifest } from '../build/webpack/plugins/pages-manifest-plugin'
import type { PayloadOptions } from './send-payload'
@@ -26,6 +26,7 @@ import {
} from '../shared/lib/router/utils/route-matcher'
import type { MiddlewareRouteMatch } from '../shared/lib/router/utils/middleware-route-matcher'
import type { RouteMatch } from './future/route-matches/route-match'
+import { renderToHTML, type RenderOpts } from './render'
import fs from 'fs'
import { join, resolve, isAbsolute } from 'path'
@@ -48,6 +49,7 @@ import { findDir } from '../lib/find-pages-dir'
import { UrlWithParsedQuery } from 'url'
import { NodeNextRequest, NodeNextResponse } from './base-http/node'
import { sendRenderResult } from './send-payload'
+import { getExtension, serveStatic } from './serve-static'
import { ParsedUrlQuery } from 'querystring'
import { ParsedUrl, parseUrl } from '../shared/lib/router/utils/parse-url'
import * as Log from '../build/output/log'
@@ -94,6 +96,7 @@ import { invokeRequest } from './lib/server-ipc/invoke-request'
import { pipeReadable } from './pipe-readable'
import { filterReqHeaders, ipcForbiddenHeaders } from './lib/server-ipc/utils'
import { createRequestResponseMocks } from './lib/mock-request'
+import chalk from 'next/dist/compiled/chalk'
import { NEXT_RSC_UNION_QUERY } from '../client/components/app-router-headers'
import { signalFromNodeResponse } from './web/spec-extension/adapters/next-request'
import { RouteModuleLoader } from './future/helpers/module-loader/route-module-loader'
@@ -385,6 +388,14 @@ export default class NextNodeServer extends BaseServer {
})
}
+ protected sendStatic(
+ req: NodeNextRequest,
+ res: NodeNextResponse,
+ path: string
+ ): Promise {
+ return serveStatic(req.originalRequest, res.originalResponse, path)
+ }
+
protected async runApi(
req: BaseNextRequest | NodeNextRequest,
res: BaseNextResponse | NodeNextResponse,
@@ -447,7 +458,7 @@ export default class NextNodeServer extends BaseServer {
res: NodeNextResponse,
pathname: string,
query: NextParsedUrlQuery,
- renderOpts: import('./render').RenderOpts
+ renderOpts: RenderOpts
): Promise {
return getTracer().trace(NextNodeServerSpan.renderHTML, async () =>
this.renderHTMLImpl(req, res, pathname, query, renderOpts)
@@ -459,35 +470,17 @@ export default class NextNodeServer extends BaseServer {
res: NodeNextResponse,
pathname: string,
query: NextParsedUrlQuery,
- renderOpts: import('./render').RenderOpts
+ renderOpts: RenderOpts
): Promise {
- if (process.env.NEXT_MINIMAL) {
- throw new Error(
- 'invariant: renderHTML should not be called in minimal mode'
- )
- // the `else` branch is needed for tree-shaking
- } else {
- // Due to the way we pass data by mutating `renderOpts`, we can't extend the
- // object here but only updating its `nextFontManifest` field.
- // https://github.com/vercel/next.js/blob/df7cbd904c3bd85f399d1ce90680c0ecf92d2752/packages/next/server/render.tsx#L947-L952
- renderOpts.nextFontManifest = this.nextFontManifest
-
- if (this.hasAppDir && renderOpts.isAppPath) {
- const { renderToHTMLOrFlight: appRenderToHTMLOrFlight } =
- require('./future/route-modules/app-page/module.compiled') as typeof import('./app-render/app-render')
- return appRenderToHTMLOrFlight(
- req.originalRequest,
- res.originalResponse,
- pathname,
- query,
- renderOpts
- )
- }
-
- // TODO: re-enable this once we've refactored to use implicit matches
- // throw new Error('Invariant: render should have used routeModule')
-
- return require('./future/route-modules/pages/module.compiled').renderToHTML(
+ // Due to the way we pass data by mutating `renderOpts`, we can't extend the
+ // object here but only updating its `nextFontManifest` field.
+ // https://github.com/vercel/next.js/blob/df7cbd904c3bd85f399d1ce90680c0ecf92d2752/packages/next/server/render.tsx#L947-L952
+ renderOpts.nextFontManifest = this.nextFontManifest
+
+ if (this.hasAppDir && renderOpts.isAppPath) {
+ const { renderToHTMLOrFlight: appRenderToHTMLOrFlight } =
+ require('./app-render/app-render') as typeof import('./app-render/app-render')
+ return appRenderToHTMLOrFlight(
req.originalRequest,
res.originalResponse,
pathname,
@@ -495,6 +488,17 @@ export default class NextNodeServer extends BaseServer {
renderOpts
)
}
+
+ // TODO: re-enable this once we've refactored to use implicit matches
+ // throw new Error('Invariant: render should have used routeModule')
+
+ return renderToHTML(
+ req.originalRequest,
+ res.originalResponse,
+ pathname,
+ query,
+ renderOpts
+ )
}
protected async imageOptimizer(
@@ -502,63 +506,55 @@ export default class NextNodeServer extends BaseServer {
res: NodeNextResponse,
paramsResult: import('./image-optimizer').ImageParamsResult
): Promise<{ buffer: Buffer; contentType: string; maxAge: number }> {
- if (process.env.NEXT_MINIMAL) {
- throw new Error(
- 'invariant: imageOptimizer should not be called in minimal mode'
- )
- } else {
- const { imageOptimizer } =
- require('./image-optimizer') as typeof import('./image-optimizer')
-
- return imageOptimizer(
- req.originalRequest,
- res.originalResponse,
- paramsResult,
- this.nextConfig,
- this.renderOpts.dev,
- async (newReq, newRes, newParsedUrl) => {
- if (newReq.url === req.url) {
- throw new Error(
- `Invariant attempted to optimize _next/image itself`
- )
- }
+ const { imageOptimizer } =
+ require('./image-optimizer') as typeof import('./image-optimizer')
+
+ return imageOptimizer(
+ req.originalRequest,
+ res.originalResponse,
+ paramsResult,
+ this.nextConfig,
+ this.renderOpts.dev,
+ async (newReq, newRes, newParsedUrl) => {
+ if (newReq.url === req.url) {
+ throw new Error(`Invariant attempted to optimize _next/image itself`)
+ }
- if (this.isRenderWorker) {
- const invokeRes = await invokeRequest(
- `http://${this.fetchHostname || 'localhost'}:${this.port}${
- newReq.url || ''
- }`,
- {
- method: newReq.method || 'GET',
- headers: newReq.headers,
- signal: signalFromNodeResponse(res.originalResponse),
- }
- )
- const filteredResHeaders = filterReqHeaders(
- toNodeOutgoingHttpHeaders(invokeRes.headers),
- ipcForbiddenHeaders
- )
-
- for (const key of Object.keys(filteredResHeaders)) {
- newRes.setHeader(key, filteredResHeaders[key] || '')
+ if (this.isRenderWorker) {
+ const invokeRes = await invokeRequest(
+ `http://${this.fetchHostname || 'localhost'}:${this.port}${
+ newReq.url || ''
+ }`,
+ {
+ method: newReq.method || 'GET',
+ headers: newReq.headers,
+ signal: signalFromNodeResponse(res.originalResponse),
}
- newRes.statusCode = invokeRes.status || 200
+ )
+ const filteredResHeaders = filterReqHeaders(
+ toNodeOutgoingHttpHeaders(invokeRes.headers),
+ ipcForbiddenHeaders
+ )
- if (invokeRes.body) {
- await pipeReadable(invokeRes.body, newRes)
- } else {
- res.send()
- }
- return
+ for (const key of Object.keys(filteredResHeaders)) {
+ newRes.setHeader(key, filteredResHeaders[key] || '')
}
- return this.getRequestHandler()(
- new NodeNextRequest(newReq),
- new NodeNextResponse(newRes),
- newParsedUrl
- )
+ newRes.statusCode = invokeRes.status || 200
+
+ if (invokeRes.body) {
+ await pipeReadable(invokeRes.body, newRes)
+ } else {
+ res.send()
+ }
+ return
}
- )
- }
+ return this.getRequestHandler()(
+ new NodeNextRequest(newReq),
+ new NodeNextResponse(newRes),
+ newParsedUrl
+ )
+ }
+ )
}
protected getPagePath(pathname: string, locales?: string[]): string {
@@ -729,109 +725,99 @@ export default class NextNodeServer extends BaseServer {
res: BaseNextResponse,
parsedUrl: NextUrlWithParsedQuery
) {
- if (
- this.minimalMode ||
- this.nextConfig.output === 'export' ||
- process.env.NEXT_MINIMAL
- ) {
+ if (this.minimalMode || this.nextConfig.output === 'export') {
res.statusCode = 400
res.body('Bad Request').send()
return {
finished: true,
}
- // the `else` branch is needed for tree-shaking
- } else {
- const { ImageOptimizerCache } =
- require('./image-optimizer') as typeof import('./image-optimizer')
-
- const imageOptimizerCache = new ImageOptimizerCache({
- distDir: this.distDir,
- nextConfig: this.nextConfig,
- })
+ }
+ const { ImageOptimizerCache } =
+ require('./image-optimizer') as typeof import('./image-optimizer')
- const { getHash, sendResponse, ImageError } =
- require('./image-optimizer') as typeof import('./image-optimizer')
+ const imageOptimizerCache = new ImageOptimizerCache({
+ distDir: this.distDir,
+ nextConfig: this.nextConfig,
+ })
- if (!this.imageResponseCache) {
- throw new Error('invariant image optimizer cache was not initialized')
- }
- const imagesConfig = this.nextConfig.images
+ const { getHash, sendResponse, ImageError } =
+ require('./image-optimizer') as typeof import('./image-optimizer')
- if (imagesConfig.loader !== 'default' || imagesConfig.unoptimized) {
- await this.render404(req, res)
- return { finished: true }
- }
- const paramsResult = ImageOptimizerCache.validateParams(
- (req as NodeNextRequest).originalRequest,
- parsedUrl.query,
- this.nextConfig,
- !!this.renderOpts.dev
- )
+ if (!this.imageResponseCache) {
+ throw new Error('invariant image optimizer cache was not initialized')
+ }
+ const imagesConfig = this.nextConfig.images
- if ('errorMessage' in paramsResult) {
- res.statusCode = 400
- res.body(paramsResult.errorMessage).send()
- return { finished: true }
- }
- const cacheKey = ImageOptimizerCache.getCacheKey(paramsResult)
+ if (imagesConfig.loader !== 'default' || imagesConfig.unoptimized) {
+ await this.render404(req, res)
+ return { finished: true }
+ }
+ const paramsResult = ImageOptimizerCache.validateParams(
+ (req as NodeNextRequest).originalRequest,
+ parsedUrl.query,
+ this.nextConfig,
+ !!this.renderOpts.dev
+ )
- try {
- const { getExtension } =
- require('./serve-static') as typeof import('./serve-static')
- const cacheEntry = await this.imageResponseCache.get(
- cacheKey,
- async () => {
- const { buffer, contentType, maxAge } = await this.imageOptimizer(
- req as NodeNextRequest,
- res as NodeNextResponse,
- paramsResult
- )
- const etag = getHash([buffer])
-
- return {
- value: {
- kind: 'IMAGE',
- buffer,
- etag,
- extension: getExtension(contentType) as string,
- },
- revalidate: maxAge,
- }
- },
- {
- incrementalCache: imageOptimizerCache,
- }
- )
+ if ('errorMessage' in paramsResult) {
+ res.statusCode = 400
+ res.body(paramsResult.errorMessage).send()
+ return { finished: true }
+ }
+ const cacheKey = ImageOptimizerCache.getCacheKey(paramsResult)
- if (cacheEntry?.value?.kind !== 'IMAGE') {
- throw new Error(
- 'invariant did not get entry from image response cache'
+ try {
+ const cacheEntry = await this.imageResponseCache.get(
+ cacheKey,
+ async () => {
+ const { buffer, contentType, maxAge } = await this.imageOptimizer(
+ req as NodeNextRequest,
+ res as NodeNextResponse,
+ paramsResult
)
- }
- sendResponse(
- (req as NodeNextRequest).originalRequest,
- (res as NodeNextResponse).originalResponse,
- paramsResult.href,
- cacheEntry.value.extension,
- cacheEntry.value.buffer,
- paramsResult.isStatic,
- cacheEntry.isMiss ? 'MISS' : cacheEntry.isStale ? 'STALE' : 'HIT',
- imagesConfig,
- cacheEntry.revalidate || 0,
- Boolean(this.renderOpts.dev)
- )
- } catch (err) {
- if (err instanceof ImageError) {
- res.statusCode = err.statusCode
- res.body(err.message).send()
+ const etag = getHash([buffer])
+
return {
- finished: true,
+ value: {
+ kind: 'IMAGE',
+ buffer,
+ etag,
+ extension: getExtension(contentType) as string,
+ },
+ revalidate: maxAge,
}
+ },
+ {
+ incrementalCache: imageOptimizerCache,
}
- throw err
+ )
+
+ if (cacheEntry?.value?.kind !== 'IMAGE') {
+ throw new Error('invariant did not get entry from image response cache')
}
- return { finished: true }
+ sendResponse(
+ (req as NodeNextRequest).originalRequest,
+ (res as NodeNextResponse).originalResponse,
+ paramsResult.href,
+ cacheEntry.value.extension,
+ cacheEntry.value.buffer,
+ paramsResult.isStatic,
+ cacheEntry.isMiss ? 'MISS' : cacheEntry.isStale ? 'STALE' : 'HIT',
+ imagesConfig,
+ cacheEntry.revalidate || 0,
+ Boolean(this.renderOpts.dev)
+ )
+ } catch (err) {
+ if (err instanceof ImageError) {
+ res.statusCode = err.statusCode
+ res.body(err.message).send()
+ return {
+ finished: true,
+ }
+ }
+ throw err
}
+ return { finished: true }
}
protected async handleCatchallRenderRequest(
@@ -1034,7 +1020,6 @@ export default class NextNodeServer extends BaseServer {
const shouldTruncateUrl = !this.nextConfig.experimental.logging?.fullUrl
if (this.renderOpts.dev) {
- const chalk = require('next/dist/compiled/chalk')
const _req = req as NodeNextRequest | IncomingMessage
const _res = res as NodeNextResponse | ServerResponse
const origReq = 'originalRequest' in _req ? _req.originalRequest : _req
@@ -1453,12 +1438,6 @@ export default class NextNodeServer extends BaseServer {
parsed: UrlWithParsedQuery
onWarning?: (warning: Error) => void
}) {
- if (process.env.NEXT_MINIMAL) {
- throw new Error(
- 'invariant: runMiddleware should not be called in minimal mode'
- )
- }
-
// Middleware is skipped for on-demand revalidate requests
if (
checkIsOnDemandRevalidate(params.request, this.renderOpts.previewProps)
@@ -1612,6 +1591,9 @@ export default class NextNodeServer extends BaseServer {
ReturnType
>
+ // Strip the internal headers.
+ this.stripInternalHeaders(req)
+
try {
await this.ensureMiddleware()
@@ -1702,7 +1684,10 @@ export default class NextNodeServer extends BaseServer {
protected getRoutesManifest(): NormalizedRouteManifest | undefined {
return getTracer().trace(NextNodeServerSpan.getRoutesManifest, () => {
- const manifest = loadManifest(join(this.distDir, ROUTES_MANIFEST))
+ const manifest: RoutesManifest = require(join(
+ this.distDir,
+ ROUTES_MANIFEST
+ ))
let rewrites = manifest.rewrites ?? {
beforeFiles: [],
@@ -1760,11 +1745,6 @@ export default class NextNodeServer extends BaseServer {
match?: RouteMatch
onWarning?: (warning: Error) => void
}): Promise {
- if (process.env.NEXT_MINIMAL) {
- throw new Error(
- 'Middleware is not supported in minimal mode. Please remove the `NEXT_MINIMAL` environment variable.'
- )
- }
let edgeInfo: ReturnType | undefined
const { query, page, match } = params
diff --git a/packages/next/src/server/render-result.ts b/packages/next/src/server/render-result.ts
index 2a8252e4fd143..b93dfce5fae21 100644
--- a/packages/next/src/server/render-result.ts
+++ b/packages/next/src/server/render-result.ts
@@ -1,4 +1,4 @@
-import { StaticGenerationStore } from '../client/components/static-generation-async-storage.external'
+import { StaticGenerationStore } from '../client/components/static-generation-async-storage'
import { pipeReadable, PipeTarget } from './pipe-readable'
type ContentTypeOption = string | undefined
diff --git a/packages/next/src/server/render.tsx b/packages/next/src/server/render.tsx
index fe36e793348e2..ac0989082aa9b 100644
--- a/packages/next/src/server/render.tsx
+++ b/packages/next/src/server/render.tsx
@@ -1,7 +1,7 @@
import type { IncomingMessage, ServerResponse } from 'http'
import type { ParsedUrlQuery } from 'querystring'
import type { NextRouter } from '../shared/lib/router/router'
-import type { HtmlProps } from '../shared/lib/html-context.shared-runtime'
+import type { HtmlProps } from '../shared/lib/html-context'
import type { DomainLocale } from './config'
import type {
AppType,
@@ -52,12 +52,12 @@ import {
} from '../shared/lib/constants'
import { isSerializableProps } from '../lib/is-serializable-props'
import { isInAmpMode } from '../shared/lib/amp-mode'
-import { AmpStateContext } from '../shared/lib/amp-context.shared-runtime'
+import { AmpStateContext } from '../shared/lib/amp-context'
import { defaultHead } from '../shared/lib/head'
-import { HeadManagerContext } from '../shared/lib/head-manager-context.shared-runtime'
-import Loadable from '../shared/lib/loadable.shared-runtime'
-import { LoadableContext } from '../shared/lib/loadable-context.shared-runtime'
-import { RouterContext } from '../shared/lib/router-context.shared-runtime'
+import { HeadManagerContext } from '../shared/lib/head-manager-context'
+import Loadable from '../shared/lib/loadable'
+import { LoadableContext } from '../shared/lib/loadable-context'
+import { RouterContext } from '../shared/lib/router-context'
import { isDynamicRoute } from '../shared/lib/router/utils/is-dynamic'
import {
ComponentsEnhancer,
@@ -65,7 +65,7 @@ import {
isResSent,
loadGetInitialProps,
} from '../shared/lib/utils'
-import { HtmlContext } from '../shared/lib/html-context.shared-runtime'
+import { HtmlContext } from '../shared/lib/html-context'
import { normalizePagePath } from '../shared/lib/page-path/normalize-page-path'
import { denormalizePagePath } from '../shared/lib/page-path/denormalize-page-path'
import { getRequestMeta, NextParsedUrlQuery } from './request-meta'
@@ -79,16 +79,16 @@ import {
renderToInitialStream,
continueFromInitialStream,
} from './stream-utils/node-web-streams-helper'
-import { ImageConfigContext } from '../shared/lib/image-config-context.shared-runtime'
+import { ImageConfigContext } from '../shared/lib/image-config-context'
import stripAnsi from 'next/dist/compiled/strip-ansi'
import { stripInternalQueries } from './internal-utils'
import {
adaptForAppRouterInstance,
adaptForSearchParams,
PathnameContextProviderAdapter,
-} from '../shared/lib/router/adapters.shared-runtime'
-import { AppRouterContext } from '../shared/lib/app-router-context.shared-runtime'
-import { SearchParamsContext } from '../shared/lib/hooks-client-context.shared-runtime'
+} from '../shared/lib/router/adapters'
+import { AppRouterContext } from '../shared/lib/app-router-context'
+import { SearchParamsContext } from '../shared/lib/hooks-client-context'
import { getTracer } from './lib/trace/tracer'
import { RenderSpan } from './lib/trace/constants'
import { ReflectAdapter } from './web/spec-extension/adapters/reflect'
diff --git a/packages/next/src/server/require-hook.ts b/packages/next/src/server/require-hook.ts
index 9b2e1526eec0e..1f53b3b479109 100644
--- a/packages/next/src/server/require-hook.ts
+++ b/packages/next/src/server/require-hook.ts
@@ -2,13 +2,11 @@
// This is needed for userland plugins to attach to the same webpack instance as Next.js'.
// Individually compiled modules are as defined for the compilation in bundles/webpack/packages/*.
-import path, { dirname } from 'path'
-
// This module will only be loaded once per process.
+const { dirname } = require('path')
const mod = require('module')
const resolveFilename = mod._resolveFilename
-const originalRequire = mod.prototype.require
const hookPropertyMap = new Map()
let aliasedPrebundledReact = false
@@ -21,9 +19,10 @@ const resolve = process.env.NEXT_MINIMAL
const toResolveMap = (map: Record): [string, string][] =>
Object.entries(map).map(([key, value]) => [key, resolve(value)])
+// these must use require.resolve to be statically analyzable
export const defaultOverrides = {
- 'styled-jsx': dirname(resolve('styled-jsx/package.json')),
- 'styled-jsx/style': resolve('styled-jsx/style'),
+ 'styled-jsx': dirname(require.resolve('styled-jsx/package.json')),
+ 'styled-jsx/style': require.resolve('styled-jsx/style'),
}
export const baseOverrides = {
@@ -79,6 +78,7 @@ export function addHookAliases(aliases: [string, string][] = []) {
}
}
+// Add default aliases
addHookAliases(toResolveMap(defaultOverrides))
// Override built-in React packages if necessary
@@ -117,29 +117,3 @@ mod._resolveFilename = function (
// We use `bind` here to avoid referencing outside variables to create potential memory leaks.
}.bind(null, resolveFilename, hookPropertyMap)
-
-// This is a hack to make sure that if a user requires a Next.js module that wasn't bundled
-// that needs to point to the rendering runtime version, it will point to the correct one.
-// This can happen on `pages` when a user requires a dependency that uses next/image for example.
-// This is only needed in production as in development we fallback to the external version.
-if (
- process.env.NODE_ENV !== 'development' &&
- process.env.__NEXT_PRIVATE_RENDER_RUNTIME &&
- !process.env.TURBOPACK
-) {
- const currentRuntime = `${
- process.env.__NEXT_PRIVATE_RENDER_RUNTIME === 'pages'
- ? 'next/dist/compiled/next-server/pages.runtime'
- : 'next/dist/compiled/next-server/app-page.runtime'
- }.prod`
-
- mod.prototype.require = function (request: string) {
- if (request.endsWith('.shared-runtime')) {
- const base = path.basename(request, '.shared-runtime')
- const camelized = base.replace(/-([a-z])/g, (g) => g[1].toUpperCase())
- const instance = originalRequire.call(this, currentRuntime)
- return instance.default.sharedModules[camelized]
- }
- return originalRequire.call(this, request)
- }
-}
diff --git a/packages/next/src/server/response-cache/index.ts b/packages/next/src/server/response-cache/index.ts
index 7bd6710cc4a80..6d135da26e939 100644
--- a/packages/next/src/server/response-cache/index.ts
+++ b/packages/next/src/server/response-cache/index.ts
@@ -20,10 +20,7 @@ export default class ResponseCache {
constructor(minimalMode: boolean) {
this.pendingResponses = new Map()
- // this is a hack to avoid Webpack knowing this is equal to this.minimalMode
- // because we replace this.minimalMode to true in production bundles.
- const minimalModeKey = 'minimalMode'
- this[minimalModeKey] = minimalMode
+ this.minimalMode = minimalMode
}
public get(
diff --git a/packages/next/src/server/response-cache/web.ts b/packages/next/src/server/response-cache/web.ts
index f255fdd5412d4..e37ccca314812 100644
--- a/packages/next/src/server/response-cache/web.ts
+++ b/packages/next/src/server/response-cache/web.ts
@@ -15,9 +15,7 @@ export default class WebResponseCache {
constructor(minimalMode: boolean) {
this.pendingResponses = new Map()
- // this is a hack to avoid Webpack knowing this is equal to this.minimalMode
- // because we replace this.minimalMode to true in production bundles.
- Object.assign(this, { minimalMode })
+ this.minimalMode = minimalMode
}
public get(
diff --git a/packages/next/src/server/web/adapter.ts b/packages/next/src/server/web/adapter.ts
index 5c6ad3e7ed5ab..1ea32a75956cd 100644
--- a/packages/next/src/server/web/adapter.ts
+++ b/packages/next/src/server/web/adapter.ts
@@ -18,7 +18,7 @@ import {
import { NEXT_QUERY_PARAM_PREFIX } from '../../lib/constants'
import { ensureInstrumentationRegistered } from './globals'
import { RequestAsyncStorageWrapper } from '../async-storage/request-async-storage-wrapper'
-import { requestAsyncStorage } from '../../client/components/request-async-storage.external'
+import { requestAsyncStorage } from '../../client/components/request-async-storage'
import { PrerenderManifest } from '../../build'
class NextRequestHint extends NextRequest {
diff --git a/packages/next/src/server/web/spec-extension/adapters/request-cookies.ts b/packages/next/src/server/web/spec-extension/adapters/request-cookies.ts
index d44ea986cad65..df3c369eef877 100644
--- a/packages/next/src/server/web/spec-extension/adapters/request-cookies.ts
+++ b/packages/next/src/server/web/spec-extension/adapters/request-cookies.ts
@@ -1,5 +1,5 @@
import type { RequestCookies } from '../cookies'
-import { StaticGenerationStore } from '../../../../client/components/static-generation-async-storage.external'
+import { StaticGenerationStore } from '../../../../client/components/static-generation-async-storage'
import { ResponseCookies } from '../cookies'
import { ReflectAdapter } from './reflect'
diff --git a/packages/next/src/server/web/spec-extension/response.ts b/packages/next/src/server/web/spec-extension/response.ts
index 18fa7158c5adc..86b09e3616a83 100644
--- a/packages/next/src/server/web/spec-extension/response.ts
+++ b/packages/next/src/server/web/spec-extension/response.ts
@@ -71,7 +71,6 @@ export class NextResponse extends Response {
body: JsonBody,
init?: ResponseInit
): NextResponse {
- // @ts-expect-error This is not in lib/dom right now, and we can't augment it.
const response: Response = Response.json(body, init)
return new NextResponse(response.body, response)
}
diff --git a/packages/next/src/server/web/spec-extension/revalidate-tag.ts b/packages/next/src/server/web/spec-extension/revalidate-tag.ts
index 7c7bff8c2f784..8d7cd68bd3a9a 100644
--- a/packages/next/src/server/web/spec-extension/revalidate-tag.ts
+++ b/packages/next/src/server/web/spec-extension/revalidate-tag.ts
@@ -1,7 +1,7 @@
import {
StaticGenerationAsyncStorage,
StaticGenerationStore,
-} from '../../../client/components/static-generation-async-storage.external'
+} from '../../../client/components/static-generation-async-storage'
export function revalidateTag(tag: string) {
const staticGenerationAsyncStorage = (
diff --git a/packages/next/src/server/web/spec-extension/unstable-cache.ts b/packages/next/src/server/web/spec-extension/unstable-cache.ts
index 1e85b5c290971..aad3ed2baf20a 100644
--- a/packages/next/src/server/web/spec-extension/unstable-cache.ts
+++ b/packages/next/src/server/web/spec-extension/unstable-cache.ts
@@ -2,7 +2,7 @@ import {
StaticGenerationStore,
staticGenerationAsyncStorage as _staticGenerationAsyncStorage,
StaticGenerationAsyncStorage,
-} from '../../../client/components/static-generation-async-storage.external'
+} from '../../../client/components/static-generation-async-storage'
import { CACHE_ONE_YEAR } from '../../../lib/constants'
import { addImplicitTags } from '../../lib/patch-fetch'
diff --git a/packages/next/src/shared/lib/amp-context.shared-runtime.ts b/packages/next/src/shared/lib/amp-context.ts
similarity index 100%
rename from packages/next/src/shared/lib/amp-context.shared-runtime.ts
rename to packages/next/src/shared/lib/amp-context.ts
diff --git a/packages/next/src/shared/lib/amp.ts b/packages/next/src/shared/lib/amp.ts
index 8edd21db9c299..04518b2389357 100644
--- a/packages/next/src/shared/lib/amp.ts
+++ b/packages/next/src/shared/lib/amp.ts
@@ -1,5 +1,5 @@
import React from 'react'
-import { AmpStateContext } from './amp-context.shared-runtime'
+import { AmpStateContext } from './amp-context'
import { isInAmpMode } from './amp-mode'
export function useAmp(): boolean {
diff --git a/packages/next/src/shared/lib/app-router-context.shared-runtime.ts b/packages/next/src/shared/lib/app-router-context.ts
similarity index 100%
rename from packages/next/src/shared/lib/app-router-context.shared-runtime.ts
rename to packages/next/src/shared/lib/app-router-context.ts
diff --git a/packages/next/src/shared/lib/dynamic.tsx b/packages/next/src/shared/lib/dynamic.tsx
index 390410edda29e..cb497fc587d4f 100644
--- a/packages/next/src/shared/lib/dynamic.tsx
+++ b/packages/next/src/shared/lib/dynamic.tsx
@@ -1,5 +1,5 @@
import React from 'react'
-import Loadable from './loadable.shared-runtime'
+import Loadable from './loadable'
const isServerSide = typeof window === 'undefined'
diff --git a/packages/next/src/shared/lib/head-manager-context.shared-runtime.ts b/packages/next/src/shared/lib/head-manager-context.ts
similarity index 100%
rename from packages/next/src/shared/lib/head-manager-context.shared-runtime.ts
rename to packages/next/src/shared/lib/head-manager-context.ts
diff --git a/packages/next/src/shared/lib/head.tsx b/packages/next/src/shared/lib/head.tsx
index 42f95767bfa4c..3156e259f656f 100644
--- a/packages/next/src/shared/lib/head.tsx
+++ b/packages/next/src/shared/lib/head.tsx
@@ -2,8 +2,8 @@
import React, { useContext } from 'react'
import Effect from './side-effect'
-import { AmpStateContext } from './amp-context.shared-runtime'
-import { HeadManagerContext } from './head-manager-context.shared-runtime'
+import { AmpStateContext } from './amp-context'
+import { HeadManagerContext } from './head-manager-context'
import { isInAmpMode } from './amp-mode'
import { warnOnce } from './utils/warn-once'
diff --git a/packages/next/src/shared/lib/hooks-client-context.shared-runtime.ts b/packages/next/src/shared/lib/hooks-client-context.ts
similarity index 100%
rename from packages/next/src/shared/lib/hooks-client-context.shared-runtime.ts
rename to packages/next/src/shared/lib/hooks-client-context.ts
diff --git a/packages/next/src/shared/lib/html-context.shared-runtime.ts b/packages/next/src/shared/lib/html-context.ts
similarity index 100%
rename from packages/next/src/shared/lib/html-context.shared-runtime.ts
rename to packages/next/src/shared/lib/html-context.ts
diff --git a/packages/next/src/shared/lib/image-config-context.shared-runtime.ts b/packages/next/src/shared/lib/image-config-context.ts
similarity index 100%
rename from packages/next/src/shared/lib/image-config-context.shared-runtime.ts
rename to packages/next/src/shared/lib/image-config-context.ts
diff --git a/packages/next/src/shared/lib/loadable-context.shared-runtime.ts b/packages/next/src/shared/lib/loadable-context.ts
similarity index 100%
rename from packages/next/src/shared/lib/loadable-context.shared-runtime.ts
rename to packages/next/src/shared/lib/loadable-context.ts
diff --git a/packages/next/src/shared/lib/loadable.shared-runtime.tsx b/packages/next/src/shared/lib/loadable.tsx
similarity index 99%
rename from packages/next/src/shared/lib/loadable.shared-runtime.tsx
rename to packages/next/src/shared/lib/loadable.tsx
index 82ba84182701f..1592d98551093 100644
--- a/packages/next/src/shared/lib/loadable.shared-runtime.tsx
+++ b/packages/next/src/shared/lib/loadable.tsx
@@ -23,7 +23,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
// Modified to be compatible with webpack 4 / Next.js
import React from 'react'
-import { LoadableContext } from './loadable-context.shared-runtime'
+import { LoadableContext } from './loadable-context'
function resolve(obj: any) {
return obj && obj.default ? obj.default : obj
diff --git a/packages/next/src/shared/lib/router-context.shared-runtime.ts b/packages/next/src/shared/lib/router-context.ts
similarity index 100%
rename from packages/next/src/shared/lib/router-context.shared-runtime.ts
rename to packages/next/src/shared/lib/router-context.ts
diff --git a/packages/next/src/shared/lib/router/adapters.test.tsx b/packages/next/src/shared/lib/router/adapters.test.tsx
index e47ce2174dd35..fa8e48f2fc088 100644
--- a/packages/next/src/shared/lib/router/adapters.test.tsx
+++ b/packages/next/src/shared/lib/router/adapters.test.tsx
@@ -1,4 +1,4 @@
-import { adaptForAppRouterInstance } from './adapters.shared-runtime'
+import { adaptForAppRouterInstance } from './adapters'
import { NextRouter } from './router'
describe('adaptForAppRouterInstance', () => {
diff --git a/packages/next/src/shared/lib/router/adapters.shared-runtime.tsx b/packages/next/src/shared/lib/router/adapters.tsx
similarity index 95%
rename from packages/next/src/shared/lib/router/adapters.shared-runtime.tsx
rename to packages/next/src/shared/lib/router/adapters.tsx
index 29f92dda8dc08..ce68a8bec1e8b 100644
--- a/packages/next/src/shared/lib/router/adapters.shared-runtime.tsx
+++ b/packages/next/src/shared/lib/router/adapters.tsx
@@ -1,10 +1,7 @@
import type { ParsedUrlQuery } from 'node:querystring'
import React, { useMemo, useRef } from 'react'
-import type {
- AppRouterInstance,
- NavigateOptions,
-} from '../app-router-context.shared-runtime'
-import { PathnameContext } from '../hooks-client-context.shared-runtime'
+import type { AppRouterInstance, NavigateOptions } from '../app-router-context'
+import { PathnameContext } from '../hooks-client-context'
import type { NextRouter } from './router'
import { isDynamicRoute } from './utils'
diff --git a/packages/next/src/shared/lib/runtime-config.shared-runtime.ts b/packages/next/src/shared/lib/runtime-config.ts
similarity index 100%
rename from packages/next/src/shared/lib/runtime-config.shared-runtime.ts
rename to packages/next/src/shared/lib/runtime-config.ts
diff --git a/packages/next/src/shared/lib/server-inserted-html.shared-runtime.tsx b/packages/next/src/shared/lib/server-inserted-html.tsx
similarity index 100%
rename from packages/next/src/shared/lib/server-inserted-html.shared-runtime.tsx
rename to packages/next/src/shared/lib/server-inserted-html.tsx
diff --git a/packages/next/src/shared/lib/utils.ts b/packages/next/src/shared/lib/utils.ts
index 4e8036a6894a2..f967be459022b 100644
--- a/packages/next/src/shared/lib/utils.ts
+++ b/packages/next/src/shared/lib/utils.ts
@@ -1,4 +1,4 @@
-import type { HtmlProps } from './html-context.shared-runtime'
+import type { HtmlProps } from './html-context'
import type { ComponentType } from 'react'
import type { DomainLocale } from '../../server/config'
import type { Env } from '@next/env'
diff --git a/packages/next/src/trace/index.ts b/packages/next/src/trace/index.ts
index e3928f775f613..e242e19c9041f 100644
--- a/packages/next/src/trace/index.ts
+++ b/packages/next/src/trace/index.ts
@@ -1,5 +1,4 @@
import { trace, flushAllTraces, Span, SpanStatus } from './trace'
import { SpanId, setGlobal } from './shared'
-export { trace, flushAllTraces, Span, setGlobal, SpanStatus }
-export type { SpanId }
+export { trace, flushAllTraces, SpanId, Span, SpanStatus, setGlobal }
diff --git a/packages/next/taskfile-webpack.js b/packages/next/taskfile-webpack.js
deleted file mode 100644
index 04495d7b3621c..0000000000000
--- a/packages/next/taskfile-webpack.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const webpack = require('webpack')
-
-module.exports = function (task) {
- task.plugin('webpack', {}, function* (_, options) {
- options = options || {}
-
- const compiler = webpack(options.config)
-
- if (options.watch) {
- compiler.watch({}, (err, stats) => {
- if (err || stats.hasErrors()) {
- console.error(err || stats.toString())
- } else {
- console.log(`${options.name} compiled successfully.`)
- }
- })
- } else {
- yield new Promise((resolve, reject) => {
- compiler.run((err, stats) => {
- if (err || stats.hasErrors()) {
- console.error(err || stats.toString())
- reject(err || stats.toString())
- }
- if (process.env.ANALYZE) {
- require('fs').writeFileSync(
- require('path').join(__dirname, options.name + '-stats.json'),
- JSON.stringify(stats.toJson())
- )
- }
- resolve()
- })
- })
- }
- })
-}
diff --git a/packages/next/taskfile.js b/packages/next/taskfile.js
index 321490234153b..f38289c3d4984 100644
--- a/packages/next/taskfile.js
+++ b/packages/next/taskfile.js
@@ -2357,7 +2357,7 @@ export async function ncc(task, opts) {
)
}
-export async function next_compile(task, opts) {
+export async function compile(task, opts) {
await task.parallel(
[
'cli',
@@ -2388,16 +2388,12 @@ export async function next_compile(task, opts) {
],
opts
)
-}
-
-export async function compile(task, opts) {
- await task.serial(['next_compile', 'next_bundle'], opts)
-
await task.serial([
'ncc_react_refresh_utils',
'ncc_next__react_dev_overlay',
'ncc_next_font',
'capsize_metrics',
+ 'minimal_next_server',
])
}
@@ -2662,38 +2658,157 @@ export async function release(task) {
await task.clear('dist').start('build')
}
-export async function next_bundle_prod(task, opts) {
- await task.source('dist').webpack({
- watch: opts.dev,
- config: require('./webpack.config')({
- dev: false,
- }),
- name: 'next-bundle-prod',
+export async function minimal_next_server(task) {
+ const outputName = 'next-server.js'
+ const cachedOutputName = `${outputName}.cache`
+
+ const minimalExternals = [
+ 'react',
+ 'react/package.json',
+ 'react/jsx-runtime',
+ 'react/jsx-dev-runtime',
+ 'react-dom',
+ 'react-dom/package.json',
+ 'react-dom/client',
+ 'react-dom/server',
+ 'react-dom/server.browser',
+ 'react-dom/server.edge',
+ 'react-server-dom-webpack/client',
+ 'react-server-dom-webpack/client.edge',
+ 'react-server-dom-webpack/server.edge',
+ 'react-server-dom-webpack/server.node',
+ 'styled-jsx',
+ 'styled-jsx/style',
+ '@opentelemetry/api',
+ 'next/dist/compiled/@next/react-dev-overlay/dist/middleware',
+ 'next/dist/compiled/@ampproject/toolbox-optimizer',
+ 'next/dist/compiled/edge-runtime',
+ 'next/dist/compiled/@edge-runtime/ponyfill',
+ 'next/dist/compiled/undici',
+ 'next/dist/compiled/raw-body',
+ 'next/dist/server/capsize-font-metrics.json',
+ 'critters',
+ 'next/dist/compiled/node-html-parser',
+ 'next/dist/compiled/compression',
+ 'next/dist/compiled/jsonwebtoken',
+ 'next/dist/compiled/@mswjs/interceptors/ClientRequest',
+ ].reduce((acc, pkg) => {
+ acc[pkg] = pkg
+ return acc
+ }, {})
+
+ Object.assign(minimalExternals, {
+ '/(.*)config$/': 'next/dist/server/config',
+ './web/sandbox': 'next/dist/server/web/sandbox',
})
-}
-export async function next_bundle_dev(task, opts) {
- await task.source('dist').webpack({
- watch: opts.dev,
- config: require('./webpack.config')({
- dev: true,
- }),
- name: 'next-bundle-dev',
+ const webpack = require('webpack')
+ const TerserPlugin = require('terser-webpack-plugin')
+ // const BundleAnalyzerPlugin =
+ // require('webpack-bundle-analyzer').BundleAnalyzerPlugin
+ /** @type {webpack.Configuration} */
+ const config = {
+ entry: join(__dirname, 'dist/server/next-server.js'),
+ target: 'node',
+ mode: 'production',
+ output: {
+ path: join(__dirname, 'dist/compiled/minimal-next-server'),
+ filename: outputName,
+ libraryTarget: 'commonjs2',
+ },
+ // left in for debugging
+ optimization: {
+ moduleIds: 'named',
+ // minimize: false,
+ minimize: true,
+ minimizer: [
+ new TerserPlugin({
+ extractComments: false,
+ terserOptions: {
+ format: {
+ comments: false,
+ },
+ compress: {
+ passes: 2,
+ },
+ },
+ }),
+ ],
+ },
+ plugins: [
+ new webpack.DefinePlugin({
+ 'process.env.NODE_ENV': JSON.stringify('production'),
+ 'process.env.NEXT_MINIMAL': JSON.stringify('true'),
+ 'process.env.NEXT_RUNTIME': JSON.stringify('nodejs'),
+ }),
+ // new BundleAnalyzerPlugin({}),
+ ],
+ externals: [minimalExternals],
+ }
+
+ await new Promise((resolve, reject) => {
+ webpack(config, (err, stats) => {
+ if (err) return reject(err)
+ if (stats.hasErrors()) {
+ return reject(new Error(stats.toString('errors-only')))
+ }
+ resolve()
+ })
})
-}
-export async function next_bundle_turbo_prod(task, opts) {
- await task.source('dist').webpack({
- watch: opts.dev,
- config: require('./webpack.config')({
- turbo: true,
- }),
- name: 'next-bundle-prod-turbo',
+ const wrappedTemplate = `
+const filename = ${JSON.stringify(outputName)}
+const { readFileSync } = require('fs'),
+ { Script } = require('vm'),
+ { wrap } = require('module'),
+ { join } = require('path');
+const basename = join(__dirname, filename)
+
+const source = readFileSync(basename, 'utf-8')
+
+const cachedData =
+ !process.pkg &&
+ require('process').platform !== 'win32' &&
+ readFileSync(join(__dirname, '${cachedOutputName}'))
+
+const scriptOpts = { filename: basename, columnOffset: 0 }
+
+const script = new Script(
+ wrap(source),
+ cachedData ? Object.assign({ cachedData }, scriptOpts) : scriptOpts
+)
+
+script.runInThisContext()(exports, require, module, __filename, __dirname)
+`
+
+ await fs.writeFile(
+ join(__dirname, `dist/compiled/minimal-next-server/next-server-cached.js`),
+ wrappedTemplate
+ )
+
+ const Module = require('module')
+ const vm = require('vm')
+ const filename = resolve(
+ __dirname,
+ 'dist/compiled/minimal-next-server',
+ outputName
+ )
+
+ const content = require('fs').readFileSync(filename, 'utf8')
+
+ const wrapper = Module.wrap(content)
+ var script = new vm.Script(wrapper, {
+ filename: filename,
+ lineOffset: 0,
+ displayErrors: true,
})
-}
-export async function next_bundle(task, opts) {
- await task.parallel(
- ['next_bundle_prod', 'next_bundle_dev', 'next_bundle_turbo_prod'],
- opts
+
+ script.runInThisContext()(exports, require, module, __filename, __dirname)
+
+ const buffer = script.createCachedData()
+
+ await fs.writeFile(
+ join(__dirname, `dist/compiled/minimal-next-server/${cachedOutputName}`),
+ buffer
)
}
diff --git a/packages/next/webpack.config.js b/packages/next/webpack.config.js
deleted file mode 100644
index 8e7c3063fa5ed..0000000000000
--- a/packages/next/webpack.config.js
+++ /dev/null
@@ -1,145 +0,0 @@
-const webpack = require('webpack')
-const path = require('path')
-const TerserPlugin = require('terser-webpack-plugin')
-const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
-
-const minimalExternals = [
- 'react',
- 'react/package.json',
- 'react/jsx-runtime',
- 'react/jsx-dev-runtime',
- 'react-dom',
- 'react-dom/package.json',
- 'react-dom/client',
- 'react-dom/server',
- 'react-dom/server.browser',
- 'react-dom/server.edge',
- 'react-server-dom-webpack/client',
- 'react-server-dom-webpack/client.edge',
- 'react-server-dom-webpack/server.edge',
- 'react-server-dom-webpack/server.node',
- 'styled-jsx',
- 'styled-jsx/style',
- '@opentelemetry/api',
- 'next/dist/compiled/@next/react-dev-overlay/dist/middleware',
- 'next/dist/compiled/@ampproject/toolbox-optimizer',
- 'next/dist/compiled/edge-runtime',
- 'next/dist/compiled/@edge-runtime/ponyfill',
- 'next/dist/compiled/undici',
- 'next/dist/compiled/raw-body',
- 'next/dist/server/capsize-font-metrics.json',
- 'critters',
- 'next/dist/compiled/node-html-parser',
- 'next/dist/compiled/compression',
- 'next/dist/compiled/jsonwebtoken',
- 'next/dist/compiled/@opentelemetry/api',
- 'next/dist/compiled/@mswjs/interceptors/ClientRequest',
-]
-
-const externalsMap = {
- './web/sandbox': 'next/dist/server/web/sandbox',
-}
-
-const externalsRegexMap = {
- '(.*)trace/tracer$': 'next/dist/server/lib/trace/tracer',
-}
-
-module.exports = ({ dev, turbo }) => {
- const externalHandler = ({ context, request, getResolve }, callback) => {
- ;(async () => {
- if (
- ((dev || turbo) && request.endsWith('.shared-runtime')) ||
- request.endsWith('.external')
- ) {
- const resolve = getResolve()
- const resolved = await resolve(context, request)
- const relative = path.relative(
- path.join(__dirname, '..'),
- resolved.replace('esm' + path.sep, '')
- )
- callback(null, `commonjs ${relative}`)
- } else {
- const regexMatch = Object.keys(externalsRegexMap).find((regex) =>
- new RegExp(regex).test(request)
- )
- if (regexMatch) {
- return callback(null, 'commonjs ' + externalsRegexMap[regexMatch])
- }
- callback()
- }
- })()
- }
-
- /** @type {webpack.Configuration} */
- return {
- entry: {
- server: path.join(__dirname, 'dist/esm/server/next-server.js'),
- 'app-page': path.join(
- __dirname,
- 'dist/esm/server/future/route-modules/app-page/module.js'
- ),
- 'app-route': path.join(
- __dirname,
- 'dist/esm/server/future/route-modules/app-route/module.js'
- ),
- pages: path.join(
- __dirname,
- 'dist/esm/server/future/route-modules/pages/module.js'
- ),
- 'pages-api': path.join(
- __dirname,
- 'dist/esm/server/future/route-modules/pages-api/module.js'
- ),
- },
- target: 'node',
- mode: 'production',
- output: {
- path: path.join(__dirname, 'dist/compiled/next-server'),
- filename: `[name]${turbo ? '-turbo' : ''}.runtime.${
- dev ? 'dev' : 'prod'
- }.js`,
- libraryTarget: 'commonjs2',
- },
- optimization: {
- moduleIds: 'named',
- minimize: true,
- // splitChunks: {
- // chunks: 'all',
- // },
- concatenateModules: true,
- minimizer: [
- new TerserPlugin({
- extractComments: false,
- terserOptions: {
- format: {
- comments: false,
- },
- compress: {
- passes: 2,
- },
- },
- }),
- ],
- },
- plugins: [
- new webpack.DefinePlugin({
- 'process.env.NEXT_MINIMAL': JSON.stringify('true'),
- 'this.serverOptions.experimentalTestProxy': JSON.stringify(false),
- 'this.minimalMode': JSON.stringify(true),
- 'this.renderOpts.dev': JSON.stringify(dev),
- 'process.env.NODE_ENV': JSON.stringify(
- dev ? 'development' : 'production'
- ),
- 'process.env.NEXT_RUNTIME': JSON.stringify('nodejs'),
- }),
- !!process.env.ANALYZE &&
- new BundleAnalyzerPlugin({
- analyzerPort: 8888 + (dev ? 0 : 1) + (turbo ? 1 : 0),
- }),
- ].filter(Boolean),
- stats: {
- optimizationBailout: true,
- },
- externals: [...minimalExternals, externalsMap, externalHandler],
- }
-}
diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json
index cc6d2a5b422a3..d760b0ff82191 100644
--- a/packages/react-dev-overlay/package.json
+++ b/packages/react-dev-overlay/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/react-dev-overlay",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"description": "A development-only overlay for developing React applications.",
"repository": {
"url": "vercel/next.js",
diff --git a/packages/react-dev-overlay/tsconfig.json b/packages/react-dev-overlay/tsconfig.json
index 59e05adbe1d27..01235b6a1bf8f 100644
--- a/packages/react-dev-overlay/tsconfig.json
+++ b/packages/react-dev-overlay/tsconfig.json
@@ -12,6 +12,7 @@
"jsx": "react",
"noFallthroughCasesInSwitch": true,
"skipLibCheck": true,
+ "module": "Node16",
"moduleResolution": "Node16"
},
"include": ["src/**/*.ts", "src/**/*.tsx", "types/local.d.ts"],
diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json
index 20e4acbdcca74..2db27f44e1e96 100644
--- a/packages/react-refresh-utils/package.json
+++ b/packages/react-refresh-utils/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/react-refresh-utils",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"description": "An experimental package providing utilities for React Refresh.",
"repository": {
"url": "vercel/next.js",
diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json
index 7677d8733511c..4e69590dcd618 100644
--- a/packages/third-parties/package.json
+++ b/packages/third-parties/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/third-parties",
- "version": "13.4.20-canary.20",
+ "version": "13.4.20-canary.21",
"private": true,
"repository": {
"url": "vercel/next.js",
@@ -23,7 +23,7 @@
"third-party-capital": "1.0.20"
},
"devDependencies": {
- "next": "13.4.20-canary.20",
+ "next": "13.4.20-canary.21",
"outdent": "0.8.0",
"prettier": "2.5.1"
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8478bb10eb18c..ecefb2db79ec1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -150,8 +150,8 @@ importers:
specifier: 18.2.4
version: 18.2.4
'@types/relay-runtime':
- specifier: 13.0.0
- version: 13.0.0
+ specifier: 14.1.13
+ version: 14.1.13
'@types/selenium-webdriver':
specifier: 4.0.15
version: 4.0.15
@@ -166,10 +166,10 @@ importers:
version: 2.0.3
'@typescript-eslint/eslint-plugin':
specifier: 6.1.0
- version: 6.1.0(@typescript-eslint/parser@6.1.0)(eslint@7.24.0)(typescript@5.1.3)
+ version: 6.1.0(@typescript-eslint/parser@6.1.0)(eslint@7.24.0)(typescript@5.2.2)
'@typescript-eslint/parser':
specifier: 6.1.0
- version: 6.1.0(eslint@7.24.0)(typescript@5.1.3)
+ version: 6.1.0(eslint@7.24.0)(typescript@5.2.2)
'@vercel/fetch':
specifier: 6.1.1
version: 6.1.1(@types/node-fetch@2.6.1)(node-fetch@2.6.7)
@@ -250,7 +250,7 @@ importers:
version: 2.22.1(@typescript-eslint/parser@6.1.0)(eslint@7.24.0)
eslint-plugin-jest:
specifier: 24.3.5
- version: 24.3.5(@typescript-eslint/eslint-plugin@6.1.0)(eslint@7.24.0)(typescript@5.1.3)
+ version: 24.3.5(@typescript-eslint/eslint-plugin@6.1.0)(eslint@7.24.0)(typescript@5.2.2)
eslint-plugin-jsdoc:
specifier: 39.6.4
version: 39.6.4(eslint@7.24.0)
@@ -520,13 +520,13 @@ importers:
version: 1.2.2
tsec:
specifier: 0.2.1
- version: 0.2.1(@bazel/bazelisk@1.12.1)(typescript@5.1.3)
+ version: 0.2.1(@bazel/bazelisk@1.12.1)(typescript@5.2.2)
turbo:
specifier: 1.10.9
version: 1.10.9
typescript:
- specifier: 5.1.3
- version: 5.1.3
+ specifier: 5.2.2
+ version: 5.2.2
unfetch:
specifier: 4.2.0
version: 4.2.0
@@ -729,7 +729,7 @@ importers:
packages/eslint-config-next:
dependencies:
'@next/eslint-plugin-next':
- specifier: 13.4.20-canary.20
+ specifier: 13.4.20-canary.21
version: link:../eslint-plugin-next
'@rushstack/eslint-patch':
specifier: ^1.3.3
@@ -790,7 +790,7 @@ importers:
packages/next:
dependencies:
'@next/env':
- specifier: 13.4.20-canary.20
+ specifier: 13.4.20-canary.21
version: link:../next-env
'@swc/helpers':
specifier: 0.5.1
@@ -917,19 +917,19 @@ importers:
specifier: 1.1.0
version: 1.1.0
'@next/polyfill-module':
- specifier: 13.4.20-canary.20
+ specifier: 13.4.20-canary.21
version: link:../next-polyfill-module
'@next/polyfill-nomodule':
- specifier: 13.4.20-canary.20
+ specifier: 13.4.20-canary.21
version: link:../next-polyfill-nomodule
'@next/react-dev-overlay':
- specifier: 13.4.20-canary.20
+ specifier: 13.4.20-canary.21
version: link:../react-dev-overlay
'@next/react-refresh-utils':
- specifier: 13.4.20-canary.20
+ specifier: 13.4.20-canary.21
version: link:../react-refresh-utils
'@next/swc':
- specifier: 13.4.20-canary.20
+ specifier: 13.4.20-canary.21
version: link:../next-swc
'@opentelemetry/api':
specifier: 1.4.1
@@ -1001,8 +1001,8 @@ importers:
specifier: 9.0.0
version: 9.0.0
'@types/lodash':
- specifier: 4.14.149
- version: 4.14.149
+ specifier: 4.14.198
+ version: 4.14.198
'@types/lodash.curry':
specifier: 4.1.6
version: 4.1.6
@@ -1244,8 +1244,8 @@ importers:
specifier: 2.4.3
version: 2.4.3(webpack@5.86.0)
msw:
- specifier: ^1.2.2
- version: 1.2.2(typescript@5.1.3)
+ specifier: 1.3.0
+ version: 1.3.0(typescript@5.2.2)
nanoid:
specifier: 3.1.32
version: 3.1.32
@@ -1381,9 +1381,6 @@ importers:
terser:
specifier: 5.14.1
version: 5.14.1
- terser-webpack-plugin:
- specifier: 5.3.9
- version: 5.3.9(@swc/core@1.3.55)(webpack@5.86.0)
text-table:
specifier: 0.2.0
version: 0.2.0
@@ -1688,7 +1685,7 @@ importers:
version: 1.0.20
devDependencies:
next:
- specifier: 13.4.20-canary.20
+ specifier: 13.4.20-canary.21
version: link:../next
outdent:
specifier: 0.8.0
@@ -6848,7 +6845,7 @@ packages:
'@types/debug': 4.1.8
'@xmldom/xmldom': 0.8.10
debug: 4.3.4
- headers-polyfill: 3.1.2
+ headers-polyfill: 3.2.3
outvariant: 1.4.0
strict-event-emitter: 0.2.8
web-encoding: 1.1.5
@@ -8336,11 +8333,11 @@ packages:
/@types/lodash.curry@4.1.6:
resolution: {integrity: sha512-x3ctCcmOYqRrihNNnQJW6fe/yZFCgnrIa6p80AiPQRO8Jis29bBdy1dEw1FwngoF/mCZa3Bx+33fUZvOEE635Q==}
dependencies:
- '@types/lodash': 4.14.149
+ '@types/lodash': 4.14.198
dev: true
- /@types/lodash@4.14.149:
- resolution: {integrity: sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==}
+ /@types/lodash@4.14.198:
+ resolution: {integrity: sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==}
dev: true
/@types/long@4.0.1:
@@ -8463,8 +8460,8 @@ packages:
'@types/scheduler': 0.16.2
csstype: 3.0.10
- /@types/relay-runtime@13.0.0:
- resolution: {integrity: sha512-yzv6F8EZPWA2rtfFP2qMluS8tsz1q4lfdYxLegCshdAjX5uqxTR2pAliATj9wrzD6OMZF4fl9aU+Y+zmSfm2EA==}
+ /@types/relay-runtime@14.1.13:
+ resolution: {integrity: sha512-NODqEnGjERJr02M0YQclUnXWCldmerNUkpFfuO317h/od1uXuwAW5131vpeiROE11BizPC/Qhup5VrwKsENazw==}
dev: true
/@types/resolve@1.17.1:
@@ -8621,7 +8618,7 @@ packages:
'@types/yargs-parser': 21.0.0
dev: true
- /@typescript-eslint/eslint-plugin@6.1.0(@typescript-eslint/parser@6.1.0)(eslint@7.24.0)(typescript@5.1.3):
+ /@typescript-eslint/eslint-plugin@6.1.0(@typescript-eslint/parser@6.1.0)(eslint@7.24.0)(typescript@5.2.2):
resolution: {integrity: sha512-qg7Bm5TyP/I7iilGyp6DRqqkt8na00lI6HbjWZObgk3FFSzH5ypRwAHXJhJkwiRtTcfn+xYQIMOR5kJgpo6upw==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
@@ -8633,10 +8630,10 @@ packages:
optional: true
dependencies:
'@eslint-community/regexpp': 4.5.1
- '@typescript-eslint/parser': 6.1.0(eslint@7.24.0)(typescript@5.1.3)
+ '@typescript-eslint/parser': 6.1.0(eslint@7.24.0)(typescript@5.2.2)
'@typescript-eslint/scope-manager': 6.1.0
- '@typescript-eslint/type-utils': 6.1.0(eslint@7.24.0)(typescript@5.1.3)
- '@typescript-eslint/utils': 6.1.0(eslint@7.24.0)(typescript@5.1.3)
+ '@typescript-eslint/type-utils': 6.1.0(eslint@7.24.0)(typescript@5.2.2)
+ '@typescript-eslint/utils': 6.1.0(eslint@7.24.0)(typescript@5.2.2)
'@typescript-eslint/visitor-keys': 6.1.0
debug: 4.3.4
eslint: 7.24.0
@@ -8645,13 +8642,13 @@ packages:
natural-compare: 1.4.0
natural-compare-lite: 1.4.0
semver: 7.5.4
- ts-api-utils: 1.0.1(typescript@5.1.3)
- typescript: 5.1.3
+ ts-api-utils: 1.0.1(typescript@5.2.2)
+ typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
- /@typescript-eslint/experimental-utils@4.29.1(eslint@7.24.0)(typescript@5.1.3):
+ /@typescript-eslint/experimental-utils@4.29.1(eslint@7.24.0)(typescript@5.2.2):
resolution: {integrity: sha512-kl6QG6qpzZthfd2bzPNSJB2YcZpNOrP6r9jueXupcZHnL74WiuSjaft7WSu17J9+ae9zTlk0KJMXPUj0daBxMw==}
engines: {node: ^10.12.0 || >=12.0.0}
peerDependencies:
@@ -8660,7 +8657,7 @@ packages:
'@types/json-schema': 7.0.12
'@typescript-eslint/scope-manager': 4.29.1
'@typescript-eslint/types': 4.29.1
- '@typescript-eslint/typescript-estree': 4.29.1(typescript@5.1.3)
+ '@typescript-eslint/typescript-estree': 4.29.1(typescript@5.2.2)
eslint: 7.24.0
eslint-scope: 5.1.1
eslint-utils: 3.0.0(eslint@7.24.0)
@@ -8669,7 +8666,7 @@ packages:
- typescript
dev: true
- /@typescript-eslint/parser@6.1.0(eslint@7.24.0)(typescript@5.1.3):
+ /@typescript-eslint/parser@6.1.0(eslint@7.24.0)(typescript@5.2.2):
resolution: {integrity: sha512-hIzCPvX4vDs4qL07SYzyomamcs2/tQYXg5DtdAfj35AyJ5PIUqhsLf4YrEIFzZcND7R2E8tpQIZKayxg8/6Wbw==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
@@ -8681,11 +8678,11 @@ packages:
dependencies:
'@typescript-eslint/scope-manager': 6.1.0
'@typescript-eslint/types': 6.1.0
- '@typescript-eslint/typescript-estree': 6.1.0(typescript@5.1.3)
+ '@typescript-eslint/typescript-estree': 6.1.0(typescript@5.2.2)
'@typescript-eslint/visitor-keys': 6.1.0
debug: 4.3.4
eslint: 7.24.0
- typescript: 5.1.3
+ typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
@@ -8726,7 +8723,7 @@ packages:
'@typescript-eslint/types': 6.1.0
'@typescript-eslint/visitor-keys': 6.1.0
- /@typescript-eslint/type-utils@6.1.0(eslint@7.24.0)(typescript@5.1.3):
+ /@typescript-eslint/type-utils@6.1.0(eslint@7.24.0)(typescript@5.2.2):
resolution: {integrity: sha512-kFXBx6QWS1ZZ5Ni89TyT1X9Ag6RXVIVhqDs0vZE/jUeWlBv/ixq2diua6G7ece6+fXw3TvNRxP77/5mOMusx2w==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
@@ -8736,12 +8733,12 @@ packages:
typescript:
optional: true
dependencies:
- '@typescript-eslint/typescript-estree': 6.1.0(typescript@5.1.3)
- '@typescript-eslint/utils': 6.1.0(eslint@7.24.0)(typescript@5.1.3)
+ '@typescript-eslint/typescript-estree': 6.1.0(typescript@5.2.2)
+ '@typescript-eslint/utils': 6.1.0(eslint@7.24.0)(typescript@5.2.2)
debug: 4.3.4
eslint: 7.24.0
- ts-api-utils: 1.0.1(typescript@5.1.3)
- typescript: 5.1.3
+ ts-api-utils: 1.0.1(typescript@5.2.2)
+ typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
@@ -8755,7 +8752,7 @@ packages:
resolution: {integrity: sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==}
engines: {node: ^16.0.0 || >=18.0.0}
- /@typescript-eslint/typescript-estree@4.29.1(typescript@5.1.3):
+ /@typescript-eslint/typescript-estree@4.29.1(typescript@5.2.2):
resolution: {integrity: sha512-lIkkrR9E4lwZkzPiRDNq0xdC3f2iVCUjw/7WPJ4S2Sl6C3nRWkeE1YXCQ0+KsiaQRbpY16jNaokdWnm9aUIsfw==}
engines: {node: ^10.12.0 || >=12.0.0}
peerDependencies:
@@ -8770,8 +8767,8 @@ packages:
globby: 11.1.0
is-glob: 4.0.3
semver: 7.3.7
- tsutils: 3.21.0(typescript@5.1.3)
- typescript: 5.1.3
+ tsutils: 3.21.0(typescript@5.2.2)
+ typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
@@ -8797,7 +8794,7 @@ packages:
- supports-color
dev: false
- /@typescript-eslint/typescript-estree@6.1.0(typescript@5.1.3):
+ /@typescript-eslint/typescript-estree@6.1.0(typescript@5.2.2):
resolution: {integrity: sha512-nUKAPWOaP/tQjU1IQw9sOPCDavs/iU5iYLiY/6u7gxS7oKQoi4aUxXS1nrrVGTyBBaGesjkcwwHkbkiD5eBvcg==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
@@ -8812,13 +8809,13 @@ packages:
globby: 11.1.0
is-glob: 4.0.3
semver: 7.5.4
- ts-api-utils: 1.0.1(typescript@5.1.3)
- typescript: 5.1.3
+ ts-api-utils: 1.0.1(typescript@5.2.2)
+ typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
- /@typescript-eslint/utils@6.1.0(eslint@7.24.0)(typescript@5.1.3):
+ /@typescript-eslint/utils@6.1.0(eslint@7.24.0)(typescript@5.2.2):
resolution: {integrity: sha512-wp652EogZlKmQoMS5hAvWqRKplXvkuOnNzZSE0PVvsKjpexd/XznRVHAtrfHFYmqaJz0DFkjlDsGYC9OXw+OhQ==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
@@ -8829,7 +8826,7 @@ packages:
'@types/semver': 7.5.0
'@typescript-eslint/scope-manager': 6.1.0
'@typescript-eslint/types': 6.1.0
- '@typescript-eslint/typescript-estree': 6.1.0(typescript@5.1.3)
+ '@typescript-eslint/typescript-estree': 6.1.0(typescript@5.2.2)
eslint: 7.24.0
semver: 7.5.4
transitivePeerDependencies:
@@ -10710,14 +10707,6 @@ packages:
ansi-styles: 4.3.0
supports-color: 7.2.0
- /chalk@4.1.1:
- resolution: {integrity: sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==}
- engines: {node: '>=10'}
- dependencies:
- ansi-styles: 4.3.0
- supports-color: 7.2.0
- dev: true
-
/chalk@4.1.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
@@ -12179,7 +12168,7 @@ packages:
supports-color:
optional: true
dependencies:
- ms: 2.1.2
+ ms: 2.1.3
/debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
@@ -13132,7 +13121,7 @@ packages:
eslint-import-resolver-webpack:
optional: true
dependencies:
- '@typescript-eslint/parser': 6.1.0(eslint@7.24.0)(typescript@5.1.3)
+ '@typescript-eslint/parser': 6.1.0(eslint@7.24.0)(typescript@5.2.2)
debug: 3.2.7
eslint-import-resolver-node: 0.3.6
find-up: 2.1.0
@@ -13191,7 +13180,7 @@ packages:
'@typescript-eslint/parser':
optional: true
dependencies:
- '@typescript-eslint/parser': 6.1.0(eslint@7.24.0)(typescript@5.1.3)
+ '@typescript-eslint/parser': 6.1.0(eslint@7.24.0)(typescript@5.2.2)
array-includes: 3.1.4
array.prototype.flat: 1.2.5
contains-path: 0.1.0
@@ -13247,7 +13236,7 @@ packages:
- supports-color
dev: false
- /eslint-plugin-jest@24.3.5(@typescript-eslint/eslint-plugin@6.1.0)(eslint@7.24.0)(typescript@5.1.3):
+ /eslint-plugin-jest@24.3.5(@typescript-eslint/eslint-plugin@6.1.0)(eslint@7.24.0)(typescript@5.2.2):
resolution: {integrity: sha512-XG4rtxYDuJykuqhsOqokYIR84/C8pRihRtEpVskYLbIIKGwPNW2ySxdctuVzETZE+MbF/e7wmsnbNVpzM0rDug==}
engines: {node: '>=10'}
peerDependencies:
@@ -13257,8 +13246,8 @@ packages:
'@typescript-eslint/eslint-plugin':
optional: true
dependencies:
- '@typescript-eslint/eslint-plugin': 6.1.0(@typescript-eslint/parser@6.1.0)(eslint@7.24.0)(typescript@5.1.3)
- '@typescript-eslint/experimental-utils': 4.29.1(eslint@7.24.0)(typescript@5.1.3)
+ '@typescript-eslint/eslint-plugin': 6.1.0(@typescript-eslint/parser@6.1.0)(eslint@7.24.0)(typescript@5.2.2)
+ '@typescript-eslint/experimental-utils': 4.29.1(eslint@7.24.0)(typescript@5.2.2)
eslint: 7.24.0
transitivePeerDependencies:
- supports-color
@@ -15331,6 +15320,10 @@ packages:
resolution: {integrity: sha512-tWCK4biJ6hcLqTviLXVR9DTRfYGQMXEIUj3gwJ2rZ5wO/at3XtkI4g8mCvFdUF9l1KMBNCfmNAdnahm1cgavQA==}
dev: true
+ /headers-polyfill@3.2.3:
+ resolution: {integrity: sha512-oj6MO8sdFQ9gQQedSVdMGh96suxTNp91vPQu7C4qx/57FqYsA5TiNr92nhIZwVQq8zygn4nu3xS1aEqpakGqdw==}
+ dev: true
+
/hex-color-regex@1.1.0:
resolution: {integrity: sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==}
dev: true
@@ -19487,13 +19480,13 @@ packages:
isarray: 1.0.0
dev: true
- /msw@1.2.2(typescript@5.1.3):
- resolution: {integrity: sha512-GsW3PE/Es/a1tYThXcM8YHOZ1S1MtivcS3He/LQbbTCx3rbWJYCtWD5XXyJ53KlNPT7O1VI9sCW3xMtgFe8XpQ==}
+ /msw@1.3.0(typescript@5.2.2):
+ resolution: {integrity: sha512-nnWAZlQyQOKeYRblCpseT1kSPt1aF5e/jHz1hn/18IxbsMFreSVV1cJriT0uV+YG6+wvwFRMHXU3zVuMvuwERQ==}
engines: {node: '>=14'}
hasBin: true
requiresBuild: true
peerDependencies:
- typescript: '>= 4.4.x <= 5.1.x'
+ typescript: '>= 4.4.x <= 5.2.x'
peerDependenciesMeta:
typescript:
optional: true
@@ -19503,11 +19496,11 @@ packages:
'@open-draft/until': 1.0.3
'@types/cookie': 0.4.1
'@types/js-levenshtein': 1.1.1
- chalk: 4.1.1
+ chalk: 4.1.2
chokidar: 3.5.3
cookie: 0.4.2
graphql: 16.7.1
- headers-polyfill: 3.1.2
+ headers-polyfill: 3.2.3
inquirer: 8.2.0
is-node-process: 1.2.0
js-levenshtein: 1.1.6
@@ -19516,7 +19509,7 @@ packages:
path-to-regexp: 6.2.1
strict-event-emitter: 0.4.6
type-fest: 2.19.0
- typescript: 5.1.3
+ typescript: 5.2.2
yargs: 17.5.1
transitivePeerDependencies:
- encoding
@@ -25709,13 +25702,13 @@ packages:
typescript: 4.8.2
dev: false
- /ts-api-utils@1.0.1(typescript@5.1.3):
+ /ts-api-utils@1.0.1(typescript@5.2.2):
resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==}
engines: {node: '>=16.13.0'}
peerDependencies:
typescript: '>=4.2.0'
dependencies:
- typescript: 5.1.3
+ typescript: 5.2.2
dev: true
/tsconfig-paths@3.14.1:
@@ -25736,7 +25729,7 @@ packages:
strip-bom: 3.0.0
dev: false
- /tsec@0.2.1(@bazel/bazelisk@1.12.1)(typescript@5.1.3):
+ /tsec@0.2.1(@bazel/bazelisk@1.12.1)(typescript@5.2.2):
resolution: {integrity: sha512-RP9vhbRbRI9VH4CfOlQvo5W9HdfiPKq0gdiUOWI5oKmLaZKNFN8CsPwBfT5ySmhnKNwmmAS/BtY3WoTfABwwig==}
hasBin: true
peerDependencies:
@@ -25746,7 +25739,7 @@ packages:
'@bazel/bazelisk': 1.12.1
glob: 7.2.0
minimatch: 3.1.2
- typescript: 5.1.3
+ typescript: 5.2.2
dev: true
/tslib@1.11.1:
@@ -25766,14 +25759,14 @@ packages:
/tslib@2.5.3:
resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==}
- /tsutils@3.21.0(typescript@5.1.3):
+ /tsutils@3.21.0(typescript@5.2.2):
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
engines: {node: '>= 6'}
peerDependencies:
typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
dependencies:
tslib: 1.11.1
- typescript: 5.1.3
+ typescript: 5.2.2
dev: true
/tty-browserify@0.0.1:
@@ -25976,8 +25969,8 @@ packages:
engines: {node: '>=4.2.0'}
hasBin: true
- /typescript@5.1.3:
- resolution: {integrity: sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==}
+ /typescript@5.2.2:
+ resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==}
engines: {node: '>=14.17'}
hasBin: true
dev: true
diff --git a/scripts/minimal-server.js b/scripts/minimal-server.js
index 08f9125a4f0cc..f4f30ac97ce25 100644
--- a/scripts/minimal-server.js
+++ b/scripts/minimal-server.js
@@ -1,4 +1,3 @@
-console.time('next-wall-time')
// Usage: node scripts/minimal-server.js
// This script is used to run a minimal Next.js server in production mode.
@@ -45,13 +44,11 @@ if (process.env.LOG_READFILE) {
require('fs').readFile = function (path, options, callback) {
readFileCount++
- console.log(`readFile: ${path}`)
return originalReadFile.apply(this, arguments)
}
require('fs').readFileSync = function (path, options) {
readFileSyncCount++
- console.log(`readFileSync: ${path}`)
return originalReadFileSync.apply(this, arguments)
}
}
@@ -59,9 +56,10 @@ if (process.env.LOG_READFILE) {
console.time('next-cold-start')
const NextServer = process.env.USE_BUNDLED_NEXT
- ? require('next/dist/compiled/next-server/server.runtime.prod').default
+ ? require('next/dist/compiled/minimal-next-server/next-server-cached').default
: require('next/dist/server/next-server').default
+console.timeEnd('next-cold-start')
if (process.env.LOG_READFILE) {
console.log(`readFileCount: ${readFileCount + readFileSyncCount}`)
}
@@ -103,20 +101,9 @@ require('http')
if (process.env.LOG_READFILE) {
console.log(`readFileCount: ${readFileCount + readFileSyncCount}`)
}
+ require('process').exit(0)
})
})
.listen(3000, () => {
console.timeEnd('next-cold-start')
- fetch('http://localhost:3000/')
- .then((res) => res.text())
- .then((text) => {
- console.log(text)
- })
- .catch((err) => {
- console.error(err)
- })
- .finally(() => {
- console.timeEnd('next-wall-time')
- require('process').exit(0)
- })
})
diff --git a/test/e2e/app-dir/actions/app-action-size-limit-invalid.test.ts b/test/e2e/app-dir/actions/app-action-size-limit-invalid.test.ts
index 3e5e6b82ea050..a61e222c3872e 100644
--- a/test/e2e/app-dir/actions/app-action-size-limit-invalid.test.ts
+++ b/test/e2e/app-dir/actions/app-action-size-limit-invalid.test.ts
@@ -113,7 +113,7 @@ createNextDescribe(
await check(() => {
const fullLog = logs.join('')
- return fullLog.includes('[Error]: Body exceeded 1.5mb limit') &&
+ return fullLog.includes('Error: Body exceeded 1.5mb limit') &&
fullLog.includes(
'To configure the body size limit for Server Actions, see'
)
diff --git a/test/e2e/app-dir/navigation/app/mpa-nav-test/page.js b/test/e2e/app-dir/navigation/app/mpa-nav-test/page.js
new file mode 100644
index 0000000000000..9a335e2d0995c
--- /dev/null
+++ b/test/e2e/app-dir/navigation/app/mpa-nav-test/page.js
@@ -0,0 +1,38 @@
+'use client'
+import Link from 'next/link'
+import { useEffect, useRef } from 'react'
+
+export default function Page() {
+ const prefetchRef = useRef()
+ const slowPageRef = useRef()
+
+ useEffect(() => {
+ function triggerPrefetch() {
+ const event = new MouseEvent('mouseover', {
+ view: window,
+ bubbles: true,
+ cancelable: true,
+ })
+
+ prefetchRef.current.dispatchEvent(event)
+ console.log('dispatched')
+ }
+
+ slowPageRef.current.click()
+
+ setInterval(() => {
+ triggerPrefetch()
+ }, 1000)
+ }, [])
+
+ return (
+ <>
+
+ To /slow-page
+
+
+ Prefetch link
+
+ >
+ )
+}
diff --git a/test/e2e/app-dir/navigation/navigation.test.ts b/test/e2e/app-dir/navigation/navigation.test.ts
index 67beabf483fe3..b3e1cf19c4261 100644
--- a/test/e2e/app-dir/navigation/navigation.test.ts
+++ b/test/e2e/app-dir/navigation/navigation.test.ts
@@ -1,5 +1,5 @@
import { createNextDescribe } from 'e2e-utils'
-import { check } from 'next-test-utils'
+import { check, waitFor } from 'next-test-utils'
import type { Request } from 'playwright-chromium'
createNextDescribe(
@@ -497,6 +497,33 @@ createNextDescribe(
.waitForElementByCss('#link-to-app')
expect(await browser.url()).toBe(next.url + '/some')
})
+
+ if (!isNextDev) {
+ // this test is pretty hard to test in playwright, so most of the heavy lifting is in the page component itself
+ // it triggers a hover on a link to initiate a prefetch request every second, and so we check that
+ // it doesn't repeatedly initiate the mpa navigation request
+ it('should not continously initiate a mpa navigation to the same URL when router state changes', async () => {
+ let requestCount = 0
+ const browser = await next.browser('/mpa-nav-test', {
+ beforePageLoad(page) {
+ page.on('request', (request) => {
+ const url = new URL(request.url())
+ // skip rsc prefetches
+ if (url.pathname === '/slow-page' && !url.search) {
+ requestCount++
+ }
+ })
+ },
+ })
+
+ await browser.waitForElementByCss('#link-to-slow-page')
+
+ // wait a few seconds since prefetches are triggered in 1s intervals in the page component
+ await waitFor(5000)
+
+ expect(requestCount).toBe(1)
+ })
+ }
})
describe('nested navigation', () => {
@@ -562,7 +589,7 @@ createNextDescribe(
)
})
- it('should emit refresh meta tag (peramnent) for redirect page when streaming', async () => {
+ it('should emit refresh meta tag (permanent) for redirect page when streaming', async () => {
const html = await next.render('/redirect/suspense-2')
expect(html).toContain(
''
diff --git a/test/e2e/app-dir/navigation/pages/slow-page.js b/test/e2e/app-dir/navigation/pages/slow-page.js
new file mode 100644
index 0000000000000..ad37357cb6dcf
--- /dev/null
+++ b/test/e2e/app-dir/navigation/pages/slow-page.js
@@ -0,0 +1,13 @@
+export default function Page() {
+ return 'Hello from slow page'
+}
+
+export async function getServerSideProps({ resolvedUrl }) {
+ if (!resolvedUrl.includes('?_rsc')) {
+ // only stall on the navigation, not prefetch
+ await new Promise((resolve) => setTimeout(resolve, 100000))
+ }
+ return {
+ props: {},
+ }
+}
diff --git a/test/e2e/getserversideprops/app/pages/index.js b/test/e2e/getserversideprops/app/pages/index.js
index da17edc01839d..4433c9c2ee84e 100644
--- a/test/e2e/getserversideprops/app/pages/index.js
+++ b/test/e2e/getserversideprops/app/pages/index.js
@@ -1,6 +1,6 @@
import Link from 'next/link'
import ReactDOM from 'react-dom/server'
-import { RouterContext } from 'next/dist/shared/lib/router-context.shared-runtime'
+import { RouterContext } from 'next/dist/shared/lib/router-context'
import { useRouter } from 'next/router'
function RouterComp(props) {
diff --git a/test/e2e/i18n-data-route/components/page.tsx b/test/e2e/i18n-data-route/components/page.tsx
new file mode 100644
index 0000000000000..60418c58cba43
--- /dev/null
+++ b/test/e2e/i18n-data-route/components/page.tsx
@@ -0,0 +1,12 @@
+import React from 'react'
+
+export function Page({ page }) {
+ return {page}
+}
+
+export function createGetServerSideProps(page: string) {
+ return async function getServerSideProps(ctx) {
+ const output = ctx.req.headers['x-invoke-output'] ?? null
+ return { props: { page, output } }
+ }
+}
diff --git a/test/e2e/i18n-data-route/i18n-data-route.test.ts b/test/e2e/i18n-data-route/i18n-data-route.test.ts
new file mode 100644
index 0000000000000..1231f78f02670
--- /dev/null
+++ b/test/e2e/i18n-data-route/i18n-data-route.test.ts
@@ -0,0 +1,87 @@
+import { createNextDescribe } from 'e2e-utils'
+
+const { i18n } = require('./next.config')
+
+const pages = [
+ { url: '/about', page: '/about', params: null },
+ { url: '/blog/about', page: '/[slug]/about', params: { slug: 'blog' } },
+]
+
+function checkDataRoute(data: any, page: string) {
+ expect(data).toHaveProperty('pageProps')
+ expect(data.pageProps).toHaveProperty('page', page)
+ expect(data.pageProps).toHaveProperty('output', page)
+}
+
+createNextDescribe(
+ 'i18n-data-route',
+ {
+ files: __dirname,
+ env: {
+ // Disable internal header stripping so we can test the invoke output.
+ __NEXT_NO_STRIP_INTERNAL_HEADERS: '1',
+ },
+ },
+ ({ next }) => {
+ describe('with locale prefix', () => {
+ describe.each(i18n.locales)('/%s', (locale) => {
+ const prefixed = pages.map((page) => ({
+ ...page,
+ url: `/${locale}${page.url}`,
+ }))
+
+ it.each(prefixed)(
+ 'should render $page via $url',
+ async ({ url, page }) => {
+ const $ = await next.render$(url)
+ expect($('[data-page]').data('page')).toBe(page)
+ }
+ )
+
+ it.each(prefixed)(
+ 'should serve data for $page',
+ async ({ url, page, params }) => {
+ url = `/_next/data/${next.buildId}${url}.json`
+ if (params) {
+ const query = new URLSearchParams(params)
+ // Ensure the query is sorted so it's deterministic.
+ query.sort()
+ url += `?${query.toString()}`
+ }
+
+ const res = await next.fetch(url)
+ expect(res.status).toBe(200)
+ expect(res.headers.get('content-type')).toBe('application/json')
+ const data = await res.json()
+ checkDataRoute(data, page)
+ }
+ )
+ })
+ })
+
+ describe('without locale prefix', () => {
+ it.each(pages)('should render $page via $url', async ({ url, page }) => {
+ const $ = await next.render$(url)
+ expect($('[data-page]').data('page')).toBe(page)
+ })
+
+ it.each(pages)(
+ 'should serve data for $page',
+ async ({ url, page, params }) => {
+ url = `/_next/data/${next.buildId}/${i18n.defaultLocale}${url}.json`
+ if (params) {
+ const query = new URLSearchParams(params)
+ // Ensure the query is sorted so it's deterministic.
+ query.sort()
+ url += `?${query.toString()}`
+ }
+ const res = await next.fetch(url)
+ expect(res.status).toBe(200)
+ expect(res.headers.get('content-type')).toBe('application/json')
+ const data = await res.json()
+ checkDataRoute(data, page)
+ }
+ )
+ })
+ }
+)
diff --git a/test/e2e/i18n-data-route/next.config.js b/test/e2e/i18n-data-route/next.config.js
new file mode 100644
index 0000000000000..32a015bd37ca9
--- /dev/null
+++ b/test/e2e/i18n-data-route/next.config.js
@@ -0,0 +1,9 @@
+/**
+ * @type {import('next').NextConfig}
+ */
+module.exports = {
+ i18n: {
+ locales: ['en-CA', 'fr-CA'],
+ defaultLocale: 'en-CA',
+ },
+}
diff --git a/test/e2e/i18n-data-route/pages/[slug]/about/index.tsx b/test/e2e/i18n-data-route/pages/[slug]/about/index.tsx
new file mode 100644
index 0000000000000..3c8a96c601f40
--- /dev/null
+++ b/test/e2e/i18n-data-route/pages/[slug]/about/index.tsx
@@ -0,0 +1,5 @@
+import { Page, createGetServerSideProps } from '../../../components/page'
+
+export default Page
+
+export const getServerSideProps = createGetServerSideProps('/[slug]/about')
diff --git a/test/e2e/i18n-data-route/pages/about/index.tsx b/test/e2e/i18n-data-route/pages/about/index.tsx
new file mode 100644
index 0000000000000..83ef2115f5326
--- /dev/null
+++ b/test/e2e/i18n-data-route/pages/about/index.tsx
@@ -0,0 +1,5 @@
+import { Page, createGetServerSideProps } from '../../components/page'
+
+export default Page
+
+export const getServerSideProps = createGetServerSideProps('/about')
diff --git a/test/e2e/opentelemetry/opentelemetry.test.ts b/test/e2e/opentelemetry/opentelemetry.test.ts
index 13e0fefea2787..ae798ec7c5c2d 100644
--- a/test/e2e/opentelemetry/opentelemetry.test.ts
+++ b/test/e2e/opentelemetry/opentelemetry.test.ts
@@ -77,80 +77,80 @@ createNextDescribe(
await check(async () => {
expect(await getSanitizedTraces(1)).toMatchInlineSnapshot(`
- Array [
- Object {
- "attributes": Object {
- "http.method": "GET",
- "http.url": "https://vercel.com/",
- "net.peer.name": "vercel.com",
- "next.span_name": "fetch GET https://vercel.com/",
- "next.span_type": "AppRender.fetch",
- },
- "kind": 2,
- "name": "fetch GET https://vercel.com/",
- "parentId": "[parent-id]",
- "status": Object {
- "code": 0,
- },
- },
- Object {
- "attributes": Object {
- "next.route": "/app/[param]/rsc-fetch",
- "next.span_name": "render route (app) /app/[param]/rsc-fetch",
- "next.span_type": "AppRender.getBodyResult",
- },
- "kind": 0,
- "name": "render route (app) /app/[param]/rsc-fetch",
- "parentId": "[parent-id]",
- "status": Object {
- "code": 0,
- },
- },
- Object {
- "attributes": Object {
- "http.method": "GET",
- "http.route": "/app/[param]/rsc-fetch",
- "http.status_code": 200,
- "http.target": "/app/param/rsc-fetch",
- "next.route": "/app/[param]/rsc-fetch",
- "next.span_name": "GET /app/[param]/rsc-fetch",
- "next.span_type": "BaseServer.handleRequest",
- },
- "kind": 1,
- "name": "GET /app/[param]/rsc-fetch",
- "parentId": undefined,
- "status": Object {
- "code": 0,
- },
- },
- Object {
- "attributes": Object {
- "next.page": "/app/[param]/layout",
- "next.span_name": "generateMetadata /app/[param]/layout",
- "next.span_type": "ResolveMetadata.generateMetadata",
- },
- "kind": 0,
- "name": "generateMetadata /app/[param]/layout",
- "parentId": "[parent-id]",
- "status": Object {
- "code": 0,
- },
- },
- Object {
- "attributes": Object {
- "next.page": "/app/[param]/rsc-fetch/page",
- "next.span_name": "generateMetadata /app/[param]/rsc-fetch/page",
- "next.span_type": "ResolveMetadata.generateMetadata",
- },
- "kind": 0,
- "name": "generateMetadata /app/[param]/rsc-fetch/page",
- "parentId": "[parent-id]",
- "status": Object {
- "code": 0,
- },
- },
- ]
- `)
+ Array [
+ Object {
+ "attributes": Object {
+ "http.method": "GET",
+ "http.url": "https://vercel.com/",
+ "net.peer.name": "vercel.com",
+ "next.span_name": "fetch GET https://vercel.com/",
+ "next.span_type": "AppRender.fetch",
+ },
+ "kind": 2,
+ "name": "fetch GET https://vercel.com/",
+ "parentId": "[parent-id]",
+ "status": Object {
+ "code": 0,
+ },
+ },
+ Object {
+ "attributes": Object {
+ "next.route": "/app/[param]/rsc-fetch",
+ "next.span_name": "render route (app) /app/[param]/rsc-fetch",
+ "next.span_type": "AppRender.getBodyResult",
+ },
+ "kind": 0,
+ "name": "render route (app) /app/[param]/rsc-fetch",
+ "parentId": "[parent-id]",
+ "status": Object {
+ "code": 0,
+ },
+ },
+ Object {
+ "attributes": Object {
+ "http.method": "GET",
+ "http.route": "/app/[param]/rsc-fetch",
+ "http.status_code": 200,
+ "http.target": "/app/param/rsc-fetch",
+ "next.route": "/app/[param]/rsc-fetch",
+ "next.span_name": "GET /app/[param]/rsc-fetch",
+ "next.span_type": "BaseServer.handleRequest",
+ },
+ "kind": 1,
+ "name": "GET /app/[param]/rsc-fetch",
+ "parentId": undefined,
+ "status": Object {
+ "code": 0,
+ },
+ },
+ Object {
+ "attributes": Object {
+ "next.page": "/app/[param]/layout",
+ "next.span_name": "generateMetadata /app/[param]/layout",
+ "next.span_type": "ResolveMetadata.generateMetadata",
+ },
+ "kind": 0,
+ "name": "generateMetadata /app/[param]/layout",
+ "parentId": "[parent-id]",
+ "status": Object {
+ "code": 0,
+ },
+ },
+ Object {
+ "attributes": Object {
+ "next.page": "/app/[param]/rsc-fetch/page",
+ "next.span_name": "generateMetadata /app/[param]/rsc-fetch/page",
+ "next.span_type": "ResolveMetadata.generateMetadata",
+ },
+ "kind": 0,
+ "name": "generateMetadata /app/[param]/rsc-fetch/page",
+ "parentId": "[parent-id]",
+ "status": Object {
+ "code": 0,
+ },
+ },
+ ]
+ `)
return 'success'
}, 'success')
})
@@ -160,39 +160,37 @@ createNextDescribe(
await check(async () => {
expect(await getSanitizedTraces(1)).toMatchInlineSnapshot(`
- Array [
- Object {
- "attributes": Object {
- "next.route": "/api/app/[param]/data/route",
- "next.span_name": "executing api route (app) /api/app/[param]/data/route",
- "next.span_type": "AppRouteRouteHandlers.runHandler",
- },
- "kind": 0,
- "name": "executing api route (app) /api/app/[param]/data/route",
- "parentId": "[parent-id]",
- "status": Object {
- "code": 0,
- },
+ Array [
+ Object {
+ "attributes": Object {
+ "next.route": "/api/app/[param]/data/route",
+ "next.span_name": "executing api route (app) /api/app/[param]/data/route",
+ "next.span_type": "AppRouteRouteHandlers.runHandler",
+ },
+ "kind": 0,
+ "name": "executing api route (app) /api/app/[param]/data/route",
+ "parentId": "[parent-id]",
+ "status": Object {
+ "code": 0,
},
- Object {
- "attributes": Object {
- "http.method": "GET",
- "http.route": "/api/app/[param]/data/route",
- "http.status_code": 200,
- "http.target": "/api/app/param/data",
- "next.route": "/api/app/[param]/data/route",
- "next.span_name": "GET /api/app/[param]/data/route",
- "next.span_type": "BaseServer.handleRequest",
- },
- "kind": 1,
- "name": "GET /api/app/[param]/data/route",
- "parentId": undefined,
- "status": Object {
- "code": 0,
- },
+ },
+ Object {
+ "attributes": Object {
+ "http.method": "GET",
+ "http.status_code": 200,
+ "http.target": "/api/app/param/data",
+ "next.span_name": "GET /api/app/param/data",
+ "next.span_type": "BaseServer.handleRequest",
},
- ]
- `)
+ "kind": 1,
+ "name": "GET /api/app/param/data",
+ "parentId": undefined,
+ "status": Object {
+ "code": 0,
+ },
+ },
+ ]
+ `)
return 'success'
}, 'success')
})
@@ -204,52 +202,52 @@ createNextDescribe(
await check(async () => {
expect(await getSanitizedTraces(1)).toMatchInlineSnapshot(`
- Array [
- Object {
- "attributes": Object {
- "http.method": "GET",
- "http.route": "/pages/[param]/getServerSideProps",
- "http.status_code": 200,
- "http.target": "/pages/param/getServerSideProps",
- "next.route": "/pages/[param]/getServerSideProps",
- "next.span_name": "GET /pages/[param]/getServerSideProps",
- "next.span_type": "BaseServer.handleRequest",
- },
- "kind": 1,
- "name": "GET /pages/[param]/getServerSideProps",
- "parentId": undefined,
- "status": Object {
- "code": 0,
- },
- },
- Object {
- "attributes": Object {
- "next.route": "/pages/[param]/getServerSideProps",
- "next.span_name": "getServerSideProps /pages/[param]/getServerSideProps",
- "next.span_type": "Render.getServerSideProps",
- },
- "kind": 0,
- "name": "getServerSideProps /pages/[param]/getServerSideProps",
- "parentId": "[parent-id]",
- "status": Object {
- "code": 0,
- },
- },
- Object {
- "attributes": Object {
- "next.route": "/pages/[param]/getServerSideProps",
- "next.span_name": "render route (pages) /pages/[param]/getServerSideProps",
- "next.span_type": "Render.renderDocument",
- },
- "kind": 0,
- "name": "render route (pages) /pages/[param]/getServerSideProps",
- "parentId": "[parent-id]",
- "status": Object {
- "code": 0,
- },
- },
- ]
- `)
+ Array [
+ Object {
+ "attributes": Object {
+ "http.method": "GET",
+ "http.route": "/pages/[param]/getServerSideProps",
+ "http.status_code": 200,
+ "http.target": "/pages/param/getServerSideProps",
+ "next.route": "/pages/[param]/getServerSideProps",
+ "next.span_name": "GET /pages/[param]/getServerSideProps",
+ "next.span_type": "BaseServer.handleRequest",
+ },
+ "kind": 1,
+ "name": "GET /pages/[param]/getServerSideProps",
+ "parentId": undefined,
+ "status": Object {
+ "code": 0,
+ },
+ },
+ Object {
+ "attributes": Object {
+ "next.route": "/pages/[param]/getServerSideProps",
+ "next.span_name": "getServerSideProps /pages/[param]/getServerSideProps",
+ "next.span_type": "Render.getServerSideProps",
+ },
+ "kind": 0,
+ "name": "getServerSideProps /pages/[param]/getServerSideProps",
+ "parentId": "[parent-id]",
+ "status": Object {
+ "code": 0,
+ },
+ },
+ Object {
+ "attributes": Object {
+ "next.route": "/pages/[param]/getServerSideProps",
+ "next.span_name": "render route (pages) /pages/[param]/getServerSideProps",
+ "next.span_type": "Render.renderDocument",
+ },
+ "kind": 0,
+ "name": "render route (pages) /pages/[param]/getServerSideProps",
+ "parentId": "[parent-id]",
+ "status": Object {
+ "code": 0,
+ },
+ },
+ ]
+ `)
return 'success'
}, 'success')
})
@@ -259,52 +257,52 @@ createNextDescribe(
await check(async () => {
expect(await getSanitizedTraces(1)).toMatchInlineSnapshot(`
- Array [
- Object {
- "attributes": Object {
- "http.method": "GET",
- "http.route": "/pages/[param]/getStaticProps",
- "http.status_code": 200,
- "http.target": "/pages/param/getStaticProps",
- "next.route": "/pages/[param]/getStaticProps",
- "next.span_name": "GET /pages/[param]/getStaticProps",
- "next.span_type": "BaseServer.handleRequest",
- },
- "kind": 1,
- "name": "GET /pages/[param]/getStaticProps",
- "parentId": undefined,
- "status": Object {
- "code": 0,
- },
- },
- Object {
- "attributes": Object {
- "next.route": "/pages/[param]/getStaticProps",
- "next.span_name": "getStaticProps /pages/[param]/getStaticProps",
- "next.span_type": "Render.getStaticProps",
- },
- "kind": 0,
- "name": "getStaticProps /pages/[param]/getStaticProps",
- "parentId": "[parent-id]",
- "status": Object {
- "code": 0,
- },
- },
- Object {
- "attributes": Object {
- "next.route": "/pages/[param]/getStaticProps",
- "next.span_name": "render route (pages) /pages/[param]/getStaticProps",
- "next.span_type": "Render.renderDocument",
- },
- "kind": 0,
- "name": "render route (pages) /pages/[param]/getStaticProps",
- "parentId": "[parent-id]",
- "status": Object {
- "code": 0,
- },
- },
- ]
- `)
+ Array [
+ Object {
+ "attributes": Object {
+ "http.method": "GET",
+ "http.route": "/pages/[param]/getStaticProps",
+ "http.status_code": 200,
+ "http.target": "/pages/param/getStaticProps",
+ "next.route": "/pages/[param]/getStaticProps",
+ "next.span_name": "GET /pages/[param]/getStaticProps",
+ "next.span_type": "BaseServer.handleRequest",
+ },
+ "kind": 1,
+ "name": "GET /pages/[param]/getStaticProps",
+ "parentId": undefined,
+ "status": Object {
+ "code": 0,
+ },
+ },
+ Object {
+ "attributes": Object {
+ "next.route": "/pages/[param]/getStaticProps",
+ "next.span_name": "getStaticProps /pages/[param]/getStaticProps",
+ "next.span_type": "Render.getStaticProps",
+ },
+ "kind": 0,
+ "name": "getStaticProps /pages/[param]/getStaticProps",
+ "parentId": "[parent-id]",
+ "status": Object {
+ "code": 0,
+ },
+ },
+ Object {
+ "attributes": Object {
+ "next.route": "/pages/[param]/getStaticProps",
+ "next.span_name": "render route (pages) /pages/[param]/getStaticProps",
+ "next.span_type": "Render.renderDocument",
+ },
+ "kind": 0,
+ "name": "render route (pages) /pages/[param]/getStaticProps",
+ "parentId": "[parent-id]",
+ "status": Object {
+ "code": 0,
+ },
+ },
+ ]
+ `)
return 'success'
}, 'success')
})
@@ -314,38 +312,38 @@ createNextDescribe(
await check(async () => {
expect(await getSanitizedTraces(1)).toMatchInlineSnapshot(`
- Array [
- Object {
- "attributes": Object {
- "http.method": "GET",
- "http.route": "/api/pages/[param]/basic",
- "http.status_code": 200,
- "http.target": "/api/pages/param/basic",
- "next.route": "/api/pages/[param]/basic",
- "next.span_name": "GET /api/pages/[param]/basic",
- "next.span_type": "BaseServer.handleRequest",
- },
- "kind": 1,
- "name": "GET /api/pages/[param]/basic",
- "parentId": undefined,
- "status": Object {
- "code": 0,
- },
- },
- Object {
- "attributes": Object {
- "next.span_name": "executing api route (pages) /api/pages/[param]/basic",
- "next.span_type": "Node.runHandler",
- },
- "kind": 0,
- "name": "executing api route (pages) /api/pages/[param]/basic",
- "parentId": "[parent-id]",
- "status": Object {
- "code": 0,
- },
- },
- ]
- `)
+ Array [
+ Object {
+ "attributes": Object {
+ "http.method": "GET",
+ "http.route": "/api/pages/[param]/basic",
+ "http.status_code": 200,
+ "http.target": "/api/pages/param/basic",
+ "next.route": "/api/pages/[param]/basic",
+ "next.span_name": "GET /api/pages/[param]/basic",
+ "next.span_type": "BaseServer.handleRequest",
+ },
+ "kind": 1,
+ "name": "GET /api/pages/[param]/basic",
+ "parentId": undefined,
+ "status": Object {
+ "code": 0,
+ },
+ },
+ Object {
+ "attributes": Object {
+ "next.span_name": "executing api route (pages) /api/pages/[param]/basic",
+ "next.span_type": "Node.runHandler",
+ },
+ "kind": 0,
+ "name": "executing api route (pages) /api/pages/[param]/basic",
+ "parentId": "[parent-id]",
+ "status": Object {
+ "code": 0,
+ },
+ },
+ ]
+ `)
return 'success'
}, 'success')
})
diff --git a/test/e2e/prerender-native-module.test.ts b/test/e2e/prerender-native-module.test.ts
index 34adb36ce5bd8..c23b1d2d05cd0 100644
--- a/test/e2e/prerender-native-module.test.ts
+++ b/test/e2e/prerender-native-module.test.ts
@@ -85,6 +85,8 @@ describe('prerender native module', () => {
/node_modules\/sqlite3\/.*?\.node/,
/node_modules\/sqlite\/.*?\.js/,
/node_modules\/next/,
+ /next\/router\.js/,
+ /next\/dist\/client\/router\.js/,
/\/data\.sqlite/,
],
notTests: [],
@@ -97,6 +99,7 @@ describe('prerender native module', () => {
)
const { version, files } = JSON.parse(contents)
expect(version).toBe(1)
+
expect(
check.tests.every((item) => files.some((file) => item.test(file)))
).toBe(true)
diff --git a/test/e2e/prerender.test.ts b/test/e2e/prerender.test.ts
index 1ff677e583b15..f21b4224fe236 100644
--- a/test/e2e/prerender.test.ts
+++ b/test/e2e/prerender.test.ts
@@ -2070,6 +2070,7 @@ describe('Prerender', () => {
/node_modules\/react\/index\.js/,
/node_modules\/react\/package\.json/,
/node_modules\/react\/cjs\/react\.production\.min\.js/,
+ /node_modules\/next/,
],
notTests: [],
},
@@ -2081,6 +2082,7 @@ describe('Prerender', () => {
/node_modules\/react\/index\.js/,
/node_modules\/react\/package\.json/,
/node_modules\/react\/cjs\/react\.production\.min\.js/,
+ /node_modules\/next/,
/\/world.txt/,
],
notTests: [
@@ -2096,6 +2098,9 @@ describe('Prerender', () => {
/node_modules\/react\/index\.js/,
/node_modules\/react\/package\.json/,
/node_modules\/react\/cjs\/react\.production\.min\.js/,
+ /node_modules\/next/,
+ /next\/router\.js/,
+ /next\/dist\/client\/router\.js/,
/node_modules\/@firebase\/firestore\/.*?\.js/,
],
notTests: [/\/world.txt/],
diff --git a/test/integration/externalize-next-server/app/node_modules/comps/index.js b/test/integration/externalize-next-server/app/node_modules/comps/index.js
new file mode 100644
index 0000000000000..74c3153f1b835
--- /dev/null
+++ b/test/integration/externalize-next-server/app/node_modules/comps/index.js
@@ -0,0 +1,5 @@
+const react = require('react')
+
+module.exports = function() {
+ return react.createElement('p', null, 'MyComp:', typeof window)
+}
diff --git a/test/integration/externalize-next-server/app/node_modules/comps/package.json b/test/integration/externalize-next-server/app/node_modules/comps/package.json
new file mode 100644
index 0000000000000..6e665b646a6ad
--- /dev/null
+++ b/test/integration/externalize-next-server/app/node_modules/comps/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "comps",
+ "version": "1.0.0",
+ "main": "index.js",
+ "license": "MIT"
+}
diff --git a/test/integration/externalize-next-server/app/package.json b/test/integration/externalize-next-server/app/package.json
new file mode 100644
index 0000000000000..c5bd706a3a950
--- /dev/null
+++ b/test/integration/externalize-next-server/app/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "externalize-next-server-app",
+ "version": "1.0.0",
+ "main": "index.js",
+ "license": "MIT"
+}
diff --git a/test/integration/externalize-next-server/app/pages/index.js b/test/integration/externalize-next-server/app/pages/index.js
new file mode 100644
index 0000000000000..9ceb7bee3db17
--- /dev/null
+++ b/test/integration/externalize-next-server/app/pages/index.js
@@ -0,0 +1,12 @@
+import MyComp from 'comps'
+
+const Page = () => (
+ <>
+ Hello {typeof window}
+
+ >
+)
+
+Page.getInitialProps = () => ({})
+
+export default Page
diff --git a/test/integration/externalize-next-server/test/index.test.js b/test/integration/externalize-next-server/test/index.test.js
new file mode 100644
index 0000000000000..bba968de16585
--- /dev/null
+++ b/test/integration/externalize-next-server/test/index.test.js
@@ -0,0 +1,19 @@
+/* eslint-env jest */
+import path from 'path'
+import { nextBuild, readNextBuildServerPageFile } from 'next-test-utils'
+
+const appDir = path.join(__dirname, '../app')
+
+describe('externalize next/dist/shared', () => {
+ beforeAll(async () => {
+ await nextBuild(appDir)
+ })
+
+ it('Bundle next/dist/shared/lib/head.js but not next/dist/shared/lib/head-manager-context.js in _error', async () => {
+ const content = readNextBuildServerPageFile(appDir, '/_error')
+ expect(content).toContain(
+ `require("next/dist/shared/lib/head-manager-context.js")`
+ )
+ expect(content).not.toContain(`require("next/dist/shared/lib/head.js")`)
+ })
+})
diff --git a/test/integration/jsconfig-baseurl/test/index.test.js b/test/integration/jsconfig-baseurl/test/index.test.js
index 4ad014d0e8f03..91f084ce1d55e 100644
--- a/test/integration/jsconfig-baseurl/test/index.test.js
+++ b/test/integration/jsconfig-baseurl/test/index.test.js
@@ -72,6 +72,12 @@ describe('TypeScript Features', () => {
const helloTrace = await fs.readJSON(
join(appDir, '.next/server/pages/hello.js.nft.json')
)
+ const appTrace = await fs.readJSON(
+ join(appDir, '.next/server/pages/_app.js.nft.json')
+ )
+ expect(
+ appTrace.files.some((file) => file.includes('node_modules/next'))
+ ).toBe(true)
expect(
helloTrace.files.some((file) => file.includes('components/world.js'))
).toBe(false)
diff --git a/test/integration/jsconfig-paths/test/index.test.js b/test/integration/jsconfig-paths/test/index.test.js
index bc3c635b9ce96..77c84e7edfbb4 100644
--- a/test/integration/jsconfig-paths/test/index.test.js
+++ b/test/integration/jsconfig-paths/test/index.test.js
@@ -89,6 +89,9 @@ function runTests() {
await nextBuild(appDir)
})
it('should trace correctly', async () => {
+ const appTrace = await fs.readJSON(
+ join(appDir, '.next/server/pages/_app.js.nft.json')
+ )
const singleAliasTrace = await fs.readJSON(
join(appDir, '.next/server/pages/single-alias.js.nft.json')
)
@@ -104,7 +107,9 @@ function runTests() {
const basicAliasTrace = await fs.readJSON(
join(appDir, '.next/server/pages/basic-alias.js.nft.json')
)
-
+ expect(
+ appTrace.files.some((file) => file.includes('node_modules/next'))
+ ).toBe(true)
expect(
singleAliasTrace.files.some((file) =>
file.includes('components/hello.js')
diff --git a/test/integration/tsconfig-verifier/test/index.test.js b/test/integration/tsconfig-verifier/test/index.test.js
index fdb648b46ee10..5102737198a85 100644
--- a/test/integration/tsconfig-verifier/test/index.test.js
+++ b/test/integration/tsconfig-verifier/test/index.test.js
@@ -298,7 +298,7 @@ describe('tsconfig.json verifier', () => {
await writeFile(
tsConfig,
- `{ "compilerOptions": { "esModuleInterop": false, "moduleResolution": "node16" } }`
+ `{ "compilerOptions": { "esModuleInterop": false, "moduleResolution": "node16", "module": "node16" } }`
)
await new Promise((resolve) => setTimeout(resolve, 500))
const { code, stderr, stdout } = await nextBuild(appDir, undefined, {
@@ -313,6 +313,7 @@ describe('tsconfig.json verifier', () => {
\\"compilerOptions\\": {
\\"esModuleInterop\\": true,
\\"moduleResolution\\": \\"node16\\",
+ \\"module\\": \\"node16\\",
\\"lib\\": [
\\"dom\\",
\\"dom.iterable\\",
@@ -323,7 +324,6 @@ describe('tsconfig.json verifier', () => {
\\"strict\\": false,
\\"noEmit\\": true,
\\"incremental\\": true,
- \\"module\\": \\"esnext\\",
\\"resolveJsonModule\\": true,
\\"isolatedModules\\": true,
\\"jsx\\": \\"preserve\\",