From 7d52589bd610c9770f3acafb8384e166f91c4400 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 9 May 2022 17:08:29 -0500 Subject: [PATCH 01/15] Update x-nextjs-cache header in minimal mode (#36791) --- packages/next/server/base-server.ts | 2 +- test/production/required-server-files.test.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/next/server/base-server.ts b/packages/next/server/base-server.ts index 37070426f429..4fd42d56f913 100644 --- a/packages/next/server/base-server.ts +++ b/packages/next/server/base-server.ts @@ -1629,7 +1629,7 @@ export default abstract class Server { return null } - if (isSSG) { + if (isSSG && !this.minimalMode) { // set x-nextjs-cache header to match the header // we set for the image-optimizer res.setHeader( diff --git a/test/production/required-server-files.test.ts b/test/production/required-server-files.test.ts index 8f5e3dd5084c..445e6034c714 100644 --- a/test/production/required-server-files.test.ts +++ b/test/production/required-server-files.test.ts @@ -188,6 +188,7 @@ describe('should set-up next', () => { redirect: 'manual', }) expect(res.status).toBe(200) + expect(res.headers.get('x-nextjs-cache')).toBeFalsy() const $ = cheerio.load(await res.text()) const props = JSON.parse($('#props').text()) expect(props.gspCalls).toBeDefined() @@ -201,6 +202,7 @@ describe('should set-up next', () => { } ) expect(res2.status).toBe(200) + expect(res2.headers.get('x-nextjs-cache')).toBeFalsy() const { pageProps: props2 } = await res2.json() expect(props2.gspCalls).toBe(props.gspCalls) From c7b2083f2eff850150ae6ac315d04ac74737e880 Mon Sep 17 00:00:00 2001 From: Erik Brinkman Date: Tue, 10 May 2022 06:33:31 -0400 Subject: [PATCH 02/15] Add experimental flag to force SWC transforms (#36789) fixes #36763 fixes #36590 ## Feature - [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - It hasn't been accepted for implementation, although that process isn't clear, and this is a pretty trivial fix. - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [x] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - This is somewhat inherent in the error log - [x] Errors have helpful link attached, see `contributing.md` ## Documentation / Examples - [x] Make sure the linting passes by running `yarn lint` --- errors/swc-disabled.md | 13 +++++ packages/next/build/webpack-config.ts | 2 +- packages/next/server/config-shared.ts | 2 + test/e2e/swc-warnings/index.test.ts | 68 +++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 test/e2e/swc-warnings/index.test.ts diff --git a/errors/swc-disabled.md b/errors/swc-disabled.md index ce026dd0e882..277aaf374d83 100644 --- a/errors/swc-disabled.md +++ b/errors/swc-disabled.md @@ -13,3 +13,16 @@ Many of the integrations with external libraries that currently require custom B - Emotion In order to prioritize transforms that will help you adopt SWC please provide your `.babelrc` on [the feedback thread](https://github.com/vercel/next.js/discussions/30174). + +#### Possible Ways to Fix It + +If you want to use SWC despite the presence of a `.babelrc` file you can force it in your `next.config.js` file. + +```js +// next.config.js +module.exports = { + experimental: { + forceSwcTransforms: true, + }, +} +``` diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index 724f96aa0ffa..ec7d218a1e14 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -411,7 +411,7 @@ export default async function getBaseWebpackConfig( const distDir = path.join(dir, config.distDir) - let useSWCLoader = !babelConfigFile + let useSWCLoader = !babelConfigFile || config.experimental.forceSwcTransforms let SWCBinaryTarget: [Feature, boolean] | undefined = undefined if (useSWCLoader) { // TODO: we do not collect wasm target yet diff --git a/packages/next/server/config-shared.ts b/packages/next/server/config-shared.ts index 8b1c10c8581d..b9221879b03e 100644 --- a/packages/next/server/config-shared.ts +++ b/packages/next/server/config-shared.ts @@ -135,6 +135,7 @@ export interface ExperimentalConfig { } > swcTraceProfiling?: boolean + forceSwcTransforms?: boolean } /** @@ -505,6 +506,7 @@ export const defaultConfig: NextConfig = { layoutRaw: false, remotePatterns: [], }, + forceSwcTransforms: false, }, } diff --git a/test/e2e/swc-warnings/index.test.ts b/test/e2e/swc-warnings/index.test.ts new file mode 100644 index 000000000000..018e7b81137e --- /dev/null +++ b/test/e2e/swc-warnings/index.test.ts @@ -0,0 +1,68 @@ +import { createNext } from 'e2e-utils' +import { NextInstance } from 'test/lib/next-modes/base' +import { renderViaHTTP } from 'next-test-utils' + +describe('swc warnings by default', () => { + let next: NextInstance + + beforeAll(async () => { + next = await createNext({ + files: { + 'pages/index.js': ` + export default function Page() { + return

hello world

+ } + `, + '.babelrc': ` + { + "presets": ["next/babel"] + } + `, + }, + dependencies: {}, + }) + }) + afterAll(() => next.destroy()) + + it('should have warning', async () => { + await renderViaHTTP(next.url, '/') + expect(next.cliOutput).toContain( + 'Disabled SWC as replacement for Babel because of custom Babel configuration' + ) + }) +}) + +describe('can force swc', () => { + let next: NextInstance + + beforeAll(async () => { + next = await createNext({ + nextConfig: { + experimental: { + forceSwcTransforms: true, + }, + }, + files: { + 'pages/index.js': ` + export default function Page() { + return

hello world

+ } + `, + '.babelrc': ` + { + "presets": ["next/babel"] + } + `, + }, + dependencies: {}, + }) + }) + afterAll(() => next.destroy()) + + it('should not have warning', async () => { + await renderViaHTTP(next.url, '/') + expect(next.cliOutput).not.toContain( + 'Disabled SWC as replacement for Babel because of custom Babel configuration' + ) + }) +}) From 342331e66d787fe6fcb226912c008b9196f29ac7 Mon Sep 17 00:00:00 2001 From: Marzouq Date: Tue, 10 May 2022 04:02:02 -0700 Subject: [PATCH 03/15] added example: with-geist-ui (#36525) ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have helpful link attached, see `contributing.md` ## Documentation / Examples - [x] Make sure the linting passes by running `yarn lint` --- examples/with-geist-ui/.gitignore | 34 +++++++ examples/with-geist-ui/README.md | 21 +++++ examples/with-geist-ui/next-env.d.ts | 5 + examples/with-geist-ui/package.json | 22 +++++ examples/with-geist-ui/pages/_app.tsx | 12 +++ examples/with-geist-ui/pages/_document.js | 33 +++++++ examples/with-geist-ui/pages/index.tsx | 87 ++++++++++++++++++ .../with-geist-ui/public/geist-banner.png | Bin 0 -> 42007 bytes examples/with-geist-ui/tsconfig.json | 20 ++++ 9 files changed, 234 insertions(+) create mode 100644 examples/with-geist-ui/.gitignore create mode 100644 examples/with-geist-ui/README.md create mode 100644 examples/with-geist-ui/next-env.d.ts create mode 100644 examples/with-geist-ui/package.json create mode 100644 examples/with-geist-ui/pages/_app.tsx create mode 100644 examples/with-geist-ui/pages/_document.js create mode 100644 examples/with-geist-ui/pages/index.tsx create mode 100644 examples/with-geist-ui/public/geist-banner.png create mode 100644 examples/with-geist-ui/tsconfig.json diff --git a/examples/with-geist-ui/.gitignore b/examples/with-geist-ui/.gitignore new file mode 100644 index 000000000000..1437c53f70bc --- /dev/null +++ b/examples/with-geist-ui/.gitignore @@ -0,0 +1,34 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel diff --git a/examples/with-geist-ui/README.md b/examples/with-geist-ui/README.md new file mode 100644 index 000000000000..04f20dd2b634 --- /dev/null +++ b/examples/with-geist-ui/README.md @@ -0,0 +1,21 @@ +# Example app with [geist-ui](https://github.com/geist-org/geist-ui) and TypeScript + +This example features how to use [geist-ui](https://github.com/geist-org/geist-ui) as the component library within a Next.js app with TypeScript. + +## Deploy your own + +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-geist-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-geist-ui&project-name=with-geist-ui&repository-name=with-geist-ui) + +Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: + +```bash +npx create-next-app --example with-geist-ui with-geist-ui-app +# or +yarn create next-app --example with-geist-ui with-geist-ui-app +# or +pnpm create next-app -- --example with-geist-ui with-geist-ui-app +``` + +Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). diff --git a/examples/with-geist-ui/next-env.d.ts b/examples/with-geist-ui/next-env.d.ts new file mode 100644 index 000000000000..4f11a03dc6cc --- /dev/null +++ b/examples/with-geist-ui/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/examples/with-geist-ui/package.json b/examples/with-geist-ui/package.json new file mode 100644 index 000000000000..81de156c6e85 --- /dev/null +++ b/examples/with-geist-ui/package.json @@ -0,0 +1,22 @@ +{ + "private": true, + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "@geist-ui/core": "latest", + "@geist-ui/icons": "1.0.1", + "next": "latest", + "react": "^18.1.0", + "react-dom": "^18.1.0" + }, + "devDependencies": { + "@types/node": "^17.0.29", + "@types/react": "^18.0.8", + "eslint": "8.14.0", + "eslint-config-next": "12.1.5", + "typescript": "^4.5.4" + } +} diff --git a/examples/with-geist-ui/pages/_app.tsx b/examples/with-geist-ui/pages/_app.tsx new file mode 100644 index 000000000000..906b974c8092 --- /dev/null +++ b/examples/with-geist-ui/pages/_app.tsx @@ -0,0 +1,12 @@ +import type { AppProps } from 'next/app' +import { GeistProvider, CssBaseline } from '@geist-ui/core' + +function MyApp({ Component, pageProps }: AppProps) { + return ( + + + + + ) +} +export default MyApp diff --git a/examples/with-geist-ui/pages/_document.js b/examples/with-geist-ui/pages/_document.js new file mode 100644 index 000000000000..8ff3141143ca --- /dev/null +++ b/examples/with-geist-ui/pages/_document.js @@ -0,0 +1,33 @@ +import Document, { Html, Head, Main, NextScript } from 'next/document' +import { CssBaseline } from '@geist-ui/core' + +class MyDocument extends Document { + static async getInitialProps(ctx) { + const initialProps = await Document.getInitialProps(ctx) + const styles = CssBaseline.flush() + + return { + ...initialProps, + styles: ( + <> + {initialProps.styles} + {styles} + + ), + } + } + + render() { + return ( + + + +
+ + + + ) + } +} + +export default MyDocument diff --git a/examples/with-geist-ui/pages/index.tsx b/examples/with-geist-ui/pages/index.tsx new file mode 100644 index 000000000000..8808b14d3a9e --- /dev/null +++ b/examples/with-geist-ui/pages/index.tsx @@ -0,0 +1,87 @@ +import Head from 'next/head' +import { + Page, + Text, + Image, + Display, + Button, + Grid, + Spacer, +} from '@geist-ui/core' +import { Github } from '@geist-ui/icons' + +const gh = 'https://github.com/geist-org/geist-ui' +const docs = 'https://geist-ui.dev' + +export default function Home() { + const redirect = (url: string) => window.open(url) + + return ( +
+ + Geist UI with NextJS + + + + + Example repository of{' '} + + Next.js + {' '} + &{' '} + + + G + + + e + + + i + + + s + + + t + + + UI. + + {' '} + + } + > + geist ui banner + + + + + + + + + + + +
+ ) +} diff --git a/examples/with-geist-ui/public/geist-banner.png b/examples/with-geist-ui/public/geist-banner.png new file mode 100644 index 0000000000000000000000000000000000000000..cf7a3facab67176d386da3be3b505ffef90823ca GIT binary patch literal 42007 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 Date: Tue, 10 May 2022 11:57:14 -0500 Subject: [PATCH 04/15] Update root component handling (#36781) --- .../build/webpack/loaders/next-view-loader.ts | 28 +++++-- packages/next/server/view-render.tsx | 80 ++++++++++--------- .../dashboard/another/page.server.js | 7 ++ .../app/views/(newroot)/layout.server.js | 19 +++++ .../deployments/breakdown/page.server.js | 7 ++ .../views/dashboard/(custom)/layout.server.js | 8 ++ test/e2e/views-dir/app/views/layout.server.js | 12 ++- test/e2e/views-dir/index.test.ts | 55 +++++++++++-- 8 files changed, 166 insertions(+), 50 deletions(-) create mode 100644 test/e2e/views-dir/app/views/(newroot)/dashboard/another/page.server.js create mode 100644 test/e2e/views-dir/app/views/(newroot)/layout.server.js create mode 100644 test/e2e/views-dir/app/views/dashboard/(custom)/deployments/breakdown/page.server.js create mode 100644 test/e2e/views-dir/app/views/dashboard/(custom)/layout.server.js diff --git a/packages/next/build/webpack/loaders/next-view-loader.ts b/packages/next/build/webpack/loaders/next-view-loader.ts index 1f4ca331584f..4374b9ff3673 100644 --- a/packages/next/build/webpack/loaders/next-view-loader.ts +++ b/packages/next/build/webpack/loaders/next-view-loader.ts @@ -22,18 +22,34 @@ async function resolveLayoutPathsByPage({ }) { const layoutPaths = new Map() const parts = pagePath.split('/') + const isNewRootLayout = + parts[1]?.length > 2 && parts[1]?.startsWith('(') && parts[1]?.endsWith(')') - for (let i = 1; i < parts.length; i++) { + for (let i = parts.length; i >= 0; i--) { const pathWithoutSlashLayout = parts.slice(0, i).join('/') - const layoutPath = `${pathWithoutSlashLayout}/layout` - - const resolvedLayoutPath = await resolve(layoutPath) + if (!pathWithoutSlashLayout) { + continue + } + const layoutPath = `${pathWithoutSlashLayout}/layout` + let resolvedLayoutPath = await resolve(layoutPath) let urlPath = pathToUrlPath(pathWithoutSlashLayout) + // if we are in a new root views/(root) and a custom root layout was + // not provided or a root layout views/layout is not present, we use + // a default root layout to provide the html/body tags + const isCustomRootLayout = isNewRootLayout && i === 2 + + if ((isCustomRootLayout || i === 1) && !resolvedLayoutPath) { + resolvedLayoutPath = await resolve('next/dist/lib/views-layout') + } layoutPaths.set(urlPath, resolvedLayoutPath) - } + // if we're in a new root layout don't add the top-level view/layout + if (isCustomRootLayout) { + break + } + } return layoutPaths } @@ -84,7 +100,7 @@ const nextViewLoader: webpack.LoaderDefinitionFunction<{ // Add page itself to the list of components componentsCode.push( `'${pathToUrlPath(pagePath).replace( - new RegExp(`/page\\.+(${extensions.join('|')})$`), + new RegExp(`/page+(${extensions.join('|')})$`), '' // use require so that we can bust the require cache )}': () => require('${pagePath}')` diff --git a/packages/next/server/view-render.tsx b/packages/next/server/view-render.tsx index f304f2472ce6..8952c5f493aa 100644 --- a/packages/next/server/view-render.tsx +++ b/packages/next/server/view-render.tsx @@ -19,7 +19,6 @@ import { import { FlushEffectsContext } from '../shared/lib/flush-effects' import { isDynamicRoute } from '../shared/lib/router/utils' import { tryGetPreviewData } from './api-utils/node' -import DefaultRootLayout from '../lib/views-layout' const ReactDOMServer = process.env.__NEXT_REACT_ROOT ? require('react-dom/server.browser') @@ -218,10 +217,13 @@ export async function renderToHTML( const isFlight = query.__flight__ !== undefined const flightRouterPath = isFlight ? query.__flight_router_path__ : undefined + delete query.__flight__ + delete query.__flight_router_path__ const hasConcurrentFeatures = !!runtime const pageIsDynamic = isDynamicRoute(pathname) - const components = Object.keys(ComponentMod.components) + const componentPaths = Object.keys(ComponentMod.components) + const components = componentPaths .filter((path) => { // Rendering part of the page is only allowed for flight data if (flightRouterPath) { @@ -238,6 +240,8 @@ export async function renderToHTML( return mod }) + const isSubtreeRender = components.length < componentPaths.length + // Reads of this are cached on the `req` object, so this should resolve // instantly. There's no need to pass this data down from a previous // invoke, where we'd have to consider server & serverless. @@ -247,22 +251,12 @@ export async function renderToHTML( (renderOpts as any).previewProps ) const isPreview = previewData !== false - - let WrappedComponent: any - let RootLayout: any - const dataCache = new Map() + let WrappedComponent: any for (let i = components.length - 1; i >= 0; i--) { const dataCacheKey = i.toString() const layout = components[i] - - if (i === 0) { - // top-most layout is the root layout that renders - // the html/body tags - RootLayout = layout.Component - continue - } let fetcher: any // TODO: pass a shared cache from previous getStaticProps/ @@ -313,8 +307,7 @@ export async function renderToHTML( // eslint-disable-next-line no-loop-func const lastComponent = WrappedComponent - WrappedComponent = () => { - let props: any + WrappedComponent = (props: any) => { if (fetcher) { // The data fetching was kicked off before rendering (see above) // if the data was not resolved yet the layout rendering will be suspended @@ -325,7 +318,25 @@ export async function renderToHTML( ) // Result of calling getStaticProps or getServerSideProps. If promise is not resolve yet it will suspend. const recordValue = readRecordValue(record) - props = recordValue.props + + if (props) { + props = Object.assign({}, props, recordValue.props) + } else { + props = recordValue.props + } + } + + // if this is the root layout pass children as bodyChildren prop + if (!isSubtreeRender && i === 0) { + return React.createElement(layout.Component, { + ...props, + headChildren: props.headChildren, + bodyChildren: React.createElement( + lastComponent || React.Fragment, + {}, + null + ), + }) } return React.createElement( @@ -345,14 +356,11 @@ export async function renderToHTML( // } } - // Fall back to default root layout that renders / / - if (!RootLayout) { - RootLayout = DefaultRootLayout - } - - const headChildren = buildManifest.rootMainFiles.map((src) => ( -