From 2766ebc8d315a71e4d4eb1ed3a1d0e6645c388c3 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 15 Apr 2024 12:42:28 +0200 Subject: [PATCH 01/96] improve turborepo caching (#64493) ### What? There is a race condition in the `pull-build-cache` script. When the remote cache entry was removed between the dry run and the real run, it will run the command and caches whatever is in the native folder. Seems like there are some very old leftover files there which lead to an broken publish. This changes the command to fail when there are no files and empties the folder before running the script. This should lead to pull-build-cache to failing instead. Closes PACK-2957 Fixes #64468 --- .github/workflows/build_and_deploy.yml | 3 +++ packages/next-swc/package.json | 2 +- scripts/pull-turbo-cache.js | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_and_deploy.yml b/.github/workflows/build_and_deploy.yml index 82ac9931614af7..9d7c3912eac848 100644 --- a/.github/workflows/build_and_deploy.yml +++ b/.github/workflows/build_and_deploy.yml @@ -275,6 +275,9 @@ jobs: cache-provider: 'turbo' shared-key: build-${{ matrix.settings.target }}-${{ hashFiles('.cargo/config.toml') }} + - name: Clear native build + run: rm -rf packages/next-swc/native + # we only need custom caching for docker builds # as they are on an older Node.js version and have # issues with turbo caching diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index fef0a7250db95d..056b9d726ee167 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -11,7 +11,7 @@ "build-native-no-plugin-woa-release": "napi build --platform -p next-swc-napi --cargo-cwd ../../ --cargo-name next_swc_napi --release --cargo-flags=--no-default-features --features image-webp,tracing/release_max_level_info --js false native", "build-native-wasi": "npx --package=@napi-rs/cli@3.0.0-alpha.45 napi build --platform --target wasm32-wasip1-threads -p next-swc-napi --cwd ../../ --output-dir packages/next-swc/native", "build-wasm": "wasm-pack build crates/wasm --scope=next", - "cache-build-native": "echo $(ls native)", + "cache-build-native": "[ -d native ] && echo $(ls native)", "rust-check-fmt": "cd ../..; cargo fmt -- --check", "rust-check-clippy": "cargo clippy --workspace --all-targets -- -D warnings -A deprecated", "rust-check-napi-rustls": "cargo check -p next-swc-napi", diff --git a/scripts/pull-turbo-cache.js b/scripts/pull-turbo-cache.js index 919618a347f611..fa7e9a06e6f286 100644 --- a/scripts/pull-turbo-cache.js +++ b/scripts/pull-turbo-cache.js @@ -42,6 +42,7 @@ const { spawn } = require('child_process') // pull cache if it was available if (task.cache.local || task.cache.remote) { + console.log('Cache Status', task.taskId, task.hash, task.cache) await new Promise((resolve, reject) => { const child = spawn( '/bin/bash', From f9cd55ff325a90f479bc9194534fab159efa2b7f Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Mon, 15 Apr 2024 10:45:59 +0000 Subject: [PATCH 02/96] v14.2.1-canary.6 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 12 ++++++------ packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 14 +++++++------- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lerna.json b/lerna.json index 57e533ec2737b3..c4d63251a02052 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.2.1-canary.5" + "version": "14.2.1-canary.6" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 81348dcff979f2..415d9f715f3c16 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.2.1-canary.5", + "version": "14.2.1-canary.6", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 5579c022b4d0ba..969b46988817dc 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.2.1-canary.5", + "version": "14.2.1-canary.6", "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": "14.2.1-canary.5", + "@next/eslint-plugin-next": "14.2.1-canary.6", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.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 6446adbe0c79bd..2f18bb55c83ad6 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": "14.2.1-canary.5", + "version": "14.2.1-canary.6", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index c5d63913ec65ff..b20097bc78fbb0 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.2.1-canary.5", + "version": "14.2.1-canary.6", "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 b99c69bd5ec78f..ef72bf9cbd1ca3 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.2.1-canary.5", + "version": "14.2.1-canary.6", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 724dd073291457..8b5cdf9787f7d8 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.2.1-canary.5", + "version": "14.2.1-canary.6", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 8141efb798262e..280c465b8c3090 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.2.1-canary.5", + "version": "14.2.1-canary.6", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 064d91cd8426b5..fbd47b3af46243 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.2.1-canary.5", + "version": "14.2.1-canary.6", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index bb49e449e20d5e..b2273b5f608738 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.2.1-canary.5", + "version": "14.2.1-canary.6", "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 0866b59abfeeed..27d7a0b29f1287 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.2.1-canary.5", + "version": "14.2.1-canary.6", "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 dcf1f263f01b89..920b9991588dcb 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.2.1-canary.5", + "version": "14.2.1-canary.6", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 056b9d726ee167..ae12e13b22eed7 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.2.1-canary.5", + "version": "14.2.1-canary.6", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 553c8b2e34c132..532591bedcc63d 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.2.1-canary.5", + "version": "14.2.1-canary.6", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.2.1-canary.5", + "@next/env": "14.2.1-canary.6", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -149,10 +149,10 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/polyfill-module": "14.2.1-canary.5", - "@next/polyfill-nomodule": "14.2.1-canary.5", - "@next/react-refresh-utils": "14.2.1-canary.5", - "@next/swc": "14.2.1-canary.5", + "@next/polyfill-module": "14.2.1-canary.6", + "@next/polyfill-nomodule": "14.2.1-canary.6", + "@next/react-refresh-utils": "14.2.1-canary.6", + "@next/swc": "14.2.1-canary.6", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", "@taskr/clear": "1.1.0", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 849afce488d510..c2059f27c59893 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": "14.2.1-canary.5", + "version": "14.2.1-canary.6", "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 0a2a77d7b283b2..de827eb312c0a1 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.2.1-canary.5", + "version": "14.2.1-canary.6", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -26,7 +26,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.2.1-canary.5", + "next": "14.2.1-canary.6", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d76d412c8578bf..0480f17bc5429b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -744,7 +744,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.2.1-canary.5 + specifier: 14.2.1-canary.6 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.2.1-canary.5 + specifier: 14.2.1-canary.6 version: link:../next-env '@swc/helpers': specifier: 0.5.5 @@ -927,16 +927,16 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/polyfill-module': - specifier: 14.2.1-canary.5 + specifier: 14.2.1-canary.6 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.2.1-canary.5 + specifier: 14.2.1-canary.6 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 14.2.1-canary.5 + specifier: 14.2.1-canary.6 version: link:../react-refresh-utils '@next/swc': - specifier: 14.2.1-canary.5 + specifier: 14.2.1-canary.6 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1551,7 +1551,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.2.1-canary.5 + specifier: 14.2.1-canary.6 version: link:../next outdent: specifier: 0.8.0 From 4623eace7613a0ed8428cd69903ae85bb0af4d76 Mon Sep 17 00:00:00 2001 From: Ryota Murakami Date: Mon, 15 Apr 2024 23:54:28 +0900 Subject: [PATCH 03/96] chore: Update pnpm v8.15.1 to v8.15.7 (#64479) Here are the release notes for pnpm versions v8.15.2 through v8.15.7, - [v8.15.2 Release Notes](https://github.com/pnpm/pnpm/releases/tag/v8.15.2) - [v8.15.3 Release Notes](https://github.com/pnpm/pnpm/releases/tag/v8.15.3) - [v8.15.4 Release Notes](https://github.com/pnpm/pnpm/releases/tag/v8.15.4) - [v8.15.5 Release Notes](https://github.com/pnpm/pnpm/releases/tag/v8.15.5) - [v8.15.6 Release Notes](https://github.com/pnpm/pnpm/releases/tag/v8.15.6) - [v8.15.7 Release Notes](https://github.com/pnpm/pnpm/releases/tag/v8.15.7) --- .github/actions/next-integration-stat/package.json | 4 ++-- .github/actions/next-stats-action/package.json | 4 ++-- .github/actions/upload-turboyet-data/package.json | 4 ++-- package.json | 4 ++-- test/.stats-app/package.json | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/actions/next-integration-stat/package.json b/.github/actions/next-integration-stat/package.json index f7139529c5c8ac..efe20f8ad066b2 100644 --- a/.github/actions/next-integration-stat/package.json +++ b/.github/actions/next-integration-stat/package.json @@ -22,7 +22,7 @@ }, "engines": { "node": ">=18.17.0", - "pnpm": "8.15.4" + "pnpm": "8.15.7" }, - "packageManager": "pnpm@8.15.4" + "packageManager": "pnpm@8.15.7" } diff --git a/.github/actions/next-stats-action/package.json b/.github/actions/next-stats-action/package.json index 1be4a941450e59..4269e374084f88 100644 --- a/.github/actions/next-stats-action/package.json +++ b/.github/actions/next-stats-action/package.json @@ -19,7 +19,7 @@ }, "engines": { "node": ">=18.17.0", - "pnpm": "8.15.4" + "pnpm": "8.15.7" }, - "packageManager": "pnpm@8.15.4" + "packageManager": "pnpm@8.15.7" } diff --git a/.github/actions/upload-turboyet-data/package.json b/.github/actions/upload-turboyet-data/package.json index d99a2194646522..ef65a1117b81a9 100644 --- a/.github/actions/upload-turboyet-data/package.json +++ b/.github/actions/upload-turboyet-data/package.json @@ -13,7 +13,7 @@ }, "engines": { "node": ">=18.17.0", - "pnpm": "8.15.4" + "pnpm": "8.15.7" }, - "packageManager": "pnpm@8.15.4" + "packageManager": "pnpm@8.15.7" } diff --git a/package.json b/package.json index 2cfe2af78f688c..2d9eced19d49d9 100644 --- a/package.json +++ b/package.json @@ -256,7 +256,7 @@ }, "engines": { "node": ">=18.17.0", - "pnpm": "8.15.4" + "pnpm": "8.15.7" }, - "packageManager": "pnpm@8.15.4" + "packageManager": "pnpm@8.15.7" } diff --git a/test/.stats-app/package.json b/test/.stats-app/package.json index 6df5695a60378f..299013ea72d1bd 100644 --- a/test/.stats-app/package.json +++ b/test/.stats-app/package.json @@ -9,7 +9,7 @@ }, "engines": { "node": ">=18.17.0", - "pnpm": "8.15.4" + "pnpm": "8.15.7" }, - "packageManager": "pnpm@8.15.4" + "packageManager": "pnpm@8.15.7" } From 9c83a3458c037ce316778aa6050f5b086fc0b80c Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 15 Apr 2024 07:56:53 -0700 Subject: [PATCH 04/96] Fix missing PagesOnly in 05-mdx (#64505) Looks like we have a syntax error in https://github.com/vercel/next.js/pull/63568 from missing closing `` tag. ```sh b383-75ab3d452c93.mdx:0:0: ERROR: [plugin: @mdx-js/esbuild] Expected a closing tag for `` (503:1-503:12) ``` x-ref: https://github.com/vercel/next.js/pull/63568 Closes NEXT-3111 --- .../01-building-your-application/07-configuring/05-mdx.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/02-app/01-building-your-application/07-configuring/05-mdx.mdx b/docs/02-app/01-building-your-application/07-configuring/05-mdx.mdx index 4cbbda31cf8b36..64b238ee346896 100644 --- a/docs/02-app/01-building-your-application/07-configuring/05-mdx.mdx +++ b/docs/02-app/01-building-your-application/07-configuring/05-mdx.mdx @@ -539,6 +539,8 @@ export default function MDXPage({ children }) { } ``` + + ## Frontmatter Frontmatter is a YAML like key/value pairing that can be used to store data about a page. `@next/mdx` does **not** support frontmatter by default, though there are many solutions for adding frontmatter to your MDX content, such as: From d6476dae843a59757dbbd79ceed4cf14a103a60d Mon Sep 17 00:00:00 2001 From: Abhay <2266146+pnutmath@users.noreply.github.com> Date: Mon, 15 Apr 2024 20:40:07 +0530 Subject: [PATCH 05/96] chore(docs): Add example usage of PixelBin custom image loader (#64074) ### Improving Documentation Integrate PixelBin Custom Image Loader for optimized image handling PixelBin is Real-time image transformations with automatic optimization, image URL and storage for efficient image organization ### References - [Resize Doc](https://www.pixelbin.io/docs/transformations/basic/resize/#width-w) - [Optimize Doc]( https://www.pixelbin.io/docs/optimizations/quality/#image-quality-when-delivering) ### Contributors - @pnutmath - @umesh162 Co-authored-by: Steven --- .../05-next-config-js/images.mdx | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/docs/02-app/02-api-reference/05-next-config-js/images.mdx b/docs/02-app/02-api-reference/05-next-config-js/images.mdx index 8c296d7c4d71f1..b0f14494ca4aec 100644 --- a/docs/02-app/02-api-reference/05-next-config-js/images.mdx +++ b/docs/02-app/02-api-reference/05-next-config-js/images.mdx @@ -61,10 +61,11 @@ To learn more about configuring the behavior of the built-in [Image Optimization - [Gumlet](#gumlet) - [ImageEngine](#imageengine) - [Imgix](#imgix) -- [Thumbor](#thumbor) +- [PixelBin](#pixelbin) - [Sanity](#sanity) - [Sirv](#sirv) - [Supabase](#supabase) +- [Thumbor](#thumbor) ### Akamai @@ -172,13 +173,16 @@ export default function imgixLoader({ src, width, quality }) { } ``` -### Thumbor +### PixelBin ```js -// Docs: https://thumbor.readthedocs.io/en/latest/ -export default function thumborLoader({ src, width, quality }) { - const params = [`${width}x0`, `filters:quality(${quality || 75})`] - return `https://example.com${params.join('/')}${src}` +// Doc (Resize): https://www.pixelbin.io/docs/transformations/basic/resize/#width-w +// Doc (Optimise): https://www.pixelbin.io/docs/optimizations/quality/#image-quality-when-delivering +// Doc (Auto Format Delivery): https://www.pixelbin.io/docs/optimizations/format/#automatic-format-selection-with-f_auto-url-parameter +export default function pixelBinLoader({ src, width, quality }) { + const name = '' + const opt = `t.resize(w:${width})~t.compress(q:${quality || 75})` + return `https://cdn.pixelbin.io/v2/${name}/${opt}/${src}?f_auto=true` } ``` @@ -225,3 +229,13 @@ export default function supabaseLoader({ src, width, quality }) { return url.href } ``` + +### Thumbor + +```js +// Docs: https://thumbor.readthedocs.io/en/latest/ +export default function thumborLoader({ src, width, quality }) { + const params = [`${width}x0`, `filters:quality(${quality || 75})`] + return `https://example.com${params.join('/')}${src}` +} +``` From bf8aecb182a4ecf7c578b916ecf40af3818d6a1c Mon Sep 17 00:00:00 2001 From: Vercel Release Bot <88769842+vercel-release-bot@users.noreply.github.com> Date: Mon, 15 Apr 2024 11:10:22 -0400 Subject: [PATCH 06/96] Update font data (#64481) This auto-generated PR updates font data with latest available Co-authored-by: JJ Kasper --- packages/font/src/google/font-data.json | 85 +++++++++++- packages/font/src/google/index.ts | 176 +++++++++++++++++++++++- 2 files changed, 256 insertions(+), 5 deletions(-) diff --git a/packages/font/src/google/font-data.json b/packages/font/src/google/font-data.json index 06566c6989c378..30e3508ce0657f 100644 --- a/packages/font/src/google/font-data.json +++ b/packages/font/src/google/font-data.json @@ -4009,8 +4009,16 @@ "subsets": ["latin", "malayalam"] }, "Gelasio": { - "weights": ["400", "500", "600", "700"], + "weights": ["400", "500", "600", "700", "variable"], "styles": ["normal", "italic"], + "axes": [ + { + "tag": "wght", + "min": 400, + "max": 700, + "defaultValue": 400 + } + ], "subsets": ["latin", "latin-ext", "vietnamese"] }, "Gemunu Libre": { @@ -5142,11 +5150,26 @@ "styles": ["normal"], "subsets": ["latin", "latin-ext", "thai", "vietnamese"] }, + "Jacquard 12 Charted": { + "weights": ["400"], + "styles": ["normal"], + "subsets": ["latin", "latin-ext", "math", "symbols"] + }, + "Jacquard 24": { + "weights": ["400"], + "styles": ["normal"], + "subsets": ["latin", "latin-ext"] + }, "Jacquarda Bastarda 9": { "weights": ["400"], "styles": ["normal"], "subsets": ["latin", "latin-ext", "math", "symbols"] }, + "Jacquarda Bastarda 9 Charted": { + "weights": ["400"], + "styles": ["normal"], + "subsets": ["latin", "latin-ext", "math", "symbols"] + }, "Jacques Francois": { "weights": ["400"], "styles": ["normal"], @@ -5162,6 +5185,41 @@ "styles": ["normal"], "subsets": ["devanagari", "latin", "latin-ext"] }, + "Jersey 10": { + "weights": ["400"], + "styles": ["normal"], + "subsets": ["latin", "latin-ext"] + }, + "Jersey 10 Charted": { + "weights": ["400"], + "styles": ["normal"], + "subsets": ["latin", "latin-ext"] + }, + "Jersey 15": { + "weights": ["400"], + "styles": ["normal"], + "subsets": ["latin", "latin-ext"] + }, + "Jersey 15 Charted": { + "weights": ["400"], + "styles": ["normal"], + "subsets": ["latin", "latin-ext"] + }, + "Jersey 20": { + "weights": ["400"], + "styles": ["normal"], + "subsets": ["latin", "latin-ext"] + }, + "Jersey 20 Charted": { + "weights": ["400"], + "styles": ["normal"], + "subsets": ["latin", "latin-ext"] + }, + "Jersey 25": { + "weights": ["400"], + "styles": ["normal"], + "subsets": ["latin", "latin-ext"] + }, "JetBrains Mono": { "weights": [ "100", @@ -6828,6 +6886,11 @@ "styles": ["normal"], "subsets": ["latin", "latin-ext", "math", "symbols"] }, + "Micro 5 Charted": { + "weights": ["400"], + "styles": ["normal"], + "subsets": ["latin", "latin-ext", "math", "symbols"] + }, "Milonga": { "weights": ["400"], "styles": ["normal"], @@ -7417,7 +7480,7 @@ "defaultValue": 400 } ], - "subsets": ["arabic", "latin", "latin-ext"] + "subsets": ["arabic", "latin", "latin-ext", "math", "symbols"] }, "Noto Nastaliq Urdu": { "weights": ["400", "500", "600", "700", "variable"], @@ -10708,6 +10771,19 @@ "styles": ["normal"], "subsets": ["latin", "latin-ext"] }, + "Platypi": { + "weights": ["300", "400", "500", "600", "700", "800", "variable"], + "styles": ["normal", "italic"], + "axes": [ + { + "tag": "wght", + "min": 300, + "max": 800, + "defaultValue": 400 + } + ], + "subsets": ["latin", "latin-ext", "vietnamese"] + }, "Play": { "weights": ["400", "700"], "styles": ["normal"], @@ -12260,6 +12336,11 @@ "styles": ["normal"], "subsets": ["hebrew", "latin", "latin-ext"] }, + "Sedan": { + "weights": ["400"], + "styles": ["normal", "italic"], + "subsets": ["latin", "latin-ext"] + }, "Sedgwick Ave": { "weights": ["400"], "styles": ["normal"], diff --git a/packages/font/src/google/index.ts b/packages/font/src/google/index.ts index ffe39bf9880cdd..e710b6c4d2e4b1 100644 --- a/packages/font/src/google/index.ts +++ b/packages/font/src/google/index.ts @@ -7134,8 +7134,14 @@ export declare function Gayathri< }): T extends undefined ? NextFont : NextFontWithVariable export declare function Gelasio< T extends CssVariable | undefined = undefined ->(options: { - weight: '400' | '500' | '600' | '700' | Array<'400' | '500' | '600' | '700'> +>(options?: { + weight?: + | '400' + | '500' + | '600' + | '700' + | 'variable' + | Array<'400' | '500' | '600' | '700'> style?: 'normal' | 'italic' | Array<'normal' | 'italic'> display?: Display variable?: T @@ -9167,6 +9173,30 @@ export declare function Itim< adjustFontFallback?: boolean subsets?: Array<'latin' | 'latin-ext' | 'thai' | 'vietnamese'> }): T extends undefined ? NextFont : NextFontWithVariable +export declare function Jacquard_12_Charted< + T extends CssVariable | undefined = undefined +>(options: { + weight: '400' | Array<'400'> + style?: 'normal' | Array<'normal'> + display?: Display + variable?: T + preload?: boolean + fallback?: string[] + adjustFontFallback?: boolean + subsets?: Array<'latin' | 'latin-ext' | 'math' | 'symbols'> +}): T extends undefined ? NextFont : NextFontWithVariable +export declare function Jacquard_24< + T extends CssVariable | undefined = undefined +>(options: { + weight: '400' | Array<'400'> + style?: 'normal' | Array<'normal'> + display?: Display + variable?: T + preload?: boolean + fallback?: string[] + adjustFontFallback?: boolean + subsets?: Array<'latin' | 'latin-ext'> +}): T extends undefined ? NextFont : NextFontWithVariable export declare function Jacquarda_Bastarda_9< T extends CssVariable | undefined = undefined >(options: { @@ -9179,6 +9209,18 @@ export declare function Jacquarda_Bastarda_9< adjustFontFallback?: boolean subsets?: Array<'latin' | 'latin-ext' | 'math' | 'symbols'> }): T extends undefined ? NextFont : NextFontWithVariable +export declare function Jacquarda_Bastarda_9_Charted< + T extends CssVariable | undefined = undefined +>(options: { + weight: '400' | Array<'400'> + style?: 'normal' | Array<'normal'> + display?: Display + variable?: T + preload?: boolean + fallback?: string[] + adjustFontFallback?: boolean + subsets?: Array<'latin' | 'latin-ext' | 'math' | 'symbols'> +}): T extends undefined ? NextFont : NextFontWithVariable export declare function Jacques_Francois< T extends CssVariable | undefined = undefined >(options: { @@ -9215,6 +9257,90 @@ export declare function Jaldi< adjustFontFallback?: boolean subsets?: Array<'devanagari' | 'latin' | 'latin-ext'> }): T extends undefined ? NextFont : NextFontWithVariable +export declare function Jersey_10< + T extends CssVariable | undefined = undefined +>(options: { + weight: '400' | Array<'400'> + style?: 'normal' | Array<'normal'> + display?: Display + variable?: T + preload?: boolean + fallback?: string[] + adjustFontFallback?: boolean + subsets?: Array<'latin' | 'latin-ext'> +}): T extends undefined ? NextFont : NextFontWithVariable +export declare function Jersey_10_Charted< + T extends CssVariable | undefined = undefined +>(options: { + weight: '400' | Array<'400'> + style?: 'normal' | Array<'normal'> + display?: Display + variable?: T + preload?: boolean + fallback?: string[] + adjustFontFallback?: boolean + subsets?: Array<'latin' | 'latin-ext'> +}): T extends undefined ? NextFont : NextFontWithVariable +export declare function Jersey_15< + T extends CssVariable | undefined = undefined +>(options: { + weight: '400' | Array<'400'> + style?: 'normal' | Array<'normal'> + display?: Display + variable?: T + preload?: boolean + fallback?: string[] + adjustFontFallback?: boolean + subsets?: Array<'latin' | 'latin-ext'> +}): T extends undefined ? NextFont : NextFontWithVariable +export declare function Jersey_15_Charted< + T extends CssVariable | undefined = undefined +>(options: { + weight: '400' | Array<'400'> + style?: 'normal' | Array<'normal'> + display?: Display + variable?: T + preload?: boolean + fallback?: string[] + adjustFontFallback?: boolean + subsets?: Array<'latin' | 'latin-ext'> +}): T extends undefined ? NextFont : NextFontWithVariable +export declare function Jersey_20< + T extends CssVariable | undefined = undefined +>(options: { + weight: '400' | Array<'400'> + style?: 'normal' | Array<'normal'> + display?: Display + variable?: T + preload?: boolean + fallback?: string[] + adjustFontFallback?: boolean + subsets?: Array<'latin' | 'latin-ext'> +}): T extends undefined ? NextFont : NextFontWithVariable +export declare function Jersey_20_Charted< + T extends CssVariable | undefined = undefined +>(options: { + weight: '400' | Array<'400'> + style?: 'normal' | Array<'normal'> + display?: Display + variable?: T + preload?: boolean + fallback?: string[] + adjustFontFallback?: boolean + subsets?: Array<'latin' | 'latin-ext'> +}): T extends undefined ? NextFont : NextFontWithVariable +export declare function Jersey_25< + T extends CssVariable | undefined = undefined +>(options: { + weight: '400' | Array<'400'> + style?: 'normal' | Array<'normal'> + display?: Display + variable?: T + preload?: boolean + fallback?: string[] + adjustFontFallback?: boolean + subsets?: Array<'latin' | 'latin-ext'> +}): T extends undefined ? NextFont : NextFontWithVariable export declare function JetBrains_Mono< T extends CssVariable | undefined = undefined >(options?: { @@ -12262,6 +12388,18 @@ export declare function Micro_5< adjustFontFallback?: boolean subsets?: Array<'latin' | 'latin-ext' | 'math' | 'symbols'> }): T extends undefined ? NextFont : NextFontWithVariable +export declare function Micro_5_Charted< + T extends CssVariable | undefined = undefined +>(options: { + weight: '400' | Array<'400'> + style?: 'normal' | Array<'normal'> + display?: Display + variable?: T + preload?: boolean + fallback?: string[] + adjustFontFallback?: boolean + subsets?: Array<'latin' | 'latin-ext' | 'math' | 'symbols'> +}): T extends undefined ? NextFont : NextFontWithVariable export declare function Milonga< T extends CssVariable | undefined = undefined >(options: { @@ -13488,7 +13626,7 @@ export declare function Noto_Naskh_Arabic< preload?: boolean fallback?: string[] adjustFontFallback?: boolean - subsets?: Array<'arabic' | 'latin' | 'latin-ext'> + subsets?: Array<'arabic' | 'latin' | 'latin-ext' | 'math' | 'symbols'> }): T extends undefined ? NextFont : NextFontWithVariable export declare function Noto_Nastaliq_Urdu< T extends CssVariable | undefined = undefined @@ -18207,6 +18345,26 @@ export declare function Plaster< adjustFontFallback?: boolean subsets?: Array<'latin' | 'latin-ext'> }): T extends undefined ? NextFont : NextFontWithVariable +export declare function Platypi< + T extends CssVariable | undefined = undefined +>(options?: { + weight?: + | '300' + | '400' + | '500' + | '600' + | '700' + | '800' + | 'variable' + | Array<'300' | '400' | '500' | '600' | '700' | '800'> + style?: 'normal' | 'italic' | Array<'normal' | 'italic'> + display?: Display + variable?: T + preload?: boolean + fallback?: string[] + adjustFontFallback?: boolean + subsets?: Array<'latin' | 'latin-ext' | 'vietnamese'> +}): T extends undefined ? NextFont : NextFontWithVariable export declare function Play< T extends CssVariable | undefined = undefined >(options: { @@ -20902,6 +21060,18 @@ export declare function Secular_One< adjustFontFallback?: boolean subsets?: Array<'hebrew' | 'latin' | 'latin-ext'> }): T extends undefined ? NextFont : NextFontWithVariable +export declare function Sedan< + T extends CssVariable | undefined = undefined +>(options: { + weight: '400' | Array<'400'> + style?: 'normal' | 'italic' | Array<'normal' | 'italic'> + display?: Display + variable?: T + preload?: boolean + fallback?: string[] + adjustFontFallback?: boolean + subsets?: Array<'latin' | 'latin-ext'> +}): T extends undefined ? NextFont : NextFontWithVariable export declare function Sedgwick_Ave< T extends CssVariable | undefined = undefined >(options: { From e7a8645cb8cb14e82d9c293fc80664295dd7fe66 Mon Sep 17 00:00:00 2001 From: Damien Simonin Feugas Date: Mon, 15 Apr 2024 17:23:30 +0200 Subject: [PATCH 07/96] BREAKING CHANGE: remove deprecated analyticsId from config, and the corresponding performance-relayer files and tests (#64199) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### 🤔 What's in there? We've deprecated config's `analyticsId` in 14.1.1 [almost 3 months ago](https://github.com/vercel/next.js/releases/tag/v14.1.1-canary.2). Users can opt in fot `@vercel/speed-insights`, or use `useReportWebVitals` to report to any provider they'd like. This PR: - removes `analyticsId` key from configuration - stops setting `__NEXT_PUBLIC_ANALYTICS_ID` env variable when the key was present - stops injecting `performance-relayer` file, when the variable is set - cleans up related test code. --- .../04-functions/use-report-web-vitals.mdx | 3 +- .../crates/next-core/src/next_config.rs | 1 - packages/next/src/build/index.ts | 7 - .../webpack/plugins/define-env-plugin.ts | 1 - packages/next/src/cli/next-dev.ts | 7 - packages/next/src/client/app-index.tsx | 8 - packages/next/src/client/index.tsx | 7 - .../src/client/performance-relayer-app.ts | 104 ------------ .../next/src/client/performance-relayer.ts | 102 ----------- packages/next/src/server/config-schema.ts | 1 - packages/next/src/server/config-shared.ts | 11 -- .../app-dir/app/useReportWebVitals.test.ts | 2 +- .../app-dir/app/vercel-speed-insights.test.ts | 83 --------- .../relay-analytics-disabled/pages/_app.js | 15 -- .../relay-analytics-disabled/pages/index.js | 25 --- .../test/index.test.js | 78 --------- .../relay-analytics/next.config.js | 5 - .../integration/relay-analytics/pages/_app.js | 23 --- .../relay-analytics/pages/index.js | 36 ---- .../relay-analytics/test/index.test.js | 158 ------------------ test/turbopack-build-tests-manifest.json | 4 +- test/turbopack-dev-tests-manifest.json | 4 +- 22 files changed, 5 insertions(+), 680 deletions(-) delete mode 100644 packages/next/src/client/performance-relayer-app.ts delete mode 100644 packages/next/src/client/performance-relayer.ts delete mode 100644 test/e2e/app-dir/app/vercel-speed-insights.test.ts delete mode 100644 test/integration/relay-analytics-disabled/pages/_app.js delete mode 100644 test/integration/relay-analytics-disabled/pages/index.js delete mode 100644 test/integration/relay-analytics-disabled/test/index.test.js delete mode 100644 test/integration/relay-analytics/next.config.js delete mode 100644 test/integration/relay-analytics/pages/_app.js delete mode 100644 test/integration/relay-analytics/pages/index.js delete mode 100644 test/integration/relay-analytics/test/index.test.js diff --git a/docs/02-app/02-api-reference/04-functions/use-report-web-vitals.mdx b/docs/02-app/02-api-reference/04-functions/use-report-web-vitals.mdx index 74103b6be4c14d..2ed2d08f2bee6e 100644 --- a/docs/02-app/02-api-reference/04-functions/use-report-web-vitals.mdx +++ b/docs/02-app/02-api-reference/04-functions/use-report-web-vitals.mdx @@ -194,7 +194,8 @@ These metrics work in all browsers that support the [User Timing API](https://ca ## Usage on Vercel -[Vercel Speed Insights](https://vercel.com/docs/concepts/speed-insights) are automatically configured on Vercel deployments, and don't require the use of `useReportWebVitals`. This hook is useful in local development, or if you're using a different analytics service. +[Vercel Speed Insights](https://vercel.com/docs/speed-insights/quickstart) does not `useReportWebVitals`, but `@vercel/speed-insights` package instead. +`useReportWebVitals` hook is useful in local development, or if you're using a different service for collecting Web Vitals. ## Sending results to external systems diff --git a/packages/next-swc/crates/next-core/src/next_config.rs b/packages/next-swc/crates/next-core/src/next_config.rs index 2216dfdbe1f8ba..1b284145cd85a8 100644 --- a/packages/next-swc/crates/next-core/src/next_config.rs +++ b/packages/next-swc/crates/next-core/src/next_config.rs @@ -83,7 +83,6 @@ pub struct NextConfig { pub cross_origin: Option, pub dev_indicators: Option, pub output: Option, - pub analytics_id: Option, #[serde(rename = "_originalRedirects")] pub original_redirects: Option>, diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts index d5c68ec9b97733..1e0f73e6bac0c1 100644 --- a/packages/next/src/build/index.ts +++ b/packages/next/src/build/index.ts @@ -3358,13 +3358,6 @@ export default async function build( return Promise.reject(err) }) - // TODO: remove in the next major version - if (config.analyticsId) { - Log.warn( - `\`config.analyticsId\` is deprecated and will be removed in next major version. Read more: https://nextjs.org/docs/messages/deprecated-analyticsid` - ) - } - if (Boolean(config.experimental.nextScriptWorkers)) { await nextBuildSpan .traceChild('verify-partytown-setup') diff --git a/packages/next/src/build/webpack/plugins/define-env-plugin.ts b/packages/next/src/build/webpack/plugins/define-env-plugin.ts index aea7e34537f2db..ecd022f9e2c2ea 100644 --- a/packages/next/src/build/webpack/plugins/define-env-plugin.ts +++ b/packages/next/src/build/webpack/plugins/define-env-plugin.ts @@ -225,7 +225,6 @@ export function getDefineEnv({ 'process.env.__NEXT_CONFIG_OUTPUT': config.output, 'process.env.__NEXT_I18N_SUPPORT': !!config.i18n, 'process.env.__NEXT_I18N_DOMAINS': config.i18n?.domains ?? false, - 'process.env.__NEXT_ANALYTICS_ID': config.analyticsId, // TODO: remove in the next major version 'process.env.__NEXT_NO_MIDDLEWARE_URL_NORMALIZE': config.skipMiddlewareUrlNormalize, 'process.env.__NEXT_EXTERNAL_MIDDLEWARE_REWRITE_RESOLVE': diff --git a/packages/next/src/cli/next-dev.ts b/packages/next/src/cli/next-dev.ts index f8d7ba0e6680b5..4abc0d8db73182 100644 --- a/packages/next/src/cli/next-dev.ts +++ b/packages/next/src/cli/next-dev.ts @@ -200,13 +200,6 @@ const nextDev = async ( traceUploadUrl = options.experimentalUploadTrace } - // TODO: remove in the next major version - if (config.analyticsId) { - Log.warn( - `\`config.analyticsId\` is deprecated and will be removed in next major version. Read more: https://nextjs.org/docs/messages/deprecated-analyticsid` - ) - } - const devServerOptions: StartServerOptions = { dir, port, diff --git a/packages/next/src/client/app-index.tsx b/packages/next/src/client/app-index.tsx index e4c9d7632d7b8d..f54d9ac06ca394 100644 --- a/packages/next/src/client/app-index.tsx +++ b/packages/next/src/client/app-index.tsx @@ -131,14 +131,6 @@ const StrictModeIfEnabled = process.env.__NEXT_STRICT_MODE_APP : React.Fragment function Root({ children }: React.PropsWithChildren<{}>) { - // TODO: remove in the next major version - if (process.env.__NEXT_ANALYTICS_ID) { - // eslint-disable-next-line react-hooks/rules-of-hooks - React.useEffect(() => { - require('./performance-relayer-app')() - }, []) - } - if (process.env.__NEXT_TEST_MODE) { // eslint-disable-next-line react-hooks/rules-of-hooks React.useEffect(() => { diff --git a/packages/next/src/client/index.tsx b/packages/next/src/client/index.tsx index dc5ba991c6450c..2af72e60a5bfc0 100644 --- a/packages/next/src/client/index.tsx +++ b/packages/next/src/client/index.tsx @@ -27,7 +27,6 @@ import { Portal } from './portal' import initHeadManager from './head-manager' import PageLoader from './page-loader' import type { StyleSheetTuple } from './page-loader' -import measureWebVitals from './performance-relayer' // TODO: remove in the next major version import { RouteAnnouncer } from './route-announcer' import { createRouter, makePublicRouterInstance } from './router' import { getProperError } from '../lib/is-error' @@ -604,12 +603,6 @@ function Root({ () => callbacks.forEach((callback) => callback()), [callbacks] ) - // TODO: remove in the next major version - // We should ask to measure the Web Vitals after rendering completes so we - // don't cause any hydration delay: - React.useEffect(() => { - measureWebVitals(onPerfEntry) - }, []) if (process.env.__NEXT_TEST_MODE) { // eslint-disable-next-line react-hooks/rules-of-hooks diff --git a/packages/next/src/client/performance-relayer-app.ts b/packages/next/src/client/performance-relayer-app.ts deleted file mode 100644 index 9dea54164db612..00000000000000 --- a/packages/next/src/client/performance-relayer-app.ts +++ /dev/null @@ -1,104 +0,0 @@ -// TODO: remove in the next major version -/* global location */ -import type { Metric, ReportCallback } from 'next/dist/compiled/web-vitals' - -// copied to prevent pulling in un-necessary utils -const WEB_VITALS = ['CLS', 'FCP', 'FID', 'INP', 'LCP', 'TTFB'] - -const initialHref = location.href -let isRegistered = false -let userReportHandler: ReportCallback | undefined -type Attribution = (typeof WEB_VITALS)[number] - -function onReport(metric: Metric): void { - if (userReportHandler) { - userReportHandler(metric) - } - - // This code is not shipped, executed, or present in the client-side - // JavaScript bundle unless explicitly enabled in your application. - // - // When this feature is enabled, we'll make it very clear by printing a - // message during the build (`next build`). - if ( - process.env.NODE_ENV === 'production' && - // This field is empty unless you explicitly configure it: - process.env.__NEXT_ANALYTICS_ID - ) { - const body: Record = { - dsn: process.env.__NEXT_ANALYTICS_ID, - id: metric.id, - page: window.__NEXT_DATA__?.page, - href: initialHref, - event_name: metric.name, - value: metric.value.toString(), - speed: - 'connection' in navigator && - (navigator as any)['connection'] && - 'effectiveType' in (navigator as any)['connection'] - ? ((navigator as any)['connection']['effectiveType'] as string) - : '', - } - - const blob = new Blob([new URLSearchParams(body).toString()], { - // This content type is necessary for `sendBeacon`: - type: 'application/x-www-form-urlencoded', - }) - const vitalsUrl = 'https://vitals.vercel-insights.com/v1/vitals' - // Navigator has to be bound to ensure it does not error in some browsers - // https://xgwang.me/posts/you-may-not-know-beacon/#it-may-throw-error%2C-be-sure-to-catch - const send = navigator.sendBeacon && navigator.sendBeacon.bind(navigator) - - function fallbackSend() { - fetch(vitalsUrl, { - body: blob, - method: 'POST', - credentials: 'omit', - keepalive: true, - // console.error is used here as when the fetch fails it does not affect functioning of the app - }).catch(console.error) - } - - try { - // If send is undefined it'll throw as well. This reduces output code size. - send!(vitalsUrl, blob) || fallbackSend() - } catch (err) { - fallbackSend() - } - } -} - -export default (onPerfEntry?: ReportCallback): void => { - if (process.env.__NEXT_ANALYTICS_ID) { - // Update function if it changes: - userReportHandler = onPerfEntry - - // Only register listeners once: - if (isRegistered) { - return - } - isRegistered = true - - const attributions: Attribution[] | undefined = process.env - .__NEXT_WEB_VITALS_ATTRIBUTION as any - - for (const webVital of WEB_VITALS) { - try { - let mod: any - - if (process.env.__NEXT_HAS_WEB_VITALS_ATTRIBUTION) { - if (attributions?.includes(webVital)) { - mod = require('next/dist/compiled/web-vitals-attribution') - } - } - if (!mod) { - mod = require('next/dist/compiled/web-vitals') - } - mod[`on${webVital}`](onReport) - } catch (err) { - // Do nothing if the module fails to load - console.warn(`Failed to track ${webVital} web-vital`, err) - } - } - } -} diff --git a/packages/next/src/client/performance-relayer.ts b/packages/next/src/client/performance-relayer.ts deleted file mode 100644 index eef50765085de7..00000000000000 --- a/packages/next/src/client/performance-relayer.ts +++ /dev/null @@ -1,102 +0,0 @@ -// TODO: remove in the next major version -/* global location */ -import type { Metric, ReportCallback } from 'next/dist/compiled/web-vitals' - -// copied to prevent pulling in un-necessary utils -const WEB_VITALS = ['CLS', 'FCP', 'FID', 'INP', 'LCP', 'TTFB'] - -const initialHref = location.href -let isRegistered = false -let userReportHandler: ReportCallback | undefined -type Attribution = (typeof WEB_VITALS)[number] - -function onReport(metric: Metric): void { - if (userReportHandler) { - userReportHandler(metric) - } - - // This code is not shipped, executed, or present in the client-side - // JavaScript bundle unless explicitly enabled in your application. - // - // When this feature is enabled, we'll make it very clear by printing a - // message during the build (`next build`). - if ( - process.env.NODE_ENV === 'production' && - // This field is empty unless you explicitly configure it: - process.env.__NEXT_ANALYTICS_ID - ) { - const body: Record = { - dsn: process.env.__NEXT_ANALYTICS_ID, - id: metric.id, - page: window.__NEXT_DATA__?.page, - href: initialHref, - event_name: metric.name, - value: metric.value.toString(), - speed: - 'connection' in navigator && - (navigator as any)['connection'] && - 'effectiveType' in (navigator as any)['connection'] - ? ((navigator as any)['connection']['effectiveType'] as string) - : '', - } - - const blob = new Blob([new URLSearchParams(body).toString()], { - // This content type is necessary for `sendBeacon`: - type: 'application/x-www-form-urlencoded', - }) - const vitalsUrl = 'https://vitals.vercel-insights.com/v1/vitals' - // Navigator has to be bound to ensure it does not error in some browsers - // https://xgwang.me/posts/you-may-not-know-beacon/#it-may-throw-error%2C-be-sure-to-catch - const send = navigator.sendBeacon && navigator.sendBeacon.bind(navigator) - - function fallbackSend() { - fetch(vitalsUrl, { - body: blob, - method: 'POST', - credentials: 'omit', - keepalive: true, - // console.error is used here as when the fetch fails it does not affect functioning of the app - }).catch(console.error) - } - - try { - // If send is undefined it'll throw as well. This reduces output code size. - send!(vitalsUrl, blob) || fallbackSend() - } catch (err) { - fallbackSend() - } - } -} - -export default (onPerfEntry?: ReportCallback): void => { - // Update function if it changes: - userReportHandler = onPerfEntry - - // Only register listeners once: - if (isRegistered) { - return - } - isRegistered = true - - const attributions: Attribution[] | undefined = process.env - .__NEXT_WEB_VITALS_ATTRIBUTION as any - - for (const webVital of WEB_VITALS) { - try { - let mod: any - - if (process.env.__NEXT_HAS_WEB_VITALS_ATTRIBUTION) { - if (attributions?.includes(webVital)) { - mod = require('next/dist/compiled/web-vitals-attribution') - } - } - if (!mod) { - mod = require('next/dist/compiled/web-vitals') - } - mod[`on${webVital}`](onReport) - } catch (err) { - // Do nothing if the module fails to load - console.warn(`Failed to track ${webVital} web-vital`, err) - } - } -} diff --git a/packages/next/src/server/config-schema.ts b/packages/next/src/server/config-schema.ts index 8d0978edb0f4fc..6dddc6ae6d3ef7 100644 --- a/packages/next/src/server/config-schema.ts +++ b/packages/next/src/server/config-schema.ts @@ -130,7 +130,6 @@ export const configSchema: zod.ZodType = z.lazy(() => canonicalBase: z.string().optional(), }) .optional(), - analyticsId: z.string().optional(), // TODO: remove in the next major version assetPrefix: z.string().optional(), basePath: z.string().optional(), cacheHandler: z.string().min(1).optional(), diff --git a/packages/next/src/server/config-shared.ts b/packages/next/src/server/config-shared.ts index a10f1748a137a1..7d2a458d9acae2 100644 --- a/packages/next/src/server/config-shared.ts +++ b/packages/next/src/server/config-shared.ts @@ -603,16 +603,6 @@ export interface NextConfig extends Record { /** @see [Compression documentation](https://nextjs.org/docs/api-reference/next.config.js/compression) */ compress?: boolean - /** - * The field should only be used when a Next.js project is not hosted on Vercel while using Vercel Speed Insights. - * Vercel provides zero-configuration insights for Next.js projects hosted on Vercel. - * - * @default '' - * @deprecated will be removed in next major version. Read more: https://nextjs.org/docs/messages/deprecated-analyticsid - * @see [how to fix deprecated analyticsId](https://nextjs.org/docs/messages/deprecated-analyticsid) - */ - analyticsId?: string - /** @see [Disabling x-powered-by](https://nextjs.org/docs/api-reference/next.config.js/disabling-x-powered-by) */ poweredByHeader?: boolean @@ -844,7 +834,6 @@ export const defaultConfig: NextConfig = { pageExtensions: ['tsx', 'ts', 'jsx', 'js'], poweredByHeader: true, compress: true, - analyticsId: process.env.VERCEL_ANALYTICS_ID || '', // TODO: remove in the next major version images: imageConfigDefault, devIndicators: { buildActivity: true, diff --git a/test/e2e/app-dir/app/useReportWebVitals.test.ts b/test/e2e/app-dir/app/useReportWebVitals.test.ts index 6afeff90d70ad0..20245bedbcb405 100644 --- a/test/e2e/app-dir/app/useReportWebVitals.test.ts +++ b/test/e2e/app-dir/app/useReportWebVitals.test.ts @@ -17,7 +17,7 @@ describe('useReportWebVitals hook', () => { afterAll(() => next.destroy()) // Analytics events are only sent in production - it('should send web-vitals to vercel-insights', async () => { + it('should send web-vitals', async () => { await next.fetch('/report-web-vitals') let eventsCount = 0 diff --git a/test/e2e/app-dir/app/vercel-speed-insights.test.ts b/test/e2e/app-dir/app/vercel-speed-insights.test.ts deleted file mode 100644 index 6aa42388695159..00000000000000 --- a/test/e2e/app-dir/app/vercel-speed-insights.test.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { createNext } from 'e2e-utils' -import { NextInstance } from 'e2e-utils' -import { check } from 'next-test-utils' - -describe('vercel speed insights', () => { - const isDev = (global as any).isNextDev - - if ((global as any).isNextDeploy) { - it('should skip next deploy for now', () => {}) - return - } - - let next: NextInstance - - function runTests({ assetPrefix }: { assetPrefix?: boolean }) { - beforeAll(async () => { - next = await createNext({ - files: __dirname, - skipStart: true, - env: { - VERCEL_ANALYTICS_ID: 'fake-analytics-id', - }, - }) - - if (assetPrefix) { - const content = await next.readFile('next.config.js') - await next.patchFile( - 'next.config.js', - content - .replace('// assetPrefix', 'assetPrefix') - .replace('// beforeFiles', 'beforeFiles') - ) - } - await next.start() - }) - afterAll(() => next.destroy()) - - // Analytics events are only sent in production - ;(isDev ? describe.skip : describe)('Vercel analytics', () => { - it('should send web vitals to Vercel analytics', async () => { - expect(next.cliOutput).toMatch( - '`config.analyticsId` is deprecated and will be removed in next major version. Read more: https://nextjs.org/docs/messages/deprecated-analyticsid' - ) - let eventsCount = 0 - let countEvents = false - const browser = await next.browser('/client-nested', { - beforePageLoad(page) { - page.route( - 'https://vitals.vercel-insights.com/v1/vitals', - (route) => { - if (countEvents) { - eventsCount += 1 - } - - route.fulfill() - } - ) - }, - }) - - // Start counting analytics events - countEvents = true - - // Refresh will trigger CLS and LCP. When page loads FCP and TTFB will trigger: - await browser.refresh() - - // After interaction LCP and FID will trigger - await browser.elementByCss('button').click() - - // Make sure all registered events in performance-relayer has fired - await check(() => eventsCount, /6/) - }) - }) - } - - describe('without assetPrefix', () => { - runTests({}) - }) - - describe('with assetPrefix', () => { - runTests({ assetPrefix: true }) - }) -}) diff --git a/test/integration/relay-analytics-disabled/pages/_app.js b/test/integration/relay-analytics-disabled/pages/_app.js deleted file mode 100644 index 5cc9a4d4848885..00000000000000 --- a/test/integration/relay-analytics-disabled/pages/_app.js +++ /dev/null @@ -1,15 +0,0 @@ -/* global localStorage */ -/* eslint-disable camelcase */ -import App from 'next/app' - -export default class MyApp extends App {} - -/* - Method is experimental and will eventually be handled in a Next.js plugin -*/ -export function reportWebVitals(data) { - localStorage.setItem( - data.name || data.entryType, - data.value !== undefined ? data.value : data.startTime - ) -} diff --git a/test/integration/relay-analytics-disabled/pages/index.js b/test/integration/relay-analytics-disabled/pages/index.js deleted file mode 100644 index 46c828a80fd0d4..00000000000000 --- a/test/integration/relay-analytics-disabled/pages/index.js +++ /dev/null @@ -1,25 +0,0 @@ -if (typeof navigator !== 'undefined') { - window.__BEACONS = window.__BEACONS || [] - - navigator.sendBeacon = async function () { - const args = await Promise.all( - [...arguments].map((v) => { - if (v instanceof Blob) { - return v.text() - } - return v - }) - ) - - window.__BEACONS.push(args) - } -} - -export default () => { - return ( -
-

Foo!

-

bar!

-
- ) -} diff --git a/test/integration/relay-analytics-disabled/test/index.test.js b/test/integration/relay-analytics-disabled/test/index.test.js deleted file mode 100644 index e77574852ccfd5..00000000000000 --- a/test/integration/relay-analytics-disabled/test/index.test.js +++ /dev/null @@ -1,78 +0,0 @@ -/* eslint-env jest */ - -import fs from 'fs-extra' -import { findPort, killApp, nextBuild, nextStart } from 'next-test-utils' -import webdriver from 'next-webdriver' -import path, { join } from 'path' - -const appDir = join(__dirname, '../') -let appPort -let server - -let buildManifest - -describe('Analytics relayer (disabled)', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - let stdout - beforeAll(async () => { - appPort = await findPort() - ;({ stdout } = await nextBuild(appDir, [], { - stdout: true, - })) - buildManifest = require(path.join( - appDir, - '.next/build-manifest.json' - ), 'utf8') - server = await nextStart(appDir, appPort) - }) - afterAll(() => killApp(server)) - - it('Does not relay any data', async () => { - const browser = await webdriver(appPort, '/') - await browser.waitForElementByCss('h1') - const h1Text = await browser.elementByCss('h1').text() - const firstContentfulPaint = parseFloat( - await browser.eval('localStorage.getItem("FCP")') - ) - - expect(h1Text).toMatch(/Foo!/) - - expect(firstContentfulPaint).not.toBeNaN() - expect(firstContentfulPaint).toBeGreaterThan(0) - - const beacons = (await browser.eval('window.__BEACONS')).map( - ([, value]) => Object.fromEntries(new URLSearchParams(value)) - ) - - expect(beacons.length).toBe(0) - - expect(stdout).not.toMatch('Next.js Speed Insights') - - await browser.close() - }) - - it('Does not include the code', async () => { - const pageFiles = [ - ...new Set([ - ...buildManifest.pages['/'].filter((file) => file.endsWith('.js')), - ...buildManifest.pages['/_app'].filter((file) => - file.endsWith('.js') - ), - ]), - ] - - expect(pageFiles.length).toBeGreaterThan(1) - - for (const pageFile of pageFiles) { - const content = await fs.readFile( - path.join(appDir, '.next', pageFile), - 'utf8' - ) - expect(content).not.toMatch('vercel-insights') - } - }) - } - ) -}) diff --git a/test/integration/relay-analytics/next.config.js b/test/integration/relay-analytics/next.config.js deleted file mode 100644 index 49ebc0dda6a7a2..00000000000000 --- a/test/integration/relay-analytics/next.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - experimental: { - webVitalsAttribution: ['CLS', 'LCP'], - }, -} diff --git a/test/integration/relay-analytics/pages/_app.js b/test/integration/relay-analytics/pages/_app.js deleted file mode 100644 index bea92c33b7215e..00000000000000 --- a/test/integration/relay-analytics/pages/_app.js +++ /dev/null @@ -1,23 +0,0 @@ -/* global localStorage */ -/* eslint-disable camelcase */ -import App from 'next/app' - -export default class MyApp extends App {} - -/* - Method is experimental and will eventually be handled in a Next.js plugin -*/ - -export function reportWebVitals(data) { - const name = data.name || data.entryType - localStorage.setItem( - name, - data.value !== undefined ? data.value : data.startTime - ) - const countMap = window.__BEACONS_COUNT - countMap.set(name, (countMap.get(name) || 0) + 1) - - if (data.attribution) { - ;(window.__metricsWithAttribution ??= []).push(data) - } -} diff --git a/test/integration/relay-analytics/pages/index.js b/test/integration/relay-analytics/pages/index.js deleted file mode 100644 index 21839b1f6776e5..00000000000000 --- a/test/integration/relay-analytics/pages/index.js +++ /dev/null @@ -1,36 +0,0 @@ -if (typeof navigator !== 'undefined') { - window.__BEACONS = window.__BEACONS || [] - window.__BEACONS_COUNT = new Map() - - navigator.sendBeacon = async function () { - const args = await Promise.all( - [...arguments].map((v) => { - if (v instanceof Blob) { - return v.text() - } - return v - }) - ) - - window.__BEACONS.push(args) - } -} - -function toggleText(e) { - const startTime = performance.now() - while (performance.now() < startTime + 100) { - // busy waiting - } - e.target.textContent = e.target.textContent === 'Click' ? 'Press' : 'Click' -} - -export default () => { - // Below comment will be used for replacing exported report method with hook based one. - return ( -
-

Foo!

-

bar!

- -
- ) -} diff --git a/test/integration/relay-analytics/test/index.test.js b/test/integration/relay-analytics/test/index.test.js deleted file mode 100644 index 7101396c9b4c16..00000000000000 --- a/test/integration/relay-analytics/test/index.test.js +++ /dev/null @@ -1,158 +0,0 @@ -/* eslint-env jest */ - -import { join } from 'path' -import webdriver from 'next-webdriver' -import { killApp, findPort, nextBuild, nextStart, check } from 'next-test-utils' - -const appDir = join(__dirname, '../') - -let appPort -let server -let stderr -jest.setTimeout(1000 * 60 * 2) - -async function buildApp() { - appPort = await findPort() - ;({ stderr } = await nextBuild(appDir, [], { - env: { VERCEL_ANALYTICS_ID: 'test' }, - stdout: true, - stderr: true, - })) - server = await nextStart(appDir, appPort) -} -async function killServer() { - await killApp(server) -} - -describe('Analytics relayer with exported method', () => { - ;(process.env.TURBOPACK_DEV ? describe.skip : describe)( - 'production mode', - () => { - beforeAll(async () => await buildApp()) - afterAll(async () => await killServer()) - runTest() - } - ) -}) - -function runTest() { - it('Relays the data to user code', async () => { - const browser = await webdriver(appPort, '/') - await browser.waitForElementByCss('h1') - - const h1Text = await browser.elementByCss('h1').text() - const data = parseFloat( - await browser.eval('localStorage.getItem("Next.js-hydration")') - ) - const firstByte = parseFloat( - await browser.eval('localStorage.getItem("TTFB")') - ) - const firstContentfulPaint = parseFloat( - await browser.eval('localStorage.getItem("FCP")') - ) - let largestContentfulPaint = await browser.eval( - 'localStorage.getItem("LCP")' - ) - let cls = await browser.eval('localStorage.getItem("CLS")') - expect(h1Text).toMatch(/Foo!/) - expect(data).not.toBeNaN() - expect(data).toBeGreaterThan(0) - expect(firstByte).not.toBeNaN() - expect(firstByte).toBeGreaterThan(0) - expect(firstContentfulPaint).not.toBeNaN() - expect(firstContentfulPaint).toBeGreaterThan(0) - expect(largestContentfulPaint).toBeNull() - expect(cls).toBeNull() - - const beaconsCountBeforeCLS = await browser.eval('window.__BEACONS_COUNT') - expect( - Object.values(beaconsCountBeforeCLS).every((value) => value === 1) - ).toBe(true) - - // Create an artificial layout shift - await browser.eval('document.querySelector("h1").style.display = "none"') - await browser.refresh() - await browser.waitForElementByCss('h1') - largestContentfulPaint = parseFloat( - await browser.eval('localStorage.getItem("LCP")') - ) - cls = parseFloat(await browser.eval('localStorage.getItem("CLS")')) - expect(cls).not.toBeNull() - expect(largestContentfulPaint).not.toBeNaN() - expect(largestContentfulPaint).toBeGreaterThan(0) - - await check(async () => { - const numBeacons = await browser.eval('window.__BEACONS.length') - return numBeacons === 2 - ? 'success' - : `invalid beacon count: ${numBeacons}` - }, 'success') - - const beacons = (await browser.eval('window.__BEACONS')).map(([, value]) => - Object.fromEntries(new URLSearchParams(value)) - ) - - const beaconsCountAfterCLS = await browser.eval('window.__BEACONS_COUNT') - expect( - Object.values(beaconsCountAfterCLS).every((value) => value === 2) - ).toBe(true) - - expect(beacons.length).toBe(2) - - for (const beacon of beacons) { - expect(beacon.event_name === 'FCP' || beacon.event_name === 'TTFB').toBe( - true - ) - expect(beacon.dsn).toBe('test') - expect(beacon.href.includes('http://')).toBe(true) - expect(beacon.id.includes('-')).toBe(true) - expect(beacon.page).toBe('/') - expect(beacon.speed).toBe('4g') - expect(isNaN(parseFloat(beacon.value))).toBe(false) - } - - expect(stderr).toMatch( - '`config.analyticsId` is deprecated and will be removed in next major version. Read more: https://nextjs.org/docs/messages/deprecated-analyticsid' - ) - await browser.close() - }) - - it('reports INP metric', async () => { - const browser = await webdriver(appPort, '/') - await browser.elementByCss('button').click() - await browser.waitForCondition( - 'document.querySelector("button").textContent === "Press"' - ) - // INP metric is only reported on pagehide or visibilitychange event, so refresh the page - await browser.refresh() - - // TODO: investigate flakey INP case - // await check(async () => { - // const INP = parseInt( - // await browser.eval('localStorage.getItem("INP")'), - // 10 - // ) - // // We introduced a delay of 100ms, so INP duration should be >= 100 - // expect(INP).toBeGreaterThanOrEqual(100) - // return 'success' - // }, 'success') - await browser.close() - }) - - it('reports attribution', async () => { - const browser = await webdriver(appPort, '/') - // trigger paint - await browser.elementByCss('button').click() - await browser.waitForCondition( - `window.__metricsWithAttribution?.length > 0` - ) - const str = await browser.eval( - `JSON.stringify(window.__metricsWithAttribution)` - ) - const metrics = JSON.parse(str) - const LCP = metrics.find((m) => m.name === 'LCP') - expect(LCP).toBeDefined() - expect(LCP.attribution).toBeDefined() - expect(LCP.attribution.element).toBe('#__next>div>h1') - }) -} diff --git a/test/turbopack-build-tests-manifest.json b/test/turbopack-build-tests-manifest.json index fa4239943ca0ae..e3a8ec5c9bc539 100644 --- a/test/turbopack-build-tests-manifest.json +++ b/test/turbopack-build-tests-manifest.json @@ -1162,9 +1162,7 @@ }, "test/e2e/app-dir/app/useReportWebVitals.test.ts": { "passed": [], - "failed": [ - "useReportWebVitals hook should send web-vitals to vercel-insights" - ], + "failed": ["useReportWebVitals hook should send web-vitals"], "pending": [], "flakey": [], "runtimeError": false diff --git a/test/turbopack-dev-tests-manifest.json b/test/turbopack-dev-tests-manifest.json index 82341f204a35c9..52f5be81ccf34a 100644 --- a/test/turbopack-dev-tests-manifest.json +++ b/test/turbopack-dev-tests-manifest.json @@ -3191,9 +3191,7 @@ "runtimeError": false }, "test/e2e/app-dir/app/useReportWebVitals.test.ts": { - "passed": [ - "useReportWebVitals hook should send web-vitals to vercel-insights" - ], + "passed": ["useReportWebVitals hook should send web-vitals"], "failed": [], "pending": [], "flakey": [], From 512cabc1ee14e74c830caaeec916e4f46b0562e3 Mon Sep 17 00:00:00 2001 From: Jeffrey Zutt Date: Mon, 15 Apr 2024 17:24:27 +0200 Subject: [PATCH 08/96] feat: strip traceparent header from cachekey (#64499) ### What? We strip the `traceparent` header from the cache-key. ### Why? The traceparent header forms part of the W3C Trace Context standard, installed to track individual HTTP requests from start to end across multiple services. That means each individual HTTP request will have a unique traceparent value, reflecting its unique journey across servers and services. If we include the traceparent header in the cache key, the uniqueness of the traceparent means the cache key would always be different even for requests that should yield the same response. This would cause the cache to always miss and re-process the request. Effectively rendering fetch-cache useless. Co-authored-by: Jeffrey --- .../next/src/server/lib/incremental-cache/index.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/next/src/server/lib/incremental-cache/index.ts b/packages/next/src/server/lib/incremental-cache/index.ts index 755da67fdf1d94..569c216ff16c2a 100644 --- a/packages/next/src/server/lib/incremental-cache/index.ts +++ b/packages/next/src/server/lib/incremental-cache/index.ts @@ -385,14 +385,19 @@ export class IncrementalCache implements IncrementalCacheType { } } + const headers = + typeof (init.headers || {}).keys === 'function' + ? Object.fromEntries(init.headers as Headers) + : Object.assign(init.headers || {}, {}) + + if ('traceparent' in headers) delete headers['traceparent'] + const cacheString = JSON.stringify([ MAIN_KEY_PREFIX, this.fetchCacheKeyPrefix || '', url, init.method, - typeof (init.headers || {}).keys === 'function' - ? Object.fromEntries(init.headers as Headers) - : init.headers, + headers, init.mode, init.redirect, init.credentials, From 2be9ccb658458b2ceb9268a734e33f28146549a2 Mon Sep 17 00:00:00 2001 From: Arne Wiese Date: Mon, 15 Apr 2024 17:50:04 +0200 Subject: [PATCH 09/96] Fix typo in dynamic-rendering.ts (#64365) Super small PR - "oustide" should be "outside" --- packages/next/src/server/app-render/dynamic-rendering.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/src/server/app-render/dynamic-rendering.ts b/packages/next/src/server/app-render/dynamic-rendering.ts index 148d095309f356..e27f807c16ff31 100644 --- a/packages/next/src/server/app-render/dynamic-rendering.ts +++ b/packages/next/src/server/app-render/dynamic-rendering.ts @@ -126,7 +126,7 @@ export function trackDynamicDataAccessed( const pathname = getPathname(store.urlPathname) if (store.isUnstableCacheCallback) { throw new Error( - `Route ${pathname} used "${expression}" inside a function cached with "unstable_cache(...)". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "${expression}" oustide of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache` + `Route ${pathname} used "${expression}" inside a function cached with "unstable_cache(...)". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "${expression}" outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache` ) } else if (store.dynamicShouldError) { throw new StaticGenBailoutError( From edb9f7a14282b33e9e8ff36b8e2cfde6ee5ad54e Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Mon, 15 Apr 2024 17:52:44 +0200 Subject: [PATCH 10/96] Add typechecking test for all entrypoints (#64478) --- .../typescript-basic/typechecking.test.ts | 28 +++++++++++++++++++ .../typescript-basic/typechecking/.gitignore | 1 + .../typescript-basic/typechecking/index.ts | 25 +++++++++++++++++ .../typechecking/next-env.d.ts | 5 ++++ .../typechecking/next.config.js | 6 ++++ .../typechecking/tsconfig.json | 26 +++++++++++++++++ 6 files changed, 91 insertions(+) create mode 100644 test/production/typescript-basic/typechecking.test.ts create mode 100644 test/production/typescript-basic/typechecking/.gitignore create mode 100644 test/production/typescript-basic/typechecking/index.ts create mode 100644 test/production/typescript-basic/typechecking/next-env.d.ts create mode 100644 test/production/typescript-basic/typechecking/next.config.js create mode 100644 test/production/typescript-basic/typechecking/tsconfig.json diff --git a/test/production/typescript-basic/typechecking.test.ts b/test/production/typescript-basic/typechecking.test.ts new file mode 100644 index 00000000000000..d93d64ef54ef31 --- /dev/null +++ b/test/production/typescript-basic/typechecking.test.ts @@ -0,0 +1,28 @@ +import * as childProcess from 'child_process' +import path from 'path' +import { FileRef, nextTestSetup } from 'e2e-utils' + +describe('typechecking', () => { + const { next } = nextTestSetup({ + files: new FileRef(path.join(__dirname, 'typechecking')), + skipStart: true, + }) + + it('should typecheck', async () => { + const { status, stdout } = childProcess.spawnSync( + 'pnpm', + ['tsc', '--project', 'tsconfig.json', '--skipLibCheck', 'false'], + { + cwd: next.testDir, + encoding: 'utf-8', + } + ) + + if (status !== 0) { + // Piped output is incomplete and the format barely useable. + // Printing it as a last resort in case it's not reproducible locally. + // Best to NEXT_TEST_SKIP_CLEANUP=1 this test and run the command in the app localy. + throw new Error('Typecheck failed: \n' + stdout) + } + }) +}) diff --git a/test/production/typescript-basic/typechecking/.gitignore b/test/production/typescript-basic/typechecking/.gitignore new file mode 100644 index 00000000000000..6fcb2e11a62576 --- /dev/null +++ b/test/production/typescript-basic/typechecking/.gitignore @@ -0,0 +1 @@ +!next-env.d.ts \ No newline at end of file diff --git a/test/production/typescript-basic/typechecking/index.ts b/test/production/typescript-basic/typechecking/index.ts new file mode 100644 index 00000000000000..69404ba3014e27 --- /dev/null +++ b/test/production/typescript-basic/typechecking/index.ts @@ -0,0 +1,25 @@ +import 'next/amp' +import 'next/app' +// FIXME +// import 'next/babel'; +import 'next/cache' +import 'next/client' +import 'next/config' +import 'next/constants' +import 'next/document' +import 'next/dynamic' +import 'next/error' +import 'next/head' +import 'next/headers' +import 'next/image' +import 'next' +// TODO @jest/types is an undeclared peer dependecy +// import 'next/jest'; +import 'next/link' +import 'next/navigation' +import 'next/og' +import 'next/router' +import 'next/script' +import 'next/server' +// FIXME +// import 'next/web-vitals'; diff --git a/test/production/typescript-basic/typechecking/next-env.d.ts b/test/production/typescript-basic/typechecking/next-env.d.ts new file mode 100644 index 00000000000000..4f11a03dc6cc37 --- /dev/null +++ b/test/production/typescript-basic/typechecking/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/test/production/typescript-basic/typechecking/next.config.js b/test/production/typescript-basic/typechecking/next.config.js new file mode 100644 index 00000000000000..807126e4cf0bf5 --- /dev/null +++ b/test/production/typescript-basic/typechecking/next.config.js @@ -0,0 +1,6 @@ +/** + * @type {import('next').NextConfig} + */ +const nextConfig = {} + +module.exports = nextConfig diff --git a/test/production/typescript-basic/typechecking/tsconfig.json b/test/production/typescript-basic/typechecking/tsconfig.json new file mode 100644 index 00000000000000..8f01956e620c8d --- /dev/null +++ b/test/production/typescript-basic/typechecking/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": false, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} From 97b4a99b0be1851df78301b2006d3130bc140907 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Mon, 15 Apr 2024 16:21:28 +0000 Subject: [PATCH 11/96] v14.2.1-canary.7 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 12 ++++++------ packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 14 +++++++------- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lerna.json b/lerna.json index c4d63251a02052..a9fd95ce45337d 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.2.1-canary.6" + "version": "14.2.1-canary.7" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 415d9f715f3c16..8134588c668a6e 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.2.1-canary.6", + "version": "14.2.1-canary.7", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 969b46988817dc..96a3bbe78c9cc2 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.2.1-canary.6", + "version": "14.2.1-canary.7", "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": "14.2.1-canary.6", + "@next/eslint-plugin-next": "14.2.1-canary.7", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.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 2f18bb55c83ad6..cf05f55e1b36c6 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": "14.2.1-canary.6", + "version": "14.2.1-canary.7", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index b20097bc78fbb0..749982d2f3dedb 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.2.1-canary.6", + "version": "14.2.1-canary.7", "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 ef72bf9cbd1ca3..183ccecfefdc30 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.2.1-canary.6", + "version": "14.2.1-canary.7", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 8b5cdf9787f7d8..249cd975b1490f 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.2.1-canary.6", + "version": "14.2.1-canary.7", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 280c465b8c3090..87cc77194af25f 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.2.1-canary.6", + "version": "14.2.1-canary.7", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index fbd47b3af46243..c606bc7025f137 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.2.1-canary.6", + "version": "14.2.1-canary.7", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index b2273b5f608738..6718b6360b7691 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.2.1-canary.6", + "version": "14.2.1-canary.7", "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 27d7a0b29f1287..1cb6558c012ee5 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.2.1-canary.6", + "version": "14.2.1-canary.7", "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 920b9991588dcb..39fb2693f0b582 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.2.1-canary.6", + "version": "14.2.1-canary.7", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index ae12e13b22eed7..637f636f595d7d 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.2.1-canary.6", + "version": "14.2.1-canary.7", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 532591bedcc63d..d633496ba07627 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.2.1-canary.6", + "version": "14.2.1-canary.7", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.2.1-canary.6", + "@next/env": "14.2.1-canary.7", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -149,10 +149,10 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/polyfill-module": "14.2.1-canary.6", - "@next/polyfill-nomodule": "14.2.1-canary.6", - "@next/react-refresh-utils": "14.2.1-canary.6", - "@next/swc": "14.2.1-canary.6", + "@next/polyfill-module": "14.2.1-canary.7", + "@next/polyfill-nomodule": "14.2.1-canary.7", + "@next/react-refresh-utils": "14.2.1-canary.7", + "@next/swc": "14.2.1-canary.7", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", "@taskr/clear": "1.1.0", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index c2059f27c59893..c171c29dae10e6 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": "14.2.1-canary.6", + "version": "14.2.1-canary.7", "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 de827eb312c0a1..fcc2dd4749a9eb 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.2.1-canary.6", + "version": "14.2.1-canary.7", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -26,7 +26,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.2.1-canary.6", + "next": "14.2.1-canary.7", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0480f17bc5429b..675f72b6f23b87 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -744,7 +744,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.2.1-canary.6 + specifier: 14.2.1-canary.7 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.2.1-canary.6 + specifier: 14.2.1-canary.7 version: link:../next-env '@swc/helpers': specifier: 0.5.5 @@ -927,16 +927,16 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/polyfill-module': - specifier: 14.2.1-canary.6 + specifier: 14.2.1-canary.7 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.2.1-canary.6 + specifier: 14.2.1-canary.7 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 14.2.1-canary.6 + specifier: 14.2.1-canary.7 version: link:../react-refresh-utils '@next/swc': - specifier: 14.2.1-canary.6 + specifier: 14.2.1-canary.7 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1551,7 +1551,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.2.1-canary.6 + specifier: 14.2.1-canary.7 version: link:../next outdent: specifier: 0.8.0 From 30521f20ff1b7942c4a8bfdaf2401c58cb44ec4a Mon Sep 17 00:00:00 2001 From: Jiwon Choi Date: Tue, 16 Apr 2024 01:25:53 +0900 Subject: [PATCH 12/96] fix(next): global not-found not working on multi-root layouts (#63053) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Why? For multi-root layouts (route groups on the root with their root layouts, no layout file on the root), it is not possible to use global `not-found` since the `layout` is missing on the root. ```sh . └── app/ ├── (main)/ │ └── layout.js ├── (sub)/ │ └── layout.js └── not-found.js --> ERR: missing layout ``` Current Behavior: ```sh not-found.js doesn't have a root layout. To fix this error, make sure every page has a root layout. ``` ## What? Let multi-root layouts also benefit from the global `not-found`. ## How? Wrap root `not-found` with default layout if root layout does not exist. Although this solution is not `multi-root` specific, it won't produce critical issues since a root `layout` is required for other cases. Fixes #55191 #54980 #59180 --- .../build/webpack/loaders/next-app-loader.ts | 6 +++-- .../app/not-found.tsx | 3 +++ .../app/page.tsx | 6 +++++ .../index.test.ts | 18 +++++++++++++++ .../multi-root-layout/app/(main)/layout.tsx | 7 ++++++ .../app/(main)/not-found.tsx | 3 +++ .../multi-root-layout/app/(main)/page.tsx | 6 +++++ .../multi-root-layout/app/(sub)/layout.tsx | 7 ++++++ .../multi-root-layout/app/(sub)/not-found.tsx | 3 +++ .../multi-root-layout/app/(sub)/sub/page.tsx | 6 +++++ .../multi-root-layout/app/not-found.tsx | 3 +++ .../not-found/multi-root-layout/index.test.ts | 22 +++++++++++++++++++ 12 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 test/development/app-dir/root-not-found-missing-root-layout/app/not-found.tsx create mode 100644 test/development/app-dir/root-not-found-missing-root-layout/app/page.tsx create mode 100644 test/development/app-dir/root-not-found-missing-root-layout/index.test.ts create mode 100644 test/e2e/app-dir/not-found/multi-root-layout/app/(main)/layout.tsx create mode 100644 test/e2e/app-dir/not-found/multi-root-layout/app/(main)/not-found.tsx create mode 100644 test/e2e/app-dir/not-found/multi-root-layout/app/(main)/page.tsx create mode 100644 test/e2e/app-dir/not-found/multi-root-layout/app/(sub)/layout.tsx create mode 100644 test/e2e/app-dir/not-found/multi-root-layout/app/(sub)/not-found.tsx create mode 100644 test/e2e/app-dir/not-found/multi-root-layout/app/(sub)/sub/page.tsx create mode 100644 test/e2e/app-dir/not-found/multi-root-layout/app/not-found.tsx create mode 100644 test/e2e/app-dir/not-found/multi-root-layout/index.test.ts diff --git a/packages/next/src/build/webpack/loaders/next-app-loader.ts b/packages/next/src/build/webpack/loaders/next-app-loader.ts index b2f4d6279adaea..19b2448840c37f 100644 --- a/packages/next/src/build/webpack/loaders/next-app-loader.ts +++ b/packages/next/src/build/webpack/loaders/next-app-loader.ts @@ -200,9 +200,10 @@ async function createTreeCodeFromPath( const isDefaultNotFound = isAppBuiltinNotFoundPage(pagePath) const appDirPrefix = isDefaultNotFound ? APP_DIR_ALIAS : splittedPath[0] - const hasRootNotFound = await resolver( + const rootNotFound = await resolver( `${appDirPrefix}/${FILE_TYPES['not-found']}` ) + const hasRootNotFound = Boolean(rootNotFound) const pages: string[] = [] let rootLayout: string | undefined @@ -382,7 +383,8 @@ async function createTreeCodeFromPath( )?.[1] rootLayout = layoutPath - if (isDefaultNotFound && !layoutPath && !rootLayout) { + const isRootNotFound = hasRootNotFound && isRootLayer && isNotFoundRoute + if ((isRootNotFound || isDefaultNotFound) && !layoutPath) { rootLayout = defaultLayoutPath definedFilePaths.push(['layout', rootLayout]) } diff --git a/test/development/app-dir/root-not-found-missing-root-layout/app/not-found.tsx b/test/development/app-dir/root-not-found-missing-root-layout/app/not-found.tsx new file mode 100644 index 00000000000000..45db9205b02f0c --- /dev/null +++ b/test/development/app-dir/root-not-found-missing-root-layout/app/not-found.tsx @@ -0,0 +1,3 @@ +export default function NotFound() { + return

not found

+} diff --git a/test/development/app-dir/root-not-found-missing-root-layout/app/page.tsx b/test/development/app-dir/root-not-found-missing-root-layout/app/page.tsx new file mode 100644 index 00000000000000..2c9cd45bf56fd6 --- /dev/null +++ b/test/development/app-dir/root-not-found-missing-root-layout/app/page.tsx @@ -0,0 +1,6 @@ +import { notFound } from 'next/navigation' + +export default function Page() { + notFound() + return

hello world

+} diff --git a/test/development/app-dir/root-not-found-missing-root-layout/index.test.ts b/test/development/app-dir/root-not-found-missing-root-layout/index.test.ts new file mode 100644 index 00000000000000..88d92f21a638f2 --- /dev/null +++ b/test/development/app-dir/root-not-found-missing-root-layout/index.test.ts @@ -0,0 +1,18 @@ +import { nextTestSetup } from 'e2e-utils' + +describe('root-not-found-missing-root-layout', () => { + const { next, isTurbopack } = nextTestSetup({ + files: __dirname, + }) + + // Skip test for turbo dev for now since generating a missing root layout is not supported yet. + // See https://github.com/vercel/next.js/pull/63053#issuecomment-1987101666 + ;(isTurbopack ? it.skip : it)( + 'should not conflict with generated layout on dev server', + async () => { + const browser = await next.browser('/') + // eslint-disable-next-line jest/no-standalone-expect + expect(await browser.elementByCss('p').text()).toBe('not found') + } + ) +}) diff --git a/test/e2e/app-dir/not-found/multi-root-layout/app/(main)/layout.tsx b/test/e2e/app-dir/not-found/multi-root-layout/app/(main)/layout.tsx new file mode 100644 index 00000000000000..4f343ea0ca4846 --- /dev/null +++ b/test/e2e/app-dir/not-found/multi-root-layout/app/(main)/layout.tsx @@ -0,0 +1,7 @@ +export default function MainRoot({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ) +} diff --git a/test/e2e/app-dir/not-found/multi-root-layout/app/(main)/not-found.tsx b/test/e2e/app-dir/not-found/multi-root-layout/app/(main)/not-found.tsx new file mode 100644 index 00000000000000..5db0dd88497ee8 --- /dev/null +++ b/test/e2e/app-dir/not-found/multi-root-layout/app/(main)/not-found.tsx @@ -0,0 +1,3 @@ +export default function MaiNotFound() { + return

Main Not Found

+} diff --git a/test/e2e/app-dir/not-found/multi-root-layout/app/(main)/page.tsx b/test/e2e/app-dir/not-found/multi-root-layout/app/(main)/page.tsx new file mode 100644 index 00000000000000..7a42159ab2fa53 --- /dev/null +++ b/test/e2e/app-dir/not-found/multi-root-layout/app/(main)/page.tsx @@ -0,0 +1,6 @@ +import { notFound } from 'next/navigation' + +export default function Main() { + notFound() + return

Main

+} diff --git a/test/e2e/app-dir/not-found/multi-root-layout/app/(sub)/layout.tsx b/test/e2e/app-dir/not-found/multi-root-layout/app/(sub)/layout.tsx new file mode 100644 index 00000000000000..a47af6d0d16dff --- /dev/null +++ b/test/e2e/app-dir/not-found/multi-root-layout/app/(sub)/layout.tsx @@ -0,0 +1,7 @@ +export default function SubRoot({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ) +} diff --git a/test/e2e/app-dir/not-found/multi-root-layout/app/(sub)/not-found.tsx b/test/e2e/app-dir/not-found/multi-root-layout/app/(sub)/not-found.tsx new file mode 100644 index 00000000000000..1aed5cb51ea508 --- /dev/null +++ b/test/e2e/app-dir/not-found/multi-root-layout/app/(sub)/not-found.tsx @@ -0,0 +1,3 @@ +export default function SubNotFound() { + return

Sub Not Found

+} diff --git a/test/e2e/app-dir/not-found/multi-root-layout/app/(sub)/sub/page.tsx b/test/e2e/app-dir/not-found/multi-root-layout/app/(sub)/sub/page.tsx new file mode 100644 index 00000000000000..584f2aff626ea9 --- /dev/null +++ b/test/e2e/app-dir/not-found/multi-root-layout/app/(sub)/sub/page.tsx @@ -0,0 +1,6 @@ +import { notFound } from 'next/navigation' + +export default function Sub() { + notFound() + return

Sub

+} diff --git a/test/e2e/app-dir/not-found/multi-root-layout/app/not-found.tsx b/test/e2e/app-dir/not-found/multi-root-layout/app/not-found.tsx new file mode 100644 index 00000000000000..b8845ad5d832f0 --- /dev/null +++ b/test/e2e/app-dir/not-found/multi-root-layout/app/not-found.tsx @@ -0,0 +1,3 @@ +export default function RootNotFound() { + return

Root Not Found

+} diff --git a/test/e2e/app-dir/not-found/multi-root-layout/index.test.ts b/test/e2e/app-dir/not-found/multi-root-layout/index.test.ts new file mode 100644 index 00000000000000..b45671a067c381 --- /dev/null +++ b/test/e2e/app-dir/not-found/multi-root-layout/index.test.ts @@ -0,0 +1,22 @@ +import { nextTestSetup } from 'e2e-utils' + +describe('not-found-multi-root-layout', () => { + const { next } = nextTestSetup({ + files: __dirname, + }) + + it('should render main not-found', async () => { + const browser = await next.browser('/') + expect(await browser.elementByCss('h1').text()).toBe('Main Not Found') + }) + + it('should render sub not-found', async () => { + const browser = await next.browser('/sub') + expect(await browser.elementByCss('h1').text()).toBe('Sub Not Found') + }) + + it('should render root not-found for uncaught routes', async () => { + const browser = await next.browser('/404') + expect(await browser.elementByCss('h1').text()).toBe('Root Not Found') + }) +}) From c325ecd69ca596024441268f0816516c6496dd2a Mon Sep 17 00:00:00 2001 From: Jiwon Choi Date: Tue, 16 Apr 2024 01:33:32 +0900 Subject: [PATCH 13/96] chore(next): add keywords on package.json (#64173) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I'm assuming leaving keywords blank is intended, but with 🖤 for Next.js, I added 10 keywords to increase the traction of users. - react - web - server - node - nextjs - vercel Also, included relative keywords that can be easily accessed from the landing of [npm](https://www.npmjs.com). - framework - front-end - back-end - cli ![Screenshot 2024-04-07 at 11 27 50 PM](https://github.com/vercel/next.js/assets/120007119/37bfe915-61e5-42db-94c3-597391b6e74c) Co-authored-by: Shu Ding --- packages/next/package.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/next/package.json b/packages/next/package.json index d633496ba07627..b35c4aa73921d0 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -320,6 +320,18 @@ "ws": "8.2.3", "zod": "3.22.3" }, + "keywords": [ + "react", + "framework", + "nextjs", + "web", + "server", + "node", + "front-end", + "back-end", + "cli", + "vercel" + ], "engines": { "node": ">=18.17.0" } From 4024a89ee830cec6ab451ba7871ae078d51a9757 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 15 Apr 2024 10:09:57 -0700 Subject: [PATCH 14/96] Fix DynamicServerError not being thrown in fetch (#64511) This ensures we properly skip calling a fetch during build-time that has `cache: 'no-store'` as it should only be called during runtime instead. Fixes: https://github.com/vercel/next.js/issues/64462 Closes NEXT-3114 --- packages/next/src/server/lib/patch-fetch.ts | 2 ++ test/e2e/app-dir/app-static/app-static.test.ts | 2 ++ .../app/force-no-store-bailout/page.js | 16 ++++++++++++++++ 3 files changed, 20 insertions(+) create mode 100644 test/e2e/app-dir/app-static/app/force-no-store-bailout/page.js diff --git a/packages/next/src/server/lib/patch-fetch.ts b/packages/next/src/server/lib/patch-fetch.ts index e5318dc371796e..5bc3e58740d612 100644 --- a/packages/next/src/server/lib/patch-fetch.ts +++ b/packages/next/src/server/lib/patch-fetch.ts @@ -668,6 +668,7 @@ function createPatchedFetcher( const err = new DynamicServerError(dynamicUsageReason) staticGenerationStore.dynamicUsageErr = err staticGenerationStore.dynamicUsageDescription = dynamicUsageReason + throw err } const hasNextConfig = 'next' in init @@ -695,6 +696,7 @@ function createPatchedFetcher( const err = new DynamicServerError(dynamicUsageReason) staticGenerationStore.dynamicUsageErr = err staticGenerationStore.dynamicUsageDescription = dynamicUsageReason + throw err } if (!staticGenerationStore.forceStatic || next.revalidate !== 0) { diff --git a/test/e2e/app-dir/app-static/app-static.test.ts b/test/e2e/app-dir/app-static/app-static.test.ts index b19aee58b71ecb..2f6905b50d6613 100644 --- a/test/e2e/app-dir/app-static/app-static.test.ts +++ b/test/e2e/app-dir/app-static/app-static.test.ts @@ -703,6 +703,8 @@ createNextDescribe( "force-dynamic-no-prerender/[id]/page_client-reference-manifest.js", "force-dynamic-prerender/[slug]/page.js", "force-dynamic-prerender/[slug]/page_client-reference-manifest.js", + "force-no-store-bailout/page.js", + "force-no-store-bailout/page_client-reference-manifest.js", "force-no-store/page.js", "force-no-store/page_client-reference-manifest.js", "force-static-fetch-no-store.html", diff --git a/test/e2e/app-dir/app-static/app/force-no-store-bailout/page.js b/test/e2e/app-dir/app-static/app/force-no-store-bailout/page.js new file mode 100644 index 00000000000000..77d9320a8f9ea3 --- /dev/null +++ b/test/e2e/app-dir/app-static/app/force-no-store-bailout/page.js @@ -0,0 +1,16 @@ +export const fetchCache = 'force-no-store' + +export default async function Page() { + // this should not be invoked during build as + // no-store should have it bail out + await fetch('https://non-existent', { + cache: 'no-store', + }) + + return ( + <> +

/force-no-store-bailout

+

{Date.now()}

+ + ) +} From 03b7a0fb12a1a4b08a6d591f20b429a520c59cc6 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Mon, 15 Apr 2024 17:24:31 +0000 Subject: [PATCH 15/96] v14.3.0-canary.0 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 12 ++++++------ packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 14 +++++++------- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lerna.json b/lerna.json index a9fd95ce45337d..2b9935cf66a2d7 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.2.1-canary.7" + "version": "14.3.0-canary.0" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 8134588c668a6e..69cacde1ce007a 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.2.1-canary.7", + "version": "14.3.0-canary.0", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 96a3bbe78c9cc2..d9863c8adffa8e 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.2.1-canary.7", + "version": "14.3.0-canary.0", "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": "14.2.1-canary.7", + "@next/eslint-plugin-next": "14.3.0-canary.0", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.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 cf05f55e1b36c6..20b2d820433fe7 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": "14.2.1-canary.7", + "version": "14.3.0-canary.0", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 749982d2f3dedb..4592bfcd639456 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.2.1-canary.7", + "version": "14.3.0-canary.0", "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 183ccecfefdc30..5f161b696565a2 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.2.1-canary.7", + "version": "14.3.0-canary.0", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 249cd975b1490f..87e14b4f1006af 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.2.1-canary.7", + "version": "14.3.0-canary.0", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 87cc77194af25f..dce10fc3569a86 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.2.1-canary.7", + "version": "14.3.0-canary.0", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index c606bc7025f137..7ac62a98cbed91 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.2.1-canary.7", + "version": "14.3.0-canary.0", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 6718b6360b7691..739bb1da866778 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.2.1-canary.7", + "version": "14.3.0-canary.0", "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 1cb6558c012ee5..f36c05ab6b5097 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.2.1-canary.7", + "version": "14.3.0-canary.0", "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 39fb2693f0b582..0254528c6718e2 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.2.1-canary.7", + "version": "14.3.0-canary.0", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 637f636f595d7d..80fce235c50034 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.2.1-canary.7", + "version": "14.3.0-canary.0", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index b35c4aa73921d0..24fb91949ec955 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.2.1-canary.7", + "version": "14.3.0-canary.0", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.2.1-canary.7", + "@next/env": "14.3.0-canary.0", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -149,10 +149,10 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/polyfill-module": "14.2.1-canary.7", - "@next/polyfill-nomodule": "14.2.1-canary.7", - "@next/react-refresh-utils": "14.2.1-canary.7", - "@next/swc": "14.2.1-canary.7", + "@next/polyfill-module": "14.3.0-canary.0", + "@next/polyfill-nomodule": "14.3.0-canary.0", + "@next/react-refresh-utils": "14.3.0-canary.0", + "@next/swc": "14.3.0-canary.0", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", "@taskr/clear": "1.1.0", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index c171c29dae10e6..041db27371ab02 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": "14.2.1-canary.7", + "version": "14.3.0-canary.0", "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 fcc2dd4749a9eb..f4e0eadd2bac51 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.2.1-canary.7", + "version": "14.3.0-canary.0", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -26,7 +26,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.2.1-canary.7", + "next": "14.3.0-canary.0", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 675f72b6f23b87..e153846c7221c4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -744,7 +744,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.2.1-canary.7 + specifier: 14.3.0-canary.0 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.2.1-canary.7 + specifier: 14.3.0-canary.0 version: link:../next-env '@swc/helpers': specifier: 0.5.5 @@ -927,16 +927,16 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/polyfill-module': - specifier: 14.2.1-canary.7 + specifier: 14.3.0-canary.0 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.2.1-canary.7 + specifier: 14.3.0-canary.0 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 14.2.1-canary.7 + specifier: 14.3.0-canary.0 version: link:../react-refresh-utils '@next/swc': - specifier: 14.2.1-canary.7 + specifier: 14.3.0-canary.0 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1551,7 +1551,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.2.1-canary.7 + specifier: 14.3.0-canary.0 version: link:../next outdent: specifier: 0.8.0 From 64da71cfc982e485d53d93c25305080115cc6d24 Mon Sep 17 00:00:00 2001 From: Ethan Arrowood Date: Mon, 15 Apr 2024 11:26:41 -0600 Subject: [PATCH 16/96] fix: `lib/helpers/install.ts` to better support pnpm and properly respect `root` argument (#64418) This fixes and improves the `lib/helpers/install.ts` file (`install()`) method to better support pnpm and properly respect the `root` argument. I encountered an issue where by running `next `, and the `` involved installing missing dependencies (like `lint` or my upcoming `experimental-test`), it was not executing pnpm in my `` because pnpm doesn't have a `--cwd` flag. Closes NEXT-3092 Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com> --- packages/next/src/lib/helpers/install.ts | 102 ++++++++--------------- 1 file changed, 36 insertions(+), 66 deletions(-) diff --git a/packages/next/src/lib/helpers/install.ts b/packages/next/src/lib/helpers/install.ts index 8a3666139b3983..b6cc20c92918d5 100644 --- a/packages/next/src/lib/helpers/install.ts +++ b/packages/next/src/lib/helpers/install.ts @@ -1,15 +1,14 @@ import { yellow } from '../picocolors' import spawn from 'next/dist/compiled/cross-spawn' - -export type PackageManager = 'npm' | 'pnpm' | 'yarn' +import type { PackageManager } from './get-pkg-manager' interface InstallArgs { /** - * Indicate whether to install packages using npm, pnpm or Yarn. + * Indicate whether to install packages using npm, pnpm, or yarn. */ packageManager: PackageManager /** - * Indicate whether there is an active Internet connection. + * Indicate whether there is an active internet connection. */ isOnline: boolean /** @@ -19,81 +18,52 @@ interface InstallArgs { } /** - * Spawn a package manager installation with either Yarn or NPM. + * Spawn a package manager installation with either npm, pnpm, or yarn. * * @returns A Promise that resolves once the installation is finished. */ export function install( root: string, - dependencies: string[] | null, + dependencies: string[], { packageManager, isOnline, devDependencies }: InstallArgs ): Promise { - /** - * (p)npm-specific command-line flags. - */ - const npmFlags: string[] = [] - /** - * Yarn-specific command-line flags. - */ - const yarnFlags: string[] = [] - /** - * Return a Promise that resolves once the installation is finished. - */ - return new Promise((resolve, reject) => { - let args: string[] - let command = packageManager - const useYarn = packageManager === 'yarn' + let args: string[] = [] - if (dependencies && dependencies.length) { - /** - * If there are dependencies, run a variation of `{packageManager} add`. - */ - if (useYarn) { - /** - * Call `yarn add --exact (--offline)? (-D)? ...`. - */ - args = ['add', '--exact'] - if (!isOnline) args.push('--offline') - args.push('--cwd', root) - if (devDependencies) args.push('--dev') - args.push(...dependencies) - } else { - /** - * Call `(p)npm install [--save|--save-dev] ...`. - */ - args = ['install', '--save-exact'] - args.push(devDependencies ? '--save-dev' : '--save') - args.push(...dependencies) - } + if (dependencies.length > 0) { + if (packageManager === 'yarn') { + args = ['add', '--exact'] + if (devDependencies) args.push('--dev') + } else if (packageManager === 'pnpm') { + args = ['add', '--save-exact'] + args.push(devDependencies ? '--save-dev' : '--save-prod') } else { - /** - * If there are no dependencies, run a variation of `{packageManager} - * install`. - */ - args = ['install'] - if (!isOnline) { - console.log(yellow('You appear to be offline.')) - if (useYarn) { - console.log(yellow('Falling back to the local Yarn cache.')) - console.log() - args.push('--offline') - } else { - console.log() - } - } + // npm + args = ['install', '--save-exact'] + args.push(devDependencies ? '--save-dev' : '--save') } - /** - * Add any package manager-specific flags. - */ - if (useYarn) { - args.push(...yarnFlags) - } else { - args.push(...npmFlags) + + args.push(...dependencies) + } else { + args = ['install'] // npm, pnpm, and yarn all support `install` + + if (!isOnline) { + args.push('--offline') + console.log(yellow('You appear to be offline.')) + if (packageManager !== 'npm') { + console.log( + yellow(`Falling back to the local ${packageManager} cache.`) + ) + } + console.log() } + } + + return new Promise((resolve, reject) => { /** * Spawn the installation process. */ - const child = spawn(command, args, { + const child = spawn(packageManager, args, { + cwd: root, stdio: 'inherit', env: { ...process.env, @@ -106,7 +76,7 @@ export function install( }) child.on('close', (code) => { if (code !== 0) { - reject({ command: `${command} ${args.join(' ')}` }) + reject({ command: `${packageManager} ${args.join(' ')}` }) return } resolve() From 2bd27e72e5039af2c6c61a450878c9fe9f949eee Mon Sep 17 00:00:00 2001 From: Jiwon Choi Date: Tue, 16 Apr 2024 04:17:48 +0900 Subject: [PATCH 17/96] fix(next): `Metadata.openGraph` values not resolving basic values when `type` is set (#63620) ### What? The string value of `Metadata.openGraph.emails` throws error: ```tsx export const metadata = { openGraph: { type: 'article', emails: 'author@vercel.com', }, }; ``` Error: ```sh r.map is not a function ``` The type is: ```tsx type OpenGraphMetadata = { // ... emails?: string | Array } ``` ### Why? Basic values such as `emails` and `phoneNumbers` were not included when `ogType` was set while resolving the values. ### How? Include basic values when resolving the metadata. Fixes #63415 --- .../metadata/resolvers/resolve-opengraph.ts | 30 ++++++++----------- .../metadata/app/opengraph/article/layout.tsx | 7 ++++- test/e2e/app-dir/metadata/metadata.test.ts | 3 ++ 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/packages/next/src/lib/metadata/resolvers/resolve-opengraph.ts b/packages/next/src/lib/metadata/resolvers/resolve-opengraph.ts index dae6fc94ddbbc9..61209b8464d06b 100644 --- a/packages/next/src/lib/metadata/resolvers/resolve-opengraph.ts +++ b/packages/next/src/lib/metadata/resolvers/resolve-opengraph.ts @@ -96,24 +96,20 @@ export function resolveImages( return nonNullableImages } +const ogTypeToFields: Record = { + article: OgTypeFields.article, + book: OgTypeFields.article, + 'music.song': OgTypeFields.song, + 'music.album': OgTypeFields.song, + 'music.playlist': OgTypeFields.playlist, + 'music.radio_station': OgTypeFields.radio, + 'video.movie': OgTypeFields.video, + 'video.episode': OgTypeFields.video, +} + function getFieldsByOgType(ogType: OpenGraphType | undefined) { - switch (ogType) { - case 'article': - case 'book': - return OgTypeFields.article - case 'music.song': - case 'music.album': - return OgTypeFields.song - case 'music.playlist': - return OgTypeFields.playlist - case 'music.radio_station': - return OgTypeFields.radio - case 'video.movie': - case 'video.episode': - return OgTypeFields.video - default: - return OgTypeFields.basic - } + if (!ogType || !(ogType in ogTypeToFields)) return OgTypeFields.basic + return ogTypeToFields[ogType].concat(OgTypeFields.basic) } function validateResolvedImageUrl( diff --git a/test/e2e/app-dir/metadata/app/opengraph/article/layout.tsx b/test/e2e/app-dir/metadata/app/opengraph/article/layout.tsx index 563c620e21d946..32f413378bb734 100644 --- a/test/e2e/app-dir/metadata/app/opengraph/article/layout.tsx +++ b/test/e2e/app-dir/metadata/app/opengraph/article/layout.tsx @@ -1,3 +1,5 @@ +import type { Metadata } from 'next' + export default function Layout({ children }) { return children } @@ -10,5 +12,8 @@ export const metadata = { publishedTime: '2023-01-01T00:00:00.000Z', authors: ['author1', 'author2', 'author3'], images: new URL('https://example.com/og-image.jpg'), - }, + emails: 'author@vercel.com', + phoneNumbers: '1234567890', + faxNumbers: '1234567890', + } satisfies Metadata['openGraph'], } diff --git a/test/e2e/app-dir/metadata/metadata.test.ts b/test/e2e/app-dir/metadata/metadata.test.ts index a95f30e0fb7191..6f776ff41e525f 100644 --- a/test/e2e/app-dir/metadata/metadata.test.ts +++ b/test/e2e/app-dir/metadata/metadata.test.ts @@ -499,6 +499,9 @@ createNextDescribe( 'og:description': 'My custom description', 'og:type': 'article', 'og:image': 'https://example.com/og-image.jpg', + 'og:email': 'author@vercel.com', + 'og:phone_number': '1234567890', + 'og:fax_number': '1234567890', 'article:published_time': '2023-01-01T00:00:00.000Z', 'article:author': ['author1', 'author2', 'author3'], }) From 6178693b39f971bd9e6d063a5b4a651dfe33edd9 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 15 Apr 2024 21:22:22 +0200 Subject: [PATCH 18/96] disable production chunking in dev (#64488) ### What? The production chunking plugin shouldn't be enabled in development ### Why? It doesn't handle HMR yet Closes PACK-2956 --- packages/next/src/build/webpack-config.ts | 3 +- test/e2e/app-dir/css-order/css-order.test.ts | 239 ++++++++++--------- 2 files changed, 126 insertions(+), 116 deletions(-) diff --git a/packages/next/src/build/webpack-config.ts b/packages/next/src/build/webpack-config.ts index 59727946003be9..a3a6218e75f5be 100644 --- a/packages/next/src/build/webpack-config.ts +++ b/packages/next/src/build/webpack-config.ts @@ -1880,7 +1880,8 @@ export default async function getBaseWebpackConfig( new NextFontManifestPlugin({ appDir, }), - isClient && + !dev && + isClient && new CssChunkingPlugin(config.experimental.cssChunking === 'strict'), !dev && isClient && diff --git a/test/e2e/app-dir/css-order/css-order.test.ts b/test/e2e/app-dir/css-order/css-order.test.ts index 24d88e60cc90f5..c8cdf95bc92a2a 100644 --- a/test/e2e/app-dir/css-order/css-order.test.ts +++ b/test/e2e/app-dir/css-order/css-order.test.ts @@ -1,5 +1,5 @@ import path from 'path' -import { createNextDescribe, FileRef } from 'e2e-utils' +import { nextTestSetup, FileRef } from 'e2e-utils' function getPairs(all: string[]): (readonly [string, string])[] { const result: (readonly [string, string])[] = [] @@ -187,141 +187,150 @@ const PAGES: Record< const allPairs = getPairs(Object.keys(PAGES)) -for (const mode of process.env.TURBOPACK ? ['turbo'] : ['strict', 'loose']) - createNextDescribe( - `css-order ${mode}`, - { - files: { - app: new FileRef(path.join(__dirname, 'app')), - pages: new FileRef(path.join(__dirname, 'pages')), - 'next.config.js': process.env.TURBOPACK - ? ` +const options = (mode) => ({ + files: { + app: new FileRef(path.join(__dirname, 'app')), + pages: new FileRef(path.join(__dirname, 'pages')), + 'next.config.js': process.env.TURBOPACK + ? ` module.exports = {}` - : ` + : ` module.exports = { experimental: { cssChunking: ${JSON.stringify(mode)} } }`, - }, - dependencies: { - sass: 'latest', - }, - }, - ({ next, isNextDev }) => { - for (const ordering of allPairs) { - const name = `should load correct styles navigating back again ${ordering.join( - ' -> ' - )} -> ${ordering.join(' -> ')}` + }, + dependencies: { + sass: 'latest', + }, +}) +describe.each(process.env.TURBOPACK ? ['turbo'] : ['strict', 'loose'])( + 'css-order %s', + (mode: string) => { + const { next, isNextDev } = nextTestSetup(options(mode)) + for (const ordering of allPairs) { + const name = `should load correct styles navigating back again ${ordering.join( + ' -> ' + )} -> ${ordering.join(' -> ')}` + if (ordering.some((page) => PAGES[page].conflict)) { + // Conflict scenarios won't support that case + continue + } + // TODO fix this case + const broken = + isNextDev || ordering.some((page) => PAGES[page].brokenLoading) + if (broken) { + it.todo(name) + continue + } + it(name, async () => { + const start = PAGES[ordering[0]] + const browser = await next.browser(start.url) + const check = async (pageInfo) => { + expect( + await browser + .waitForElementByCss(pageInfo.selector) + .getComputedCss('color') + ).toBe(pageInfo.color) + if (pageInfo.background) { + expect( + await browser + .waitForElementByCss(pageInfo.selector) + .getComputedCss('background-color') + ).toBe(pageInfo.background) + } + } + const navigate = async (page) => { + await browser.waitForElementByCss('#' + page).click() + } + await check(start) + for (const page of ordering.slice(1)) { + await navigate(page) + await check(PAGES[page]) + } + for (const page of ordering) { + await navigate(page) + await check(PAGES[page]) + } + await browser.close() + }) + } + } +) +describe.each(process.env.TURBOPACK ? ['turbo'] : ['strict', 'loose'])( + 'css-order %s', + (mode: string) => { + const { next, isNextDev } = nextTestSetup(options(mode)) + for (const ordering of allPairs) { + const name = `should load correct styles navigating ${ordering.join( + ' -> ' + )}` + if (mode !== 'turbo') { if (ordering.some((page) => PAGES[page].conflict)) { // Conflict scenarios won't support that case continue } // TODO fix this case - const broken = - mode === 'turbo' - ? isNextDev - : ordering.some( - (page) => - PAGES[page].brokenLoading || - (isNextDev && PAGES[page].brokenLoadingDev) - ) + const broken = ordering.some( + (page) => + PAGES[page].brokenLoading || + (isNextDev && PAGES[page].brokenLoadingDev) + ) if (broken) { it.todo(name) continue } - it(name, async () => { - const start = PAGES[ordering[0]] - const browser = await next.browser(start.url) - const check = async (pageInfo) => { - expect( - await browser - .waitForElementByCss(pageInfo.selector) - .getComputedCss('color') - ).toBe(pageInfo.color) - if (pageInfo.background) { - expect( - await browser - .waitForElementByCss(pageInfo.selector) - .getComputedCss('background-color') - ).toBe(pageInfo.background) - } - } - const navigate = async (page) => { - await browser.waitForElementByCss('#' + page).click() - } - await check(start) - for (const page of ordering.slice(1)) { - await navigate(page) - await check(PAGES[page]) - } - for (const page of ordering) { - await navigate(page) - await check(PAGES[page]) - } - }) - } - for (const ordering of allPairs) { - const name = `should load correct styles navigating ${ordering.join( - ' -> ' - )}` - if (mode !== 'turbo') { - if (ordering.some((page) => PAGES[page].conflict)) { - // Conflict scenarios won't support that case - continue - } - // TODO fix this case - const broken = ordering.some( - (page) => - PAGES[page].brokenLoading || - (isNextDev && PAGES[page].brokenLoadingDev) - ) - if (broken) { - it.todo(name) - continue - } - } else { - // TODO fix this case - const broken = ordering.some((page) => PAGES[page].brokenLoadingTurbo) - if (broken) { - it.todo(name) - continue - } - } - it(name, async () => { - const start = PAGES[ordering[0]] - const browser = await next.browser(start.url) - const check = async (pageInfo) => { - expect( - await browser - .waitForElementByCss(pageInfo.selector) - .getComputedCss('color') - ).toBe(pageInfo.color) - } - const navigate = async (page) => { - await browser.waitForElementByCss('#' + page).click() - } - await check(start) - for (const page of ordering.slice(1)) { - await navigate(page) - await check(PAGES[page]) - } - }) - } - for (const [page, pageInfo] of Object.entries(PAGES)) { - const name = `should load correct styles on ${page}` - if (mode === 'loose' && pageInfo.conflict) { - // Conflict scenarios won't support that case + } else { + // TODO fix this case + const broken = ordering.some((page) => PAGES[page].brokenLoadingTurbo) + if (broken) { + it.todo(name) continue } - it(name, async () => { - const browser = await next.browser(pageInfo.url) + } + it(name, async () => { + const start = PAGES[ordering[0]] + const browser = await next.browser(start.url) + const check = async (pageInfo) => { expect( await browser .waitForElementByCss(pageInfo.selector) .getComputedCss('color') ).toBe(pageInfo.color) - }) + } + const navigate = async (page) => { + await browser.waitForElementByCss('#' + page).click() + } + await check(start) + for (const page of ordering.slice(1)) { + await navigate(page) + await check(PAGES[page]) + } + await browser.close() + }) + } + } +) +describe.each(process.env.TURBOPACK ? ['turbo'] : ['strict', 'loose'])( + 'css-order %s', + (mode: string) => { + const { next } = nextTestSetup(options(mode)) + for (const [page, pageInfo] of Object.entries(PAGES)) { + const name = `should load correct styles on ${page}` + if (mode === 'loose' && pageInfo.conflict) { + // Conflict scenarios won't support that case + continue } + it(name, async () => { + const browser = await next.browser(pageInfo.url) + expect( + await browser + .waitForElementByCss(pageInfo.selector) + .getComputedCss('color') + ).toBe(pageInfo.color) + await browser.close() + }) } - ) + } +) From 81450de6afabd540d4019c30f91b14b9191593e3 Mon Sep 17 00:00:00 2001 From: Jiwon Choi Date: Tue, 16 Apr 2024 04:46:42 +0900 Subject: [PATCH 19/96] hotfix: hardcoded skip turbopack tests to manifest (#64515) cc @shuding CI run failed after #63053 on turbo production, which had not yet been targeted for turbo. x-ref: #63103 --------- Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com> Co-authored-by: Leah <8845940+ForsakenHarmony@users.noreply.github.com> Co-authored-by: Jiachi Liu --- .../index.test.ts | 17 ++++++----------- test/turbopack-build-tests-manifest.json | 12 ++++++++++++ test/turbopack-dev-tests-manifest.json | 9 +++++++++ 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/test/development/app-dir/root-not-found-missing-root-layout/index.test.ts b/test/development/app-dir/root-not-found-missing-root-layout/index.test.ts index 88d92f21a638f2..d81b12ae7b2092 100644 --- a/test/development/app-dir/root-not-found-missing-root-layout/index.test.ts +++ b/test/development/app-dir/root-not-found-missing-root-layout/index.test.ts @@ -1,18 +1,13 @@ import { nextTestSetup } from 'e2e-utils' describe('root-not-found-missing-root-layout', () => { - const { next, isTurbopack } = nextTestSetup({ + const { next } = nextTestSetup({ files: __dirname, }) - // Skip test for turbo dev for now since generating a missing root layout is not supported yet. - // See https://github.com/vercel/next.js/pull/63053#issuecomment-1987101666 - ;(isTurbopack ? it.skip : it)( - 'should not conflict with generated layout on dev server', - async () => { - const browser = await next.browser('/') - // eslint-disable-next-line jest/no-standalone-expect - expect(await browser.elementByCss('p').text()).toBe('not found') - } - ) + it('should not conflict with generated layout on dev server', async () => { + const browser = await next.browser('/') + // eslint-disable-next-line jest/no-standalone-expect + expect(await browser.elementByCss('p').text()).toBe('not found') + }) }) diff --git a/test/turbopack-build-tests-manifest.json b/test/turbopack-build-tests-manifest.json index e3a8ec5c9bc539..c486b66780f61a 100644 --- a/test/turbopack-build-tests-manifest.json +++ b/test/turbopack-build-tests-manifest.json @@ -2164,6 +2164,18 @@ "flakey": [], "runtimeError": false }, + "test/e2e/app-dir/not-found/multi-root-layout/index.test.ts": { + "passed": [ + "not-found-multi-root-layout should render main not-found", + "not-found-multi-root-layout should render sub not-found" + ], + "failed": [ + "not-found-multi-root-layout should render root not-found for uncaught routes" + ], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/e2e/app-dir/pages-to-app-routing/pages-to-app-routing.test.ts": { "passed": ["pages-to-app-routing should work using browser"], "failed": [], diff --git a/test/turbopack-dev-tests-manifest.json b/test/turbopack-dev-tests-manifest.json index 52f5be81ccf34a..efc8e7bd37b218 100644 --- a/test/turbopack-dev-tests-manifest.json +++ b/test/turbopack-dev-tests-manifest.json @@ -1479,6 +1479,15 @@ "flakey": [], "runtimeError": false }, + "test/development/app-dir/root-not-found-missing-root-layout/index.test.ts": { + "passed": [], + "failed": [ + "root-not-found-missing-root-layout should not conflict with generated layout on dev server" + ], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/development/app-dir/strict-mode-enabled-by-default/strict-mode-enabled-by-default.test.ts": { "passed": ["Strict Mode enabled by default should work using browser"], "failed": [], From bde895191d92e276885d1b73d6e1431bc5e47616 Mon Sep 17 00:00:00 2001 From: Kenji <98567681+kenji-webdev@users.noreply.github.com> Date: Mon, 15 Apr 2024 16:49:53 -0300 Subject: [PATCH 20/96] docs(09-authentication): fixes link to NextAuth.js (#64457) There's a TODO above the links, I didn't understand if it was related to this PR as the domain was already authjs.dev ### What? - Fixes the link to NextAuth in the `Examples` section ### How? - Changes https://authjs.dev/guides/upgrade-to-v5 to https://authjs.dev/getting-started/migrating-to-v5 Co-authored-by: JJ Kasper --- .../01-building-your-application/09-authentication/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/02-app/01-building-your-application/09-authentication/index.mdx b/docs/02-app/01-building-your-application/09-authentication/index.mdx index c65b1f58b33fd8..fdf1611521551b 100644 --- a/docs/02-app/01-building-your-application/09-authentication/index.mdx +++ b/docs/02-app/01-building-your-application/09-authentication/index.mdx @@ -877,7 +877,7 @@ Here are authentication solutions compatible with Next.js, please refer to the q - [Clerk](https://clerk.com/docs/quickstarts/nextjs) - [Kinde](https://kinde.com/docs/developer-tools/nextjs-sdk) - [Lucia](https://lucia-auth.com/getting-started/nextjs-app) -- [NextAuth.js](https://authjs.dev/guides/upgrade-to-v5) +- [NextAuth.js](https://authjs.dev/getting-started/migrating-to-v5) - [Supabase](https://supabase.com/docs/guides/getting-started/quickstarts/nextjs) - [Stytch](https://stytch.com/docs/guides/quickstarts/nextjs) - [Iron Session](https://github.com/vvo/iron-session) From 3491417ac529f71fb6ebf23e816c20880246e8f7 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 15 Apr 2024 22:19:31 +0200 Subject: [PATCH 21/96] update turbopack (#64501) * https://github.com/vercel/turbo/pull/7858 * https://github.com/vercel/turbo/pull/7944 * https://github.com/vercel/turbo/pull/7936 * https://github.com/vercel/turbo/pull/7959 --- Cargo.lock | 70 +++++++++++++++++++------------------- Cargo.toml | 6 ++-- packages/next/package.json | 2 +- pnpm-lock.yaml | 8 ++--- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c8d43c6eadea77..2b1479686d5d11 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -321,7 +321,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "serde", "smallvec", @@ -3218,7 +3218,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "serde", @@ -7174,7 +7174,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "async-trait", @@ -7205,7 +7205,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "cargo-lock", @@ -7217,7 +7217,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "bytes", @@ -7231,7 +7231,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "dotenvs", @@ -7245,7 +7245,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "lazy_static", @@ -7261,7 +7261,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "auto-hash-map", @@ -7293,7 +7293,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "base16", "hex", @@ -7305,7 +7305,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "proc-macro-error", @@ -7318,7 +7318,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "proc-macro2", "quote", @@ -7328,7 +7328,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "mimalloc", ] @@ -7336,7 +7336,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "auto-hash-map", @@ -7361,7 +7361,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "async-recursion", @@ -7391,7 +7391,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "auto-hash-map", "mdxjs", @@ -7431,7 +7431,7 @@ dependencies = [ [[package]] name = "turbopack-browser" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7454,7 +7454,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "clap", @@ -7471,7 +7471,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "async-recursion", @@ -7500,7 +7500,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7527,7 +7527,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "async-compression", @@ -7563,7 +7563,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "async-trait", @@ -7598,7 +7598,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "serde", "serde_json", @@ -7609,7 +7609,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "async-trait", @@ -7633,7 +7633,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "indoc", @@ -7649,7 +7649,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7665,7 +7665,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "base64 0.21.4", @@ -7684,7 +7684,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "serde", @@ -7699,7 +7699,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "mdxjs", @@ -7714,7 +7714,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "async-stream", @@ -7748,7 +7748,7 @@ dependencies = [ [[package]] name = "turbopack-nodejs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "turbopack-resolve" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7786,7 +7786,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "serde", @@ -7802,7 +7802,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "swc_core", "turbo-tasks", @@ -7813,7 +7813,7 @@ dependencies = [ [[package]] name = "turbopack-trace-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "crossbeam-channel", @@ -7829,7 +7829,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240411.3#9d45eacc8bf80f52cd445d2926fabbf9fe7a535c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240415.5#f91c908fb1e7f6a047bfe0b35cc9143ba4c5e5ea" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index ad6f5669375278..81e71d9006f2be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,11 +37,11 @@ swc_core = { version = "0.90.30", features = [ testing = { version = "0.35.22" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240411.3" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240415.5" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240411.3" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240415.5" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240411.3" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240415.5" } # General Deps diff --git a/packages/next/package.json b/packages/next/package.json index 24fb91949ec955..3d9e4c3becf788 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -196,7 +196,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.26.4", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240411.3", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240415.5", "acorn": "8.5.0", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e153846c7221c4..34374c761e8839 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1068,8 +1068,8 @@ importers: specifier: 0.26.4 version: 0.26.4 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240411.3 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240411.3' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240415.5 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240415.5' acorn: specifier: 8.5.0 version: 8.5.0 @@ -25543,8 +25543,8 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240411.3': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240411.3} + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240415.5': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240415.5} name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: From 19c206038bb11c3bfc89484b534758991bbec110 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Mon, 15 Apr 2024 21:13:24 +0000 Subject: [PATCH 22/96] v14.3.0-canary.1 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 12 ++++++------ packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 14 +++++++------- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lerna.json b/lerna.json index 2b9935cf66a2d7..ad52698dd018b2 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.3.0-canary.0" + "version": "14.3.0-canary.1" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 69cacde1ce007a..a7df9a00ed3c08 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.3.0-canary.0", + "version": "14.3.0-canary.1", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index d9863c8adffa8e..1afe18e4ecca77 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.3.0-canary.0", + "version": "14.3.0-canary.1", "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": "14.3.0-canary.0", + "@next/eslint-plugin-next": "14.3.0-canary.1", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.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 20b2d820433fe7..e6643c88034017 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": "14.3.0-canary.0", + "version": "14.3.0-canary.1", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 4592bfcd639456..8989cf32d7210a 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.3.0-canary.0", + "version": "14.3.0-canary.1", "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 5f161b696565a2..a363abe31fd19f 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.3.0-canary.0", + "version": "14.3.0-canary.1", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 87e14b4f1006af..0133e3b4349604 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.3.0-canary.0", + "version": "14.3.0-canary.1", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index dce10fc3569a86..7d6f68916cb6f7 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.3.0-canary.0", + "version": "14.3.0-canary.1", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 7ac62a98cbed91..91438f29c3ba08 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.3.0-canary.0", + "version": "14.3.0-canary.1", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 739bb1da866778..bad84191f7d9b7 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.3.0-canary.0", + "version": "14.3.0-canary.1", "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 f36c05ab6b5097..0a61d6f2cebd4e 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.3.0-canary.0", + "version": "14.3.0-canary.1", "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 0254528c6718e2..832c6a243177ad 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.3.0-canary.0", + "version": "14.3.0-canary.1", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 80fce235c50034..4af621ba219369 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.3.0-canary.0", + "version": "14.3.0-canary.1", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 3d9e4c3becf788..b56130b2ee3e38 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.3.0-canary.0", + "version": "14.3.0-canary.1", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.3.0-canary.0", + "@next/env": "14.3.0-canary.1", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -149,10 +149,10 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/polyfill-module": "14.3.0-canary.0", - "@next/polyfill-nomodule": "14.3.0-canary.0", - "@next/react-refresh-utils": "14.3.0-canary.0", - "@next/swc": "14.3.0-canary.0", + "@next/polyfill-module": "14.3.0-canary.1", + "@next/polyfill-nomodule": "14.3.0-canary.1", + "@next/react-refresh-utils": "14.3.0-canary.1", + "@next/swc": "14.3.0-canary.1", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", "@taskr/clear": "1.1.0", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 041db27371ab02..cf8f5c3b6698b4 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": "14.3.0-canary.0", + "version": "14.3.0-canary.1", "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 f4e0eadd2bac51..560e7e0622545c 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.3.0-canary.0", + "version": "14.3.0-canary.1", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -26,7 +26,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.3.0-canary.0", + "next": "14.3.0-canary.1", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 34374c761e8839..c8e6887618d965 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -744,7 +744,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.3.0-canary.0 + specifier: 14.3.0-canary.1 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.3.0-canary.0 + specifier: 14.3.0-canary.1 version: link:../next-env '@swc/helpers': specifier: 0.5.5 @@ -927,16 +927,16 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/polyfill-module': - specifier: 14.3.0-canary.0 + specifier: 14.3.0-canary.1 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.3.0-canary.0 + specifier: 14.3.0-canary.1 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 14.3.0-canary.0 + specifier: 14.3.0-canary.1 version: link:../react-refresh-utils '@next/swc': - specifier: 14.3.0-canary.0 + specifier: 14.3.0-canary.1 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1551,7 +1551,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.3.0-canary.0 + specifier: 14.3.0-canary.1 version: link:../next outdent: specifier: 0.8.0 From 24575b3a09324896bf0ac1c810876bc3d3b24175 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 15 Apr 2024 14:15:10 -0700 Subject: [PATCH 23/96] Update to latest rust-cache (#64524) Updates to latest version which bumps Node.js version to avoid v16 deprecation. Closes NEXT-3120 --- .github/workflows/build_and_deploy.yml | 2 +- .github/workflows/build_reusable.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_and_deploy.yml b/.github/workflows/build_and_deploy.yml index 9d7c3912eac848..1a445fd315c22f 100644 --- a/.github/workflows/build_and_deploy.yml +++ b/.github/workflows/build_and_deploy.yml @@ -269,7 +269,7 @@ jobs: if: ${{ matrix.settings.setup }} - name: Cache on ${{ github.ref_name }} - uses: ijjk/rust-cache@turbo-cache-v1.0.7 + uses: ijjk/rust-cache@turbo-cache-v1.0.8 with: save-if: 'true' cache-provider: 'turbo' diff --git a/.github/workflows/build_reusable.yml b/.github/workflows/build_reusable.yml index 0d48f5403af8ac..fc8fc373e09b5c 100644 --- a/.github/workflows/build_reusable.yml +++ b/.github/workflows/build_reusable.yml @@ -125,7 +125,7 @@ jobs: - run: corepack prepare --activate yarn@1.22.19 && npm i -g "turbo@${TURBO_VERSION}" "@napi-rs/cli@${NAPI_CLI_VERSION}" - name: Cache on ${{ github.ref_name }} - uses: ijjk/rust-cache@turbo-cache-v1.0.7 + uses: ijjk/rust-cache@turbo-cache-v1.0.8 if: ${{ inputs.rustCacheKey }} with: cache-provider: 'turbo' From f79440260cf21260d19e00a20802bb4743addc24 Mon Sep 17 00:00:00 2001 From: Will Binns-Smith Date: Mon, 15 Apr 2024 14:18:56 -0700 Subject: [PATCH 24/96] Turbopack: Allow client components to be imported in app routes (#64520) Resolves #64412 This adds a client transition to the app route `ModuleAssetContext` and the corresponding transforms so that client components can be safely imported and referenced (as their proxies) in app routes. Test Plan: Added an integration test Closes PACK-2964 --- packages/next-swc/crates/next-api/src/app.rs | 22 ++++++++++++++++++- .../crates/next-core/src/next_import_map.rs | 2 +- .../next-core/src/next_server/context.rs | 22 ++++++++++++++++++- .../ClientComponent.tsx | 5 +++++ .../app-routes-client-component.test.ts | 19 ++++++++++++++++ .../app/runtime/route.ts | 8 +++++++ 6 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 test/e2e/app-dir/app-routes-client-component/ClientComponent.tsx create mode 100644 test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts create mode 100644 test/e2e/app-dir/app-routes-client-component/app/runtime/route.ts diff --git a/packages/next-swc/crates/next-api/src/app.rs b/packages/next-swc/crates/next-api/src/app.rs index 5c8d73a56b5117..9f82537007f13c 100644 --- a/packages/next-swc/crates/next-api/src/app.rs +++ b/packages/next-swc/crates/next-api/src/app.rs @@ -103,6 +103,7 @@ impl AppProject { fn route_ty(self: Vc) -> ServerContextType { ServerContextType::AppRoute { app_dir: self.app_dir(), + ecmascript_client_reference_transition_name: Some(self.client_transition_name()), } } @@ -328,8 +329,27 @@ impl AppProject { #[turbo_tasks::function] fn route_module_context(self: Vc) -> Vc { + let transitions = [ + ( + ECMASCRIPT_CLIENT_TRANSITION_NAME.to_string(), + Vc::upcast(NextEcmascriptClientReferenceTransition::new( + Vc::upcast(self.client_transition()), + self.ssr_transition(), + )), + ), + ( + "next-dynamic".to_string(), + Vc::upcast(NextDynamicTransition::new(Vc::upcast( + self.client_transition(), + ))), + ), + ("next-ssr".to_string(), Vc::upcast(self.ssr_transition())), + ] + .into_iter() + .collect(); + ModuleAssetContext::new( - Default::default(), + Vc::cell(transitions), self.project().server_compile_time_info(), self.route_module_options_context(), self.route_resolve_options_context(), 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 76114d0e6b1862..1be71bf8e7cc8b 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 @@ -575,7 +575,7 @@ async fn insert_next_server_special_aliases( // the logic closely follows the one in createRSCAliases in webpack-config.ts ServerContextType::AppSSR { app_dir } | ServerContextType::AppRSC { app_dir, .. } - | ServerContextType::AppRoute { app_dir } => { + | ServerContextType::AppRoute { app_dir, .. } => { import_map.insert_exact_alias( "styled-jsx", request_to_import_mapping(get_next_package(app_dir), "styled-jsx"), 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 c044e1f32e01e0..d4bd4703e92cff 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 @@ -93,6 +93,7 @@ pub enum ServerContextType { }, AppRoute { app_dir: Vc, + ecmascript_client_reference_transition_name: Option>, }, Middleware, Instrumentation, @@ -616,8 +617,27 @@ pub async fn get_server_module_options_context( ..module_options_context } } - ServerContextType::AppRoute { .. } => { + ServerContextType::AppRoute { + app_dir, + ecmascript_client_reference_transition_name, + } => { next_server_rules.extend(source_transform_rules); + if let Some(ecmascript_client_reference_transition_name) = + ecmascript_client_reference_transition_name + { + next_server_rules.push(get_ecma_transform_rule( + Box::new(ClientDirectiveTransformer::new( + ecmascript_client_reference_transition_name, + )), + enable_mdx_rs.is_some(), + true, + )); + } + + next_server_rules.push( + get_next_react_server_components_transform_rule(next_config, true, Some(app_dir)) + .await?, + ); let module_options_context = ModuleOptionsContext { esm_url_rewrite_behavior: Some(UrlRewriteBehavior::Full), diff --git a/test/e2e/app-dir/app-routes-client-component/ClientComponent.tsx b/test/e2e/app-dir/app-routes-client-component/ClientComponent.tsx new file mode 100644 index 00000000000000..bac9e866ae4d3e --- /dev/null +++ b/test/e2e/app-dir/app-routes-client-component/ClientComponent.tsx @@ -0,0 +1,5 @@ +'use client' + +export function ClientComponent() { + return
ClientComponent
+} diff --git a/test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts b/test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts new file mode 100644 index 00000000000000..c85903614f4d90 --- /dev/null +++ b/test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts @@ -0,0 +1,19 @@ +import { FileRef, nextTestSetup } from 'e2e-utils' +import path from 'path' + +describe('referencing a client component in an app route', () => { + const { next } = nextTestSetup({ + files: new FileRef(path.join(__dirname)), + dependencies: { + react: 'latest', + 'react-dom': 'latest', + }, + }) + + it('responds without error', async () => { + expect(JSON.parse(await next.render('/runtime'))).toEqual({ + // Turbopack's proxy components are functions + clientComponent: process.env.TURBOPACK ? 'function' : 'object', + }) + }) +}) diff --git a/test/e2e/app-dir/app-routes-client-component/app/runtime/route.ts b/test/e2e/app-dir/app-routes-client-component/app/runtime/route.ts new file mode 100644 index 00000000000000..e4ce5094e904d0 --- /dev/null +++ b/test/e2e/app-dir/app-routes-client-component/app/runtime/route.ts @@ -0,0 +1,8 @@ +import { NextResponse } from 'next/server' +import { ClientComponent } from '../../ClientComponent' + +export function GET() { + return NextResponse.json({ + clientComponent: typeof ClientComponent, + }) +} From d1e7847ad12ebe6eb6a79af6c281c1b6707fbeb3 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Mon, 15 Apr 2024 23:33:07 +0200 Subject: [PATCH 25/96] refactor: remove always truthy flag (#64522) Remove the `this.exportRuntime` flag in build manifest plugin where it's always true Closes NEXT-3118 --- packages/next/src/build/webpack-config.ts | 1 - .../build/webpack/plugins/build-manifest-plugin.ts | 12 +++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/packages/next/src/build/webpack-config.ts b/packages/next/src/build/webpack-config.ts index a3a6218e75f5be..0f48f804c567dd 100644 --- a/packages/next/src/build/webpack-config.ts +++ b/packages/next/src/build/webpack-config.ts @@ -1815,7 +1815,6 @@ export default async function getBaseWebpackConfig( buildId, rewrites, isDevFallback, - exportRuntime: true, appDirEnabled: hasAppDir, }), new ProfilingPlugin({ runWebpackSpan, rootDir: dir }), diff --git a/packages/next/src/build/webpack/plugins/build-manifest-plugin.ts b/packages/next/src/build/webpack/plugins/build-manifest-plugin.ts index 9b9c3006d9a56c..5486a50b715957 100644 --- a/packages/next/src/build/webpack/plugins/build-manifest-plugin.ts +++ b/packages/next/src/build/webpack/plugins/build-manifest-plugin.ts @@ -123,14 +123,12 @@ export default class BuildManifestPlugin { private buildId: string private rewrites: CustomRoutes['rewrites'] private isDevFallback: boolean - private exportRuntime: boolean private appDirEnabled: boolean constructor(options: { buildId: string rewrites: CustomRoutes['rewrites'] isDevFallback?: boolean - exportRuntime?: boolean appDirEnabled: boolean }) { this.buildId = options.buildId @@ -144,7 +142,6 @@ export default class BuildManifestPlugin { this.rewrites.beforeFiles = options.rewrites.beforeFiles.map(processRoute) this.rewrites.afterFiles = options.rewrites.afterFiles.map(processRoute) this.rewrites.fallback = options.rewrites.fallback.map(processRoute) - this.exportRuntime = !!options.exportRuntime } createAssets(compiler: any, compilation: any, assets: any) { @@ -258,12 +255,9 @@ export default class BuildManifestPlugin { JSON.stringify(assetMap, null, 2) ) - if (this.exportRuntime) { - assets[`server/${MIDDLEWARE_BUILD_MANIFEST}.js`] = - new sources.RawSource( - `self.__BUILD_MANIFEST=${JSON.stringify(assetMap)}` - ) - } + assets[`server/${MIDDLEWARE_BUILD_MANIFEST}.js`] = new sources.RawSource( + `self.__BUILD_MANIFEST=${JSON.stringify(assetMap)}` + ) if (!this.isDevFallback) { const clientManifestPath = `${CLIENT_STATIC_FILES_PATH}/${this.buildId}/_buildManifest.js` From cd36a8f21795b3b68477e411c3d5259ce3ba7c7b Mon Sep 17 00:00:00 2001 From: Will Binns-Smith Date: Mon, 15 Apr 2024 14:40:56 -0700 Subject: [PATCH 26/96] =?UTF-8?q?Turbopack:=20don=E2=80=99t=20show=20long?= =?UTF-8?q?=20internal=20stack=20traces=20on=20build=20errors=20(#64427)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turbopack: don’t show long internal stack traces on build errors Fixes PACK-2909 Looks like this may have been introduced in #61929, when code was moved out of `setup-dev-bundler.ts`, `ModuleBuildError` was duplicated and no longer satisfied the `instanceof` check. Closes PACK-2951 --- .../next/src/server/dev/turbopack-utils.ts | 2 +- .../lib/router-utils/setup-dev-bundler.ts | 42 +++++++++---------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/packages/next/src/server/dev/turbopack-utils.ts b/packages/next/src/server/dev/turbopack-utils.ts index 75d6d9a98460e3..b9b5c6252c56ec 100644 --- a/packages/next/src/server/dev/turbopack-utils.ts +++ b/packages/next/src/server/dev/turbopack-utils.ts @@ -41,7 +41,7 @@ export async function getTurbopackJsConfig( return jsConfig ?? { compilerOptions: {} } } -class ModuleBuildError extends Error {} +export class ModuleBuildError extends Error {} /** * Thin stopgap workaround layer to mimic existing wellknown-errors-plugin in webpack's build diff --git a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts index f3eb481850a506..79fbba8c00c418 100644 --- a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts +++ b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts @@ -76,6 +76,7 @@ import { createHotReloaderTurbopack } from '../../dev/hot-reloader-turbopack' import { getErrorSource } from '../../../shared/lib/error-source' import type { StackFrame } from 'next/dist/compiled/stacktrace-parser' import { generateEncryptionKeyBase64 } from '../../app-render/encryption-utils' +import { ModuleBuildError } from '../../dev/turbopack-utils' export type SetupOpts = { renderServer: LazyRenderServerInstance @@ -128,8 +129,6 @@ async function verifyTypeScript(opts: SetupOpts) { return usingTypeScript } -class ModuleBuildError extends Error {} - export async function propagateServerField( opts: SetupOpts, field: PropagateToWorkersField, @@ -972,15 +971,7 @@ async function startWatcher(opts: SetupOpts) { errorToLog = err } - if (type === 'warning') { - Log.warn(errorToLog) - } else if (type === 'app-dir') { - logAppDirError(errorToLog) - } else if (type) { - Log.error(`${type}:`, errorToLog) - } else { - Log.error(errorToLog) - } + logError(errorToLog, type) console[type === 'warning' ? 'warn' : 'error'](originalCodeFrame) usedOriginalStack = true } @@ -993,17 +984,7 @@ async function startWatcher(opts: SetupOpts) { } if (!usedOriginalStack) { - if (err instanceof ModuleBuildError) { - Log.error(err.message) - } else if (type === 'warning') { - Log.warn(err) - } else if (type === 'app-dir') { - logAppDirError(err) - } else if (type) { - Log.error(`${type}:`, err) - } else { - Log.error(err) - } + logError(err, type) } } @@ -1025,6 +1006,23 @@ async function startWatcher(opts: SetupOpts) { } } +function logError( + err: unknown, + type?: 'unhandledRejection' | 'uncaughtException' | 'warning' | 'app-dir' +) { + if (err instanceof ModuleBuildError) { + Log.error(err.message) + } else if (type === 'warning') { + Log.warn(err) + } else if (type === 'app-dir') { + logAppDirError(err) + } else if (type) { + Log.error(`${type}:`, err) + } else { + Log.error(err) + } +} + export async function setupDevBundler(opts: SetupOpts) { const isSrcDir = path .relative(opts.dir, opts.pagesDir || opts.appDir || '') From a9adf0db67271b143c29b4651434de784deea74e Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Mon, 15 Apr 2024 21:45:17 +0000 Subject: [PATCH 27/96] v14.3.0-canary.2 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 12 ++++++------ packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 14 +++++++------- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lerna.json b/lerna.json index ad52698dd018b2..da3651dfbbd9cc 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.3.0-canary.1" + "version": "14.3.0-canary.2" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index a7df9a00ed3c08..321e7124946a45 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.3.0-canary.1", + "version": "14.3.0-canary.2", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 1afe18e4ecca77..67ad4c8d62601b 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.3.0-canary.1", + "version": "14.3.0-canary.2", "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": "14.3.0-canary.1", + "@next/eslint-plugin-next": "14.3.0-canary.2", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.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 e6643c88034017..92dce7798e30b0 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": "14.3.0-canary.1", + "version": "14.3.0-canary.2", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 8989cf32d7210a..530faf95c67dfc 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.3.0-canary.1", + "version": "14.3.0-canary.2", "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 a363abe31fd19f..4886b0c8bc86de 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.3.0-canary.1", + "version": "14.3.0-canary.2", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 0133e3b4349604..2e0a926835bba7 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.3.0-canary.1", + "version": "14.3.0-canary.2", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 7d6f68916cb6f7..e98ba58ba842c6 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.3.0-canary.1", + "version": "14.3.0-canary.2", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 91438f29c3ba08..5e7fef686479f1 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.3.0-canary.1", + "version": "14.3.0-canary.2", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index bad84191f7d9b7..fcc34376f81e3c 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.3.0-canary.1", + "version": "14.3.0-canary.2", "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 0a61d6f2cebd4e..432ca6081d33b6 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.3.0-canary.1", + "version": "14.3.0-canary.2", "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 832c6a243177ad..4ed86867ba2172 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.3.0-canary.1", + "version": "14.3.0-canary.2", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 4af621ba219369..687ec2afa1148e 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.3.0-canary.1", + "version": "14.3.0-canary.2", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index b56130b2ee3e38..2fa681b8d0b479 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.3.0-canary.1", + "version": "14.3.0-canary.2", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.3.0-canary.1", + "@next/env": "14.3.0-canary.2", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -149,10 +149,10 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/polyfill-module": "14.3.0-canary.1", - "@next/polyfill-nomodule": "14.3.0-canary.1", - "@next/react-refresh-utils": "14.3.0-canary.1", - "@next/swc": "14.3.0-canary.1", + "@next/polyfill-module": "14.3.0-canary.2", + "@next/polyfill-nomodule": "14.3.0-canary.2", + "@next/react-refresh-utils": "14.3.0-canary.2", + "@next/swc": "14.3.0-canary.2", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", "@taskr/clear": "1.1.0", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index cf8f5c3b6698b4..95240fd731609c 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": "14.3.0-canary.1", + "version": "14.3.0-canary.2", "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 560e7e0622545c..047cc1939cc5e2 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.3.0-canary.1", + "version": "14.3.0-canary.2", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -26,7 +26,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.3.0-canary.1", + "next": "14.3.0-canary.2", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c8e6887618d965..caee652b85cc6d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -744,7 +744,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.3.0-canary.1 + specifier: 14.3.0-canary.2 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.3.0-canary.1 + specifier: 14.3.0-canary.2 version: link:../next-env '@swc/helpers': specifier: 0.5.5 @@ -927,16 +927,16 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/polyfill-module': - specifier: 14.3.0-canary.1 + specifier: 14.3.0-canary.2 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.3.0-canary.1 + specifier: 14.3.0-canary.2 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 14.3.0-canary.1 + specifier: 14.3.0-canary.2 version: link:../react-refresh-utils '@next/swc': - specifier: 14.3.0-canary.1 + specifier: 14.3.0-canary.2 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1551,7 +1551,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.3.0-canary.1 + specifier: 14.3.0-canary.2 version: link:../next outdent: specifier: 0.8.0 From c9bfe4c8927bfd301fa6908c6bb6855f583aad55 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 15 Apr 2024 14:53:23 -0700 Subject: [PATCH 28/96] Require turbopack build jobs (#64526) These should be required for the workflow to be considered passing so that we don't accidentally forget to update the manifests Closes NEXT-3122 --- .github/workflows/build_and_test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 1606168096e70e..b7a44dd852a131 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -461,6 +461,8 @@ jobs: 'test-turbopack-integration', 'test-new-tests-dev', 'test-new-tests-start', + 'test-turbopack-production', + 'test-turbopack-production-integration', ] if: always() From f563940f69a95d9792e4c8f533611e3ae2671a08 Mon Sep 17 00:00:00 2001 From: Adam Jones Date: Mon, 15 Apr 2024 23:01:50 +0100 Subject: [PATCH 29/96] next/script: Correctly apply async and defer props (#52939) ### Summary Fixes #52935 `next/script` has a `Script` component that supports an `async` prop. However, when scripts are loaded with the `async` prop set to false, the script is loaded as if async was set to true. This may cause scripts to execute out of order. Repro: https://github.com/domdomegg/next-async-script-reproduction I think this is occurring because Next uses setAttribute to set the async and defer attributes. However, this is not a valid way to set these properties on a script. This is because . Demo: https://jsfiddle.net/6ktpfae1/ This PR fixes this behaviour by using removeAttribute after calling setAttribute (rather than using setAttribute "false"). This appears to result in correct behaviour. Given it appears this workaround was already applied in `next/head`, I've harmonised the code between these two. ### Next steps I think this PR is ready for review. I acknowledge there are no test changes, but there are no existing tests for `next/script` at all and creating them I think would be disproportionally difficult given issues in #52943. --------- Co-authored-by: Tim Neutkens Co-authored-by: Sam Ko Co-authored-by: JJ Kasper --- packages/next/src/client/head-manager.ts | 26 +------- packages/next/src/client/script.tsx | 21 +------ .../src/client/set-attributes-from-props.ts | 59 +++++++++++++++++++ .../client-navigation/fixture/pages/head.js | 4 +- .../client-navigation/fixture/pages/script.js | 11 ++++ .../{test-async.js => test-async-false.js} | 0 .../fixture/public/test-async-true.js | 0 .../pages-dir/client-navigation/index.test.ts | 48 +++++++++++++++ .../pages-dir/client-navigation/rendering.ts | 3 +- tsec-exemptions.json | 1 + 10 files changed, 128 insertions(+), 45 deletions(-) create mode 100644 packages/next/src/client/set-attributes-from-props.ts create mode 100644 test/development/pages-dir/client-navigation/fixture/pages/script.js rename test/development/pages-dir/client-navigation/fixture/public/{test-async.js => test-async-false.js} (100%) create mode 100644 test/development/pages-dir/client-navigation/fixture/public/test-async-true.js diff --git a/packages/next/src/client/head-manager.ts b/packages/next/src/client/head-manager.ts index 5d9bc835653afd..8d477e46e9fb41 100644 --- a/packages/next/src/client/head-manager.ts +++ b/packages/next/src/client/head-manager.ts @@ -1,30 +1,8 @@ -export const DOMAttributeNames: Record = { - acceptCharset: 'accept-charset', - className: 'class', - htmlFor: 'for', - httpEquiv: 'http-equiv', - noModule: 'noModule', -} +import { setAttributesFromProps } from './set-attributes-from-props' function reactElementToDOM({ type, props }: JSX.Element): HTMLElement { const el: HTMLElement = document.createElement(type) - for (const p in props) { - if (!props.hasOwnProperty(p)) continue - if (p === 'children' || p === 'dangerouslySetInnerHTML') continue - - // we don't render undefined props to the DOM - if (props[p] === undefined) continue - - const attr = DOMAttributeNames[p] || p.toLowerCase() - if ( - type === 'script' && - (attr === 'async' || attr === 'defer' || attr === 'noModule') - ) { - ;(el as HTMLScriptElement)[attr] = !!props[p] - } else { - el.setAttribute(attr, props[p]) - } - } + setAttributesFromProps(el, props) const { children, dangerouslySetInnerHTML } = props if (dangerouslySetInnerHTML) { diff --git a/packages/next/src/client/script.tsx b/packages/next/src/client/script.tsx index 32f8ea719b0f37..834dc83e804a22 100644 --- a/packages/next/src/client/script.tsx +++ b/packages/next/src/client/script.tsx @@ -4,7 +4,7 @@ import ReactDOM from 'react-dom' import React, { useEffect, useContext, useRef } from 'react' import type { ScriptHTMLAttributes } from 'react' import { HeadManagerContext } from '../shared/lib/head-manager-context.shared-runtime' -import { DOMAttributeNames } from './head-manager' +import { setAttributesFromProps } from './set-attributes-from-props' import { requestIdleCallback } from './request-idle-callback' const ScriptCache = new Map() @@ -25,16 +25,6 @@ export interface ScriptProps extends ScriptHTMLAttributes { */ export type Props = ScriptProps -const ignoreProps = [ - 'onLoad', - 'onReady', - 'dangerouslySetInnerHTML', - 'children', - 'onError', - 'strategy', - 'stylesheets', -] - const insertStylesheets = (stylesheets: string[]) => { // Case 1: Styles for afterInteractive/lazyOnload with appDir injected via handleClientScriptLoad // @@ -148,14 +138,7 @@ const loadScript = (props: ScriptProps): void => { ScriptCache.set(src, loadPromise) } - for (const [k, value] of Object.entries(props)) { - if (value === undefined || ignoreProps.includes(k)) { - continue - } - - const attr = DOMAttributeNames[k] || k.toLowerCase() - el.setAttribute(attr, value) - } + setAttributesFromProps(el, props) if (strategy === 'worker') { el.setAttribute('type', 'text/partytown') diff --git a/packages/next/src/client/set-attributes-from-props.ts b/packages/next/src/client/set-attributes-from-props.ts new file mode 100644 index 00000000000000..f5141a57d6f27a --- /dev/null +++ b/packages/next/src/client/set-attributes-from-props.ts @@ -0,0 +1,59 @@ +const DOMAttributeNames: Record = { + acceptCharset: 'accept-charset', + className: 'class', + htmlFor: 'for', + httpEquiv: 'http-equiv', + noModule: 'noModule', +} + +const ignoreProps = [ + 'onLoad', + 'onReady', + 'dangerouslySetInnerHTML', + 'children', + 'onError', + 'strategy', + 'stylesheets', +] + +function isBooleanScriptAttribute( + attr: string +): attr is 'async' | 'defer' | 'noModule' { + return ['async', 'defer', 'noModule'].includes(attr) +} + +export function setAttributesFromProps(el: HTMLElement, props: object) { + for (const [p, value] of Object.entries(props)) { + if (!props.hasOwnProperty(p)) continue + if (ignoreProps.includes(p)) continue + + // we don't render undefined props to the DOM + if (value === undefined) { + continue + } + + const attr = DOMAttributeNames[p] || p.toLowerCase() + + if (el.tagName === 'SCRIPT' && isBooleanScriptAttribute(attr)) { + // Correctly assign boolean script attributes + // https://github.com/vercel/next.js/pull/20748 + ;(el as HTMLScriptElement)[attr] = !!value + } else { + el.setAttribute(attr, String(value)) + } + + // Remove falsy non-zero boolean attributes so they are correctly interpreted + // (e.g. if we set them to false, this coerces to the string "false", which the browser interprets as true) + if ( + value === false || + (el.tagName === 'SCRIPT' && + isBooleanScriptAttribute(attr) && + (!value || value === 'false')) + ) { + // Call setAttribute before, as we need to set and unset the attribute to override force async: + // https://html.spec.whatwg.org/multipage/scripting.html#script-force-async + el.setAttribute(attr, '') + el.removeAttribute(attr) + } + } +} diff --git a/test/development/pages-dir/client-navigation/fixture/pages/head.js b/test/development/pages-dir/client-navigation/fixture/pages/head.js index bd50dddcc54d46..a143355259fa23 100644 --- a/test/development/pages-dir/client-navigation/fixture/pages/head.js +++ b/test/development/pages-dir/client-navigation/fixture/pages/head.js @@ -116,7 +116,9 @@ export default () => ( {/* this should not execute twice on the client */} - + + {/* this should have async set to false on the client */} + {/* this should not execute twice on the client (intentionally sets defer to `yas` to test boolean coercion) */} diff --git a/test/development/pages-dir/client-navigation/fixture/pages/script.js b/test/development/pages-dir/client-navigation/fixture/pages/script.js new file mode 100644 index 00000000000000..7e3558850fd92e --- /dev/null +++ b/test/development/pages-dir/client-navigation/fixture/pages/script.js @@ -0,0 +1,11 @@ +import React from 'react' +import Script from 'next/script' + +export default () => ( +
+

I am a page to test next/script

+