-
diff --git a/errors/react-hydration-error.md b/errors/react-hydration-error.md index e78e9b7c54976..26d65c5516767 100644 --- a/errors/react-hydration-error.md +++ b/errors/react-hydration-error.md @@ -84,5 +84,5 @@ Common causes with css-in-js libraries: ### Useful Links -- [React Hydration Documentation](https://reactjs.org/docs/react-dom.html#hydrate) +- [React Hydration Documentation](https://reactjs.org/docs/react-dom-client.html#hydrateroot) - [Josh Comeau's article on React Hydration](https://www.joshwcomeau.com/react/the-perils-of-rehydration/) diff --git a/examples/with-chakra-ui/README.md b/examples/with-chakra-ui/README.md index ba37792453b2d..60720036ddcde 100644 --- a/examples/with-chakra-ui/README.md +++ b/examples/with-chakra-ui/README.md @@ -10,7 +10,7 @@ We are connecting the Next.js `_app.js` with `chakra-ui`'s Provider and theme so Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) or preview live with [StackBlitz](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-chakra-ui) -[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-chakra-ui-typescript&project-name=with-chakra-ui&repository-name=with-chakra-ui) +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-chakra-ui&project-name=with-chakra-ui&repository-name=with-chakra-ui) ## How to use diff --git a/lerna.json b/lerna.json index 489c08307e975..b45ccf0f78e2e 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "12.3.2-canary.7" + "version": "12.3.2-canary.9" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 056e2968c1847..e9e29e34788dd 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "12.3.2-canary.7", + "version": "12.3.2-canary.9", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 7dde295ad3cb5..f3ee7eb2be5fb 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "12.3.2-canary.7", + "version": "12.3.2-canary.9", "description": "ESLint configuration used by NextJS.", "main": "index.js", "license": "MIT", @@ -9,7 +9,7 @@ "directory": "packages/eslint-config-next" }, "dependencies": { - "@next/eslint-plugin-next": "12.3.2-canary.7", + "@next/eslint-plugin-next": "12.3.2-canary.9", "@rushstack/eslint-patch": "^1.1.3", "@typescript-eslint/parser": "^5.21.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/lib/rules/no-head-element.js b/packages/eslint-plugin-next/lib/rules/no-head-element.js index 42b44991c9107..c1668b2cf6fca 100644 --- a/packages/eslint-plugin-next/lib/rules/no-head-element.js +++ b/packages/eslint-plugin-next/lib/rules/no-head-element.js @@ -14,7 +14,11 @@ module.exports = { create: function (context) { return { JSXOpeningElement(node) { - if (node.name.name !== 'head') { + const paths = context.getFilename() + + const isInAppDir = paths.includes('app/') && !paths.includes('pages/') + // Only lint the
element in pages directory + if (node.name.name !== 'head' || isInAppDir) { return } diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 005a939a0dd46..7043bfe1c4b42 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": "12.3.2-canary.7", + "version": "12.3.2-canary.9", "description": "ESLint plugin for NextJS.", "main": "lib/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index e57155dba9fc5..f5f29f3907e74 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "12.3.2-canary.7", + "version": "12.3.2-canary.9", "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 b4b90f218a0fd..0a6a060d4bf43 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "12.3.2-canary.7", + "version": "12.3.2-canary.9", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 82177a42c48be..fdbd95f97410d 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "12.3.2-canary.7", + "version": "12.3.2-canary.9", "license": "MIT", "dependencies": { "chalk": "4.1.0", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index ce9aded51d075..5e5bd5680b6da 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "12.3.2-canary.7", + "version": "12.3.2-canary.9", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index c0605a402b56f..948ec09453acf 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "12.3.2-canary.7", + "version": "12.3.2-canary.9", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index c2517dc835dab..b4d9c35c606a3 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "12.3.2-canary.7", + "version": "12.3.2-canary.9", "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 06a93895a5772..a0100dc3aa9bd 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "12.3.2-canary.7", + "version": "12.3.2-canary.9", "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 870d47e2bc61c..4ffda06fea520 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "12.3.2-canary.7", + "version": "12.3.2-canary.9", "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 dd1155701e555..e4035884b37f7 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "12.3.2-canary.7", + "version": "12.3.2-canary.9", "private": true, "scripts": { "build-native": "napi build --platform -p next-swc-napi --cargo-name next_swc_napi native --features plugin", diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index e23463e2a3011..2af0e86ee8678 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -1007,14 +1007,7 @@ export default async function getBaseWebpackConfig( alias: process.env.__NEXT_REACT_CHANNEL ? { react: `react-${process.env.__NEXT_REACT_CHANNEL}`, - 'react/package.json': `react-${process.env.__NEXT_REACT_CHANNEL}/package.json`, - 'react/jsx-runtime': `react-${process.env.__NEXT_REACT_CHANNEL}/jsx-runtime`, - 'react/jsx-dev-runtime': `react-${process.env.__NEXT_REACT_CHANNEL}/jsx-dev-runtime`, 'react-dom': `react-dom-${process.env.__NEXT_REACT_CHANNEL}`, - 'react-dom/package.json': `react-dom-${process.env.__NEXT_REACT_CHANNEL}/package.json`, - 'react-dom/server': `react-dom-${process.env.__NEXT_REACT_CHANNEL}/server`, - 'react-dom/server.browser': `react-dom-${process.env.__NEXT_REACT_CHANNEL}/server.browser`, - 'react-dom/client': `react-dom-${process.env.__NEXT_REACT_CHANNEL}/client`, } : false, conditionNames: ['react-server'], @@ -1172,10 +1165,10 @@ export default async function getBaseWebpackConfig( context, request ) - return resolved + return `${externalType} ${resolved}` } catch (err) { - // The `react-server` condition is not matched, fallback. return + // The `react-server` condition is not matched, fallback. } } diff --git a/packages/next/build/webpack/loaders/next-font-loader/index.ts b/packages/next/build/webpack/loaders/next-font-loader/index.ts index 7ca2455227b68..9ab979e69e4a3 100644 --- a/packages/next/build/webpack/loaders/next-font-loader/index.ts +++ b/packages/next/build/webpack/loaders/next-font-loader/index.ts @@ -22,7 +22,7 @@ export default async function nextFontLoader(this: any) { const interpolatedName = loaderUtils.interpolateName( this, // Font files ending with .p.(woff|woff2|eot|ttf|otf) are preloaded - `static/fonts/[hash]${preload ? '.p' : ''}.${ext}`, + `static/media/[hash]${preload ? '.p' : ''}.${ext}`, opts ) const outputPath = `${assetPrefix}/_next/${interpolatedName}` diff --git a/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts b/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts index 6226bb18052c4..e3083547890c8 100644 --- a/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts +++ b/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts @@ -16,7 +16,8 @@ import { COMPILER_NAMES, FLIGHT_SERVER_CSS_MANIFEST, } from '../../../shared/lib/constants' -import { FlightCSSManifest } from './flight-manifest-plugin' +import { FlightCSSManifest, traverseModules } from './flight-manifest-plugin' +import { ASYNC_CLIENT_MODULES } from './flight-manifest-plugin' import { isClientComponentModule } from '../loaders/utils' interface Options { @@ -64,6 +65,18 @@ export class FlightClientEntryPlugin { compiler.hooks.finishMake.tapPromise(PLUGIN_NAME, (compilation) => { return this.createClientEntries(compiler, compilation) }) + + compiler.hooks.afterCompile.tap(PLUGIN_NAME, (compilation) => { + traverseModules(compilation, (mod) => { + // The module must has request, and resource so it's not a new entry created with loader. + // Using the client layer module, which doesn't have `rsc` tag in buildInfo. + if (mod.request && mod.resource && !mod.buildInfo.rsc) { + if (compilation.moduleGraph.isAsync(mod)) { + ASYNC_CLIENT_MODULES.add(mod.resource) + } + } + }) + }) } async createClientEntries(compiler: any, compilation: any) { @@ -380,6 +393,7 @@ export class FlightClientEntryPlugin { compilation.hooks.failedEntry.call(entry, options, err) return reject(err) } + compilation.hooks.succeedEntry.call(entry, options, module) return resolve(module) } diff --git a/packages/next/build/webpack/plugins/flight-manifest-plugin.ts b/packages/next/build/webpack/plugins/flight-manifest-plugin.ts index 271e7bb721b84..fe8f55fb22444 100644 --- a/packages/next/build/webpack/plugins/flight-manifest-plugin.ts +++ b/packages/next/build/webpack/plugins/flight-manifest-plugin.ts @@ -44,6 +44,11 @@ interface ManifestNode { * Chunks for the module. JS and CSS. */ chunks: ManifestChunks + + /** + * If chunk contains async module + */ + async?: boolean } } @@ -61,6 +66,37 @@ export type FlightCSSManifest = { const PLUGIN_NAME = 'FlightManifestPlugin' +// Collect modules from server/edge compiler in client layer, +// and detect if it's been used, and mark it as `async: true` for react. +// So that react could unwrap the async module from promise and render module itself. +export const ASYNC_CLIENT_MODULES = new Set{name}
) diff --git a/test/e2e/app-dir/rsc-basic/app/shared/page.js b/test/e2e/app-dir/rsc-basic/app/shared/page.js index 761727eca2e7d..d61c03703de63 100644 --- a/test/e2e/app-dir/rsc-basic/app/shared/page.js +++ b/test/e2e/app-dir/rsc-basic/app/shared/page.js @@ -14,7 +14,6 @@ export default function Page() {