diff --git a/.github/actions/issue-validator/index.js b/.github/actions/issue-validator/index.js index 97f62210ff31..3298578b5ba7 100644 --- a/.github/actions/issue-validator/index.js +++ b/.github/actions/issue-validator/index.js @@ -8700,20 +8700,23 @@ const r = 'template: bug' const s = 'please add a complete reproduction' const i = !!process.env.DEBUG + const json = (e) => JSON.stringify(e, null, 2) async function run() { try { - const { - payload: { issue: p, pull_request: d }, - repo: o, - } = e.context - if (d || !p?.body) return - const { body: n, labels: l, number: m } = p + const { payload: p, repo: d } = e.context + const { issue: o, pull_request: n } = p + if (n || !o?.body) return + const l = p.label + const { body: m, number: u } = o + const c = o.labels a.info( - `Validating issue ${m}:\n Label(s): ${l.join(', ')}\n Body: ${n}` + `Validating issue ${u}:\n Labels:\n New: ${json( + l + )}\n All: ${json(c)}\n Body: ${m}` ) - const u = l.some((e) => e.name === r) - const c = l.some((e) => e.name === t) - if (!u || !c) { + const v = l.name === r + const h = c.some((e) => e.name === t) + if (!v && !h) { return a.info( 'Issue is ignored, because it is not a bug report or is not manually labeled' ) @@ -8721,68 +8724,68 @@ if (!process.env.GITHUB_TOKEN) { throw new Error('GITHUB_TOKEN is not set') } - const v = e.getOctokit(process.env.GITHUB_TOKEN).rest + const g = e.getOctokit(process.env.GITHUB_TOKEN).rest function notifyOnIssue(e, p) { - const d = { ...o, issue_number: m } + const t = { ...d, issue_number: u } if (i) { a.info('Skipping comment/label because we are in DEBUG mode') - a.info(JSON.stringify({ label: e, comment: p }, null, 2)) + a.info(json({ label: e, comment: p })) return } return Promise.all([ - v.issues.addLabels({ ...d, labels: [e] }), - v.issues.createComment({ ...d, body: p }), + g.issues.addLabels({ ...t, labels: [e] }), + g.issues.createComment({ ...t, body: p }), ]) } - const h = n.includes( + const w = m.includes( '- [X] I verified that the issue exists in Next.js canary release' ) - if (!h || c) { + if (!w || h) { await notifyOnIssue( t, 'Please verify your issue reproduces with `next@canary`. The canary version of Next.js ships daily and includes all features and fixes that have not been released to the stable version yet. Think of canary as a public beta. Some issues may already be fixed in the canary version, so please verify that your issue reproduces by running `npm install next@canary`. If the issue does not reproduce with the canary version, then it has already been fixed and this issue can be closed.' ) return a.info( `Commented on issue, because it was ${ - c ? 'manually labeled' : 'not verified against canary' + h ? 'manually labeled' : 'not verified against canary' }` ) } - const g = n + const _ = m .match(/### Link to reproduction\n\n(?.*)\n/) ?.groups?.url.trim() - if (!g || !(await fetch(g)).ok) { + if (!_ || !(await fetch(_)).ok) { await notifyOnIssue( s, 'The link to the reproduction appears to be incorrect/unreachable. Please add a link to the reproduction of the issue. This is a required field. If your project is private, you can invite @balazsorban44 to the repository so the Next.js team can investigate further.' ) return a.info( - `Commented on issue, because the reproduction url (${g}) was not reachable` + `Commented on issue, because the reproduction url (${_}) was not reachable` ) } - const w = [ + const T = [ 'Operating System:', 'Binaries:', 'Relevant packages:', - ].every((e) => n.includes(e)) - if (!w) { + ].every((e) => m.includes(e)) + if (!T) { return a.info( 'Could not detect `next info` output, skipping as version detection might be unreliable' ) } - const _ = n.match( + const E = m.match( /Relevant packages:\n next: (?\d+\.\d+\.\d+)/ )?.groups?.version - a.info(`Reported Next.js version: ${_}`) - if (!_) { + a.info(`Reported Next.js version: ${E}`) + if (!E) { return } - const { tag_name: T } = await (await v.repos.listReleases(o)).data[0] - a.info(`Last Next.js version, based on GitHub releases: ${T}`) - if (T.includes('canary') && _ !== T) { + const { tag_name: b } = await (await g.repos.listReleases(d)).data[0] + a.info(`Last Next.js version, based on GitHub releases: ${b}`) + if (b.includes('canary') && E !== b) { await notifyOnIssue( t, - `The reported Next.js version did not match the latest \`next@canary\` version (${T}). The canary version of Next.js ships daily and includes all features and fixes that have not been released to the stable version yet. Think of canary as a public beta. Some issues may already be fixed in the canary version, so please verify that your issue reproduces by running \`npm install next@canary\`. If the issue does not reproduce with the canary version, then it has already been fixed and this issue can be closed.` + `The reported Next.js version did not match the latest \`next@canary\` version (${b}). The canary version of Next.js ships daily and includes all features and fixes that have not been released to the stable version yet. Think of canary as a public beta. Some issues may already be fixed in the canary version, so please verify that your issue reproduces by running \`npm install next@canary\`. If the issue does not reproduce with the canary version, then it has already been fixed and this issue can be closed.` ) return a.info( `Commented on issue, because it was not verified against canary` diff --git a/.github/actions/issue-validator/src/index.js b/.github/actions/issue-validator/src/index.js index 2d1608295afc..8d3cc90435a3 100644 --- a/.github/actions/issue-validator/src/index.js +++ b/.github/actions/issue-validator/src/index.js @@ -6,31 +6,48 @@ const verifyCanaryLabel = 'please verify canary' const bugReportLabel = 'template: bug' const addReproductionLabel = 'please add a complete reproduction' const debug = !!process.env.DEBUG +const json = (o) => JSON.stringify(o, null, 2) + +/** + * @typedef {{ + * id :number + * node_id :string + * url :string + * name :string + * description :string + * color :string + * default :boolean + * }} Label + */ async function run() { try { - const { - payload: { issue, pull_request }, - repo, - } = github.context + const { payload, repo } = github.context + const { issue, pull_request } = payload if (pull_request || !issue?.body) return - const { body, labels, number: issueNumber } = issue + /** @type {Label} */ + const newLabel = payload.label + const { body, number: issueNumber } = issue + /** @type {Label[]} */ + const labels = issue.labels core.info( `Validating issue ${issueNumber}: - Label(s): ${labels.join(', ')} + Labels: + New: ${json(newLabel)} + All: ${json(labels)} Body: ${body}` ) - const isBugReport = labels.some((label) => label.name === bugReportLabel) + const isBugReport = newLabel.name === bugReportLabel const isManuallyLabeled = labels.some( (label) => label.name === verifyCanaryLabel ) - if (!isBugReport || !isManuallyLabeled) { + if (!isBugReport && !isManuallyLabeled) { return core.info( 'Issue is ignored, because it is not a bug report or is not manually labeled' ) @@ -51,7 +68,7 @@ async function run() { if (debug) { core.info('Skipping comment/label because we are in DEBUG mode') - core.info(JSON.stringify({ label, comment }, null, 2)) + core.info(json({ label, comment })) return } diff --git a/docs/going-to-production.md b/docs/going-to-production.md index 94bf7d3b6941..a68edd3ff53f 100644 --- a/docs/going-to-production.md +++ b/docs/going-to-production.md @@ -91,6 +91,7 @@ To reduce the amount of JavaScript sent to the browser, you can use the followin - [Package Phobia](https://packagephobia.com/) – Find the cost of adding a new dev dependency to your project. - [Bundle Phobia](https://bundlephobia.com/) - Analyze how much a dependency can increase bundle sizes. - [Webpack Bundle Analyzer](https://github.com/vercel/next.js/tree/canary/packages/next-bundle-analyzer) – Visualize size of webpack output files with an interactive, zoomable treemap. +- [bundlejs](https://bundlejs.com/) - An online tool to quickly bundle & minify your projects, while viewing the compressed gzip/brotli bundle size, all running locally on your browser. Each file inside your `pages/` directory will automatically be code split into its own JavaScript bundle during `next build`. You can also use [Dynamic Imports](/docs/advanced-features/dynamic-import.md) to lazy-load components and libraries. For example, you might want to defer loading your modal code until a user clicks the open button. diff --git a/lerna.json b/lerna.json index e61a1b808026..dccccf4d40fd 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "12.2.3-canary.8" + "version": "12.2.3-canary.11" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 508abf8d7cf4..2dceb2285b76 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.2.3-canary.8", + "version": "12.2.3-canary.11", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index e44d550ce164..2a0c9aa7dc33 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.2.3-canary.8", + "version": "12.2.3-canary.11", "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.2.3-canary.8", + "@next/eslint-plugin-next": "12.2.3-canary.11", "@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/package.json b/packages/eslint-plugin-next/package.json index b8355262eedc..5fe7fc8b78a5 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.2.3-canary.8", + "version": "12.2.3-canary.11", "description": "ESLint plugin for NextJS.", "main": "lib/index.js", "license": "MIT", diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 2a8daa001253..3bc61f85c433 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.2.3-canary.8", + "version": "12.2.3-canary.11", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index aa4719ff7dd7..bd68e65c7f00 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "12.2.3-canary.8", + "version": "12.2.3-canary.11", "license": "MIT", "dependencies": { "chalk": "4.1.0", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 110f08555817..98ac16f7627a 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "12.2.3-canary.8", + "version": "12.2.3-canary.11", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index d33b6db68fb3..30256a9062e5 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "12.2.3-canary.8", + "version": "12.2.3-canary.11", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index b188f940632b..3a4ea30c115e 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.2.3-canary.8", + "version": "12.2.3-canary.11", "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 9c5b6f0fef62..ad0ee0f3e34f 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.2.3-canary.8", + "version": "12.2.3-canary.11", "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 db3bad246acb..99941109ee10 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.2.3-canary.8", + "version": "12.2.3-canary.11", "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 65734209702e..650d6b445da8 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "12.2.3-canary.8", + "version": "12.2.3-canary.11", "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/loaders/next-app-loader.ts b/packages/next/build/webpack/loaders/next-app-loader.ts index 3b8833630c5a..6d9f6d790009 100644 --- a/packages/next/build/webpack/loaders/next-app-loader.ts +++ b/packages/next/build/webpack/loaders/next-app-loader.ts @@ -16,12 +16,6 @@ async function createTreeCodeFromPath({ const appDirPrefix = splittedPath[0] const segments = ['', ...splittedPath.slice(1)] - const isNewRootLayout = - segments[0]?.length > 2 && - segments[0]?.startsWith('(') && - segments[0]?.endsWith(')') - - let isCustomRootLayout = false // segment.length - 1 because arrays start at 0 and we're decrementing for (let i = segments.length - 1; i >= 0; i--) { @@ -43,11 +37,6 @@ async function createTreeCodeFromPath({ const resolvedLayoutPath = await resolve(layoutPath) const resolvedLoadingPath = await resolve(loadingPath) - // if we are in a new root app/(root) and a custom root layout was - // not provided or a root layout app/layout is not present, we use - // a default root layout to provide the html/body tags - isCustomRootLayout = isNewRootLayout && i === 1 - // Existing tree are the children of the current segment const children = tree @@ -68,11 +57,6 @@ async function createTreeCodeFromPath({ : '' } }]` - - // if we're in a new root layout don't add the top-level app/layout - if (isCustomRootLayout) { - break - } } return `const tree = ${tree};` diff --git a/packages/next/client/components/layout-router.client.tsx b/packages/next/client/components/layout-router.client.tsx index ca1de4594d5a..3a3cc6ed1495 100644 --- a/packages/next/client/components/layout-router.client.tsx +++ b/packages/next/client/components/layout-router.client.tsx @@ -42,6 +42,11 @@ function createInfinitePromise() { return infinitePromise } +function topOfElementInViewport(element: HTMLElement) { + const rect = element.getBoundingClientRect() + return rect.top >= 0 +} + export function InnerLayoutRouter({ parallelRouterKey, url, @@ -72,7 +77,10 @@ export function InnerLayoutRouter({ if (focusRef.focus && focusAndScrollRef.current) { focusRef.focus = false focusAndScrollRef.current.focus() - focusAndScrollRef.current.scrollIntoView() + // Only scroll into viewport when the layout is not visible currently. + if (!topOfElementInViewport(focusAndScrollRef.current)) { + focusAndScrollRef.current.scrollIntoView() + } } }, [focusRef]) diff --git a/packages/next/client/components/reducer.ts b/packages/next/client/components/reducer.ts index abb2b82c3607..2767862c24b5 100644 --- a/packages/next/client/components/reducer.ts +++ b/packages/next/client/components/reducer.ts @@ -154,27 +154,28 @@ const canOptimisticallyRender = ( ): boolean => { const segment = segments[0] const isLastSegment = segments.length === 1 - const [existingSegment, existingParallelRoutes, , , loadingMarker] = flightRouterState + // If the segments mismatch we can't resolve deeper into the tree + const segmentMatches = matchSegment(existingSegment, segment) - const hasLoading = loadingMarker === 'loading' + // If the segment mismatches we can't assume this level has loading + if (!segmentMatches) { + return false + } + const hasLoading = loadingMarker === 'loading' // If the tree path holds at least one loading.js it will be optimistic if (hasLoading) { return true } - // Above already catches the last segment case where `hasLoading` is true, so in this case it would always be `false`. if (isLastSegment) { return false } - // If the segments mismatch we can't resolve deeper into the tree - const segmentMatches = matchSegment(existingSegment, segment) - // If the existingParallelRoutes does not have a `children` parallelRouteKey we can't resolve deeper into the tree - if (!segmentMatches || !existingParallelRoutes.children) { + if (!existingParallelRoutes.children) { return hasLoading } @@ -188,9 +189,9 @@ const canOptimisticallyRender = ( const createOptimisticTree = ( segments: string[], flightRouterState: FlightRouterState | null, - isFirstSegment: boolean, + _isFirstSegment: boolean, parentRefetch: boolean, - href?: string + _href?: string ): FlightRouterState => { const [existingSegment, existingParallelRoutes] = flightRouterState || [ null, @@ -232,10 +233,11 @@ const createOptimisticTree = ( result[3] = 'refetch' } + // TODO-APP: Revisit // Add url into the tree - if (isFirstSegment) { - result[2] = href - } + // if (isFirstSegment) { + // result[2] = href + // } // Copy the loading flag from existing tree if (flightRouterState && flightRouterState[4]) { @@ -250,15 +252,16 @@ const walkTreeWithFlightDataPath = ( flightRouterState: FlightRouterState, treePatch: FlightRouterState ): FlightRouterState => { - const [segment, parallelRoutes, url] = flightRouterState + const [segment, parallelRoutes /* , url */] = flightRouterState // Root refresh if (flightSegmentPath.length === 1) { const tree: FlightRouterState = [...treePatch] - if (url) { - tree[2] = url - } + // TODO-APP: revisit + // if (url) { + // tree[2] = url + // } return tree } @@ -286,13 +289,14 @@ const walkTreeWithFlightDataPath = ( }, ] - if (url) { - tree[2] = url - } + // TODO-APP: Revisit + // if (url) { + // tree[2] = url + // } // Copy loading flag - if (flightSegmentPath[4]) { - tree[4] = flightSegmentPath[4] + if (flightRouterState[4]) { + tree[4] = flightRouterState[4] } return tree diff --git a/packages/next/package.json b/packages/next/package.json index b00942ff6a75..30bd0ef18325 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "12.2.3-canary.8", + "version": "12.2.3-canary.11", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -72,7 +72,7 @@ ] }, "dependencies": { - "@next/env": "12.2.3-canary.8", + "@next/env": "12.2.3-canary.11", "@swc/helpers": "0.4.3", "caniuse-lite": "^1.0.30001332", "postcss": "8.4.14", @@ -123,11 +123,11 @@ "@hapi/accept": "5.0.2", "@napi-rs/cli": "2.4.4", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "12.2.3-canary.8", - "@next/polyfill-nomodule": "12.2.3-canary.8", - "@next/react-dev-overlay": "12.2.3-canary.8", - "@next/react-refresh-utils": "12.2.3-canary.8", - "@next/swc": "12.2.3-canary.8", + "@next/polyfill-module": "12.2.3-canary.11", + "@next/polyfill-nomodule": "12.2.3-canary.11", + "@next/react-dev-overlay": "12.2.3-canary.11", + "@next/react-refresh-utils": "12.2.3-canary.11", + "@next/swc": "12.2.3-canary.11", "@taskr/clear": "1.1.0", "@taskr/esnext": "1.1.0", "@taskr/watch": "1.1.0", diff --git a/packages/next/server/app-render.tsx b/packages/next/server/app-render.tsx index a27550af9f4f..1e4f6be28f39 100644 --- a/packages/next/server/app-render.tsx +++ b/packages/next/server/app-render.tsx @@ -651,7 +651,18 @@ export async function renderToHTML( } type getServerSidePropsContextPage = GetServerSidePropsContext & { - query: URLSearchParams + searchParams: URLSearchParams + pathname: string + } + + type GetStaticPropsContext = { + layoutSegments: FlightSegmentPath + params?: { [key: string]: string | string[] } + preview?: boolean + previewData?: string | object | undefined + } + + type GetStaticPropContextPage = GetStaticPropsContext & { pathname: string } @@ -668,7 +679,7 @@ export async function renderToHTML( cookies, layoutSegments: segmentPath, // TODO-APP: change pathname to actual pathname, it holds the dynamic parameter currently - ...(isPage ? { query, pathname } : {}), + ...(isPage ? { searchParams: query, pathname } : {}), ...(pageIsDynamic ? { params: currentParams } : undefined), ...(isPreview ? { preview: true, previewData: previewData } @@ -681,7 +692,9 @@ export async function renderToHTML( } // TODO-APP: implement layout specific caching for getStaticProps if (layoutOrPageMod.getStaticProps) { - const getStaticPropsContext = { + const getStaticPropsContext: + | GetStaticPropsContext + | GetStaticPropContextPage = { layoutSegments: segmentPath, ...(isPage ? { pathname } : {}), ...(pageIsDynamic ? { params: currentParams } : undefined), @@ -729,7 +742,7 @@ export async function renderToHTML( // If you have a `/dashboard/[team]/layout.js` it will provide `team` as a param but not anything further down. params={currentParams} // Query is only provided to page - {...(isPage ? { query } : {})} + {...(isPage ? { searchParams: query } : {})} /> ) }, diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 98d5bbafeab4..1135f4ea463d 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "12.2.3-canary.8", + "version": "12.2.3-canary.11", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index f868399521c9..156ee419b8b3 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": "12.2.3-canary.8", + "version": "12.2.3-canary.11", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5f126498ba41..8095fcd66cda 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -364,7 +364,7 @@ importers: packages/eslint-config-next: specifiers: - '@next/eslint-plugin-next': 12.2.3-canary.8 + '@next/eslint-plugin-next': 12.2.3-canary.11 '@rushstack/eslint-patch': ^1.1.3 '@typescript-eslint/parser': ^5.21.0 eslint-import-resolver-node: ^0.3.6 @@ -420,12 +420,12 @@ importers: '@hapi/accept': 5.0.2 '@napi-rs/cli': 2.4.4 '@napi-rs/triples': 1.1.0 - '@next/env': 12.2.3-canary.8 - '@next/polyfill-module': 12.2.3-canary.8 - '@next/polyfill-nomodule': 12.2.3-canary.8 - '@next/react-dev-overlay': 12.2.3-canary.8 - '@next/react-refresh-utils': 12.2.3-canary.8 - '@next/swc': 12.2.3-canary.8 + '@next/env': 12.2.3-canary.11 + '@next/polyfill-module': 12.2.3-canary.11 + '@next/polyfill-nomodule': 12.2.3-canary.11 + '@next/react-dev-overlay': 12.2.3-canary.11 + '@next/react-refresh-utils': 12.2.3-canary.11 + '@next/swc': 12.2.3-canary.11 '@swc/helpers': 0.4.3 '@taskr/clear': 1.1.0 '@taskr/esnext': 1.1.0 diff --git a/test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js b/test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js index cb2b99034594..b564508deb0c 100644 --- a/test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js +++ b/test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js @@ -1,7 +1,11 @@ -export default function Page({ params, query }) { +export default function Page({ params, searchParams }) { return ( -

- hello from /param-and-query/{params.slug}?slug={query.slug} +

+ hello from /param-and-query/{params.slug}?slug={searchParams.slug}

) } diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index 757d5e6a10b2..90ebe52e76bc 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -6,6 +6,8 @@ import cheerio from 'cheerio' import webdriver from 'next-webdriver' describe('app dir', () => { + const isDev = (global as any).isNextDev + if ((global as any).isNextDeploy) { it('should skip next deploy for now', () => {}) return @@ -211,33 +213,38 @@ describe('app dir', () => { expect(html).toContain('hello from app/dashboard') }) - it('should not rerender layout when navigating between routes in the same layout', async () => { - const browser = await webdriver(next.url, '/same-layout/first') + // TODO-APP: Enable in development + ;(isDev ? it.skip : it)( + 'should not rerender layout when navigating between routes in the same layout', + async () => { + const browser = await webdriver(next.url, '/same-layout/first') - try { - // Get the render id from the dom and click the first link. - const firstRenderID = await browser.elementById('render-id').text() - await browser.elementById('link').click() - await browser.waitForElementByCss('#second-page') + try { + // Get the render id from the dom and click the first link. + const firstRenderID = await browser.elementById('render-id').text() + await browser.elementById('link').click() + await browser.waitForElementByCss('#second-page') - // Get the render id from the dom again, it should be the same! - const secondRenderID = await browser.elementById('render-id').text() - expect(secondRenderID).toBe(firstRenderID) + // Get the render id from the dom again, it should be the same! + const secondRenderID = await browser.elementById('render-id').text() + expect(secondRenderID).toBe(firstRenderID) - // Navigate back to the first page again by clicking the link. - await browser.elementById('link').click() - await browser.waitForElementByCss('#first-page') + // Navigate back to the first page again by clicking the link. + await browser.elementById('link').click() + await browser.waitForElementByCss('#first-page') - // Get the render id from the dom again, it should be the same! - const thirdRenderID = await browser.elementById('render-id').text() - expect(thirdRenderID).toBe(firstRenderID) - } finally { - await browser.close() + // Get the render id from the dom again, it should be the same! + const thirdRenderID = await browser.elementById('render-id').text() + expect(thirdRenderID).toBe(firstRenderID) + } finally { + await browser.close() + } } - }) + ) describe('', () => { - it('should hard push', async () => { + // TODO-APP: fix development test + it.skip('should hard push', async () => { const browser = await webdriver(next.url, '/link-hard-push') try { @@ -264,7 +271,8 @@ describe('app dir', () => { } }) - it('should hard replace', async () => { + // TODO-APP: fix development test + it.skip('should hard replace', async () => { const browser = await webdriver(next.url, '/link-hard-replace') try { @@ -954,7 +962,11 @@ describe('app dir', () => { '/client-with-errors/get-static-props' ) expect(res.status).toBe(500) - expect(await res.text()).toContain('Internal Server Error') + expect(await res.text()).toContain( + isDev + ? 'getStaticProps is not supported on Client Components' + : 'Internal Server Error' + ) }) it('should throw an error when getServerSideProps is used', async () => { @@ -963,7 +975,11 @@ describe('app dir', () => { '/client-with-errors/get-server-side-props' ) expect(res.status).toBe(500) - expect(await res.text()).toContain('Internal Server Error') + expect(await res.text()).toContain( + isDev + ? 'getServerSideProps is not supported on Client Components' + : 'Internal Server Error' + ) }) }) diff --git a/test/e2e/app-dir/rendering.test.ts b/test/e2e/app-dir/rendering.test.ts index ed4565dc0518..10ec1b72df4f 100644 --- a/test/e2e/app-dir/rendering.test.ts +++ b/test/e2e/app-dir/rendering.test.ts @@ -15,7 +15,7 @@ describe('app dir rendering', () => { return } - const isDev = (global as any).isDev + const isDev = (global as any).isNextDev let next: NextInstance beforeAll(async () => { diff --git a/test/e2e/app-dir/rsc-basic/app/next-api/link/page.server.js b/test/e2e/app-dir/rsc-basic/app/next-api/link/page.server.js index 60b98b5c8122..280b98b735bb 100644 --- a/test/e2e/app-dir/rsc-basic/app/next-api/link/page.server.js +++ b/test/e2e/app-dir/rsc-basic/app/next-api/link/page.server.js @@ -18,10 +18,10 @@ export default function LinkPage({ queryId }) { export function getServerSideProps(ctx) { // FIXME: query is missing - const { query } = ctx + const { searchParams } = ctx return { props: { - queryId: query.id || '0', + queryId: searchParams.id || '0', }, } }