From c6ba688c404f9961ca3e3514dce79b0d06973244 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 9 Aug 2021 16:13:50 +0200 Subject: [PATCH 01/11] disable cache compression as it slows down the build (#27887) --- packages/next/build/webpack-config.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index 570684bb34baeff..873cd9b728b65d0 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -1446,6 +1446,8 @@ export default async function getBaseWebpackConfig( // - next.config.js keys that affect compilation version: `${process.env.__NEXT_VERSION}|${configVars}`, cacheDirectory: path.join(distDir, 'cache', 'webpack'), + // we assume that the CI already uses cache compression + compression: false, } // Adds `next.config.js` as a buildDependency when custom webpack config is provided From b60c943750ff63b086f6adaf20daac3aa6e23573 Mon Sep 17 00:00:00 2001 From: Nick Kelly Date: Mon, 9 Aug 2021 08:28:00 -0700 Subject: [PATCH 02/11] Remove extraneous fs.stat calls (#27779) ## Performance improvement - [x] Performance improvement Uses `fs.readdir`'s `withFileTypes` option, added in NodeJS version 10, to simultaneously read the target directories files and their stats, removing the need to call `fs.stat` on each of the files individually. Similar to #27769, applies the same change to `recursiveCopy` and `recursiveDelete`. --- packages/next/lib/recursive-copy.ts | 33 ++++++++++++++++++++------ packages/next/lib/recursive-delete.ts | 24 ++++++++++--------- packages/next/lib/recursive-readdir.ts | 10 +++++++- 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/packages/next/lib/recursive-copy.ts b/packages/next/lib/recursive-copy.ts index 9b3536b6077e59b..5d5d75183471a3b 100644 --- a/packages/next/lib/recursive-copy.ts +++ b/packages/next/lib/recursive-copy.ts @@ -1,5 +1,5 @@ import path from 'path' -import { promises, constants } from 'fs' +import { promises, constants, Dirent, Stats } from 'fs' import { Sema } from 'next/dist/compiled/async-sema' const COPYFILE_EXCL = constants.COPYFILE_EXCL @@ -23,13 +23,28 @@ export async function recursiveCopy( const sema = new Sema(concurrency) - async function _copy(item: string): Promise { + // deep copy the file/directory + async function _copy(item: string, lstats?: Stats | Dirent): Promise { const target = item.replace(from, to) - const stats = await promises.stat(item) await sema.acquire() - if (stats.isDirectory()) { + if (!lstats) { + // after lock on first run + lstats = await promises.lstat(from) + } + + // readdir & lstat do not follow symbolic links + // if part is a symbolic link, follow it with stat + let isFile = lstats.isFile() + let isDirectory = lstats.isDirectory() + if (lstats.isSymbolicLink()) { + const stats = await promises.stat(item) + isFile = stats.isFile() + isDirectory = stats.isDirectory() + } + + if (isDirectory) { try { await promises.mkdir(target) } catch (err) { @@ -39,10 +54,12 @@ export async function recursiveCopy( } } sema.release() - const files = await promises.readdir(item) - await Promise.all(files.map((file) => _copy(path.join(item, file)))) + const files = await promises.readdir(item, { withFileTypes: true }) + await Promise.all( + files.map((file) => _copy(path.join(item, file.name), file)) + ) } else if ( - stats.isFile() && + isFile && // before we send the path to filter // we remove the base path (from) and replace \ by / (windows) filter(item.replace(from, '').replace(/\\/g, '/')) @@ -53,6 +70,8 @@ export async function recursiveCopy( overwrite ? undefined : COPYFILE_EXCL ) sema.release() + } else { + sema.release() } } diff --git a/packages/next/lib/recursive-delete.ts b/packages/next/lib/recursive-delete.ts index 46d108922b53e0c..f73759525795143 100644 --- a/packages/next/lib/recursive-delete.ts +++ b/packages/next/lib/recursive-delete.ts @@ -1,4 +1,4 @@ -import { promises } from 'fs' +import { Dirent, promises } from 'fs' import { join } from 'path' import { promisify } from 'util' @@ -41,7 +41,7 @@ export async function recursiveDelete( ): Promise { let result try { - result = await promises.readdir(dir) + result = await promises.readdir(dir, { withFileTypes: true }) } catch (e) { if (e.code === 'ENOENT') { return @@ -50,17 +50,19 @@ export async function recursiveDelete( } await Promise.all( - result.map(async (part: string) => { - const absolutePath = join(dir, part) - const pathStat = await promises.stat(absolutePath).catch((e) => { - if (e.code !== 'ENOENT') throw e - }) - if (!pathStat) { - return + result.map(async (part: Dirent) => { + const absolutePath = join(dir, part.name) + + // readdir does not follow symbolic links + // if part is a symbolic link, follow it using stat + let isDirectory = part.isDirectory() + if (part.isSymbolicLink()) { + const stats = await promises.stat(absolutePath) + isDirectory = stats.isDirectory() } - const pp = join(previousPath, part) - if (pathStat.isDirectory() && (!exclude || !exclude.test(pp))) { + const pp = join(previousPath, part.name) + if (isDirectory && (!exclude || !exclude.test(pp))) { await recursiveDelete(absolutePath, exclude, pp) return promises.rmdir(absolutePath) } diff --git a/packages/next/lib/recursive-readdir.ts b/packages/next/lib/recursive-readdir.ts index f606f704114f785..5a2eb32120dcc98 100644 --- a/packages/next/lib/recursive-readdir.ts +++ b/packages/next/lib/recursive-readdir.ts @@ -23,7 +23,15 @@ export async function recursiveReadDir( const absolutePath = join(dir, part.name) if (ignore && ignore.test(part.name)) return - if (part.isDirectory()) { + // readdir does not follow symbolic links + // if part is a symbolic link, follow it using stat + let isDirectory = part.isDirectory() + if (part.isSymbolicLink()) { + const stats = await promises.stat(absolutePath) + isDirectory = stats.isDirectory() + } + + if (isDirectory) { await recursiveReadDir(absolutePath, filter, ignore, arr, rootDir) return } From c9ff4c798921645692d997c5ba61ce84cb076281 Mon Sep 17 00:00:00 2001 From: "C. Lewis" <1657236+ctjlewis@users.noreply.github.com> Date: Mon, 9 Aug 2021 11:21:16 -0500 Subject: [PATCH 03/11] feat(package.json): add contributor-friendly lifecycle scripts (#27825) ## Feature I was struggling to get my local dev build working as a local package.json override, and types do not seem to be generated by `yarn dev`, so I had to figure out a cohesive way to build the project start-to-finish (and also clean the project). Building the project and all types ended up just being `yarn prepublish`, here aliased as `yarn build`, and I added a `yarn clean` script. These two together should make it very difficult for any contributor to be confused how to generate a final build including all type declarations. - [ ] 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 - [x] 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 https://github.com/ctjlewis/next.js/blob/b2a888c14405d7978dc612fc4c66db208038736f/contributing.md#building --- contributing.md | 15 ++++++++++++++- package.json | 2 ++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/contributing.md b/contributing.md index 9bc7f5c57f1f4a6..bd3bbfc5ca46b92 100644 --- a/contributing.md +++ b/contributing.md @@ -12,7 +12,20 @@ Read about our [Commitment to Open Source](https://vercel.com/oss). > You may need to run `yarn types` again if your types get outdated. -To contribute to [our examples](examples), take a look at the [“Adding examples” section](#adding-examples). +To contribute to [our examples](examples), take a look at the [“Adding examples” +section](#adding-examples). + +## Building + +You can build the project, including all type definitions, with: + +```bash +yarn build +# - or - +yarn prepublish +``` + +If you need to clean the project for any reason, use `yarn clean`. ## Adding warning/error descriptions diff --git a/package.json b/package.json index b7956f57574a78c..912463d8f1c5398 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,8 @@ "packages/*" ], "scripts": { + "clean": "yarn lerna clean -y && yarn lerna bootstrap && yarn lerna exec 'rm -rf ./dist'", + "build": "yarn prepublish", "lerna": "lerna", "dev": "lerna run dev --stream --parallel", "dev2": "while true; do yarn --check-files && yarn dev; done", From 1969124d07c9f1ff1c03e0eaabd419413b03a3c5 Mon Sep 17 00:00:00 2001 From: stefanprobst Date: Mon, 9 Aug 2021 19:13:30 +0200 Subject: [PATCH 04/11] Add type annotation for NextConfig to CNA typescript template (#27872) This adds a type annotation for the `NextConfig` type to `next.config.js` in the `create-next-app` typescript template. ## 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 - [ ] Make sure the linting passes --- packages/create-next-app/templates/typescript/next.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/create-next-app/templates/typescript/next.config.js b/packages/create-next-app/templates/typescript/next.config.js index 0d6071006ab351f..8b61df4e50f8a8a 100644 --- a/packages/create-next-app/templates/typescript/next.config.js +++ b/packages/create-next-app/templates/typescript/next.config.js @@ -1,3 +1,4 @@ +/** @type {import('next').NextConfig} */ module.exports = { reactStrictMode: true, } From 9d3e895124fcadfef57dc253d887bce4aa604ae9 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Tue, 10 Aug 2021 01:57:11 +0800 Subject: [PATCH 05/11] Upgrade styled-jsx to v4 (#27890) Upgrade styled-jsx to v4 for supporting concurrent mode in react 18 ## 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 - [ ] Make sure the linting passes --- packages/next/package.json | 2 +- yarn.lock | 36 ++++++++++++++++++++---------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/packages/next/package.json b/packages/next/package.json index 34f3dd5c33f7025..eac16043299154f 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -106,7 +106,7 @@ "stream-browserify": "3.0.0", "stream-http": "3.1.1", "string_decoder": "1.3.0", - "styled-jsx": "3.4.7", + "styled-jsx": "4.0.0", "timers-browserify": "2.0.12", "tty-browserify": "0.0.1", "use-subscription": "1.5.1", diff --git a/yarn.lock b/yarn.lock index b0137fd62a9464a..3b5433efe116ca8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -551,6 +551,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8" integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg== +"@babel/helper-validator-identifier@^7.14.9": + version "7.14.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48" + integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g== + "@babel/helper-validator-option@^7.12.1", "@babel/helper-validator-option@^7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz#d66cb8b7a3e7fe4c6962b32020a131ecf0847f4f" @@ -958,7 +963,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-jsx@^7.14.5": +"@babel/plugin-syntax-jsx@7.14.5", "@babel/plugin-syntax-jsx@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz#000e2e25d8673cce49300517a3eda44c263e4201" integrity sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw== @@ -1974,13 +1979,12 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" -"@babel/types@7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" - integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg== +"@babel/types@7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd" + integrity sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ== dependencies: - esutils "^2.0.2" - lodash "^4.17.13" + "@babel/helper-validator-identifier" "^7.14.9" to-fast-properties "^2.0.0" "@babel/types@^7.12.13", "@babel/types@^7.13.0": @@ -5724,7 +5728,7 @@ babel-plugin-polyfill-regenerator@^0.2.2: babel-plugin-syntax-jsx "^6.18.0" lodash "^4.17.11" -babel-plugin-syntax-jsx@6.18.0, babel-plugin-syntax-jsx@^6.18.0: +babel-plugin-syntax-jsx@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" @@ -6321,7 +6325,7 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@1.0.30001228, caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001020, caniuse-lite@^1.0.30001093, caniuse-lite@^1.0.30001165, caniuse-lite@^1.0.30001202, caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001228: +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001020, caniuse-lite@^1.0.30001093, caniuse-lite@^1.0.30001165, caniuse-lite@^1.0.30001202, caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001228: version "1.0.30001228" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa" integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A== @@ -12573,7 +12577,7 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@~4.17.10: +lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@~4.17.10: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== @@ -18155,13 +18159,13 @@ styled-jsx-plugin-postcss@3.0.2: postcss "^7.0.2" postcss-load-plugins "^2.3.0" -styled-jsx@3.4.7: - version "3.4.7" - resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-3.4.7.tgz#803bc8a36f1c359cc99691b6db6e0791ea3e1e31" - integrity sha512-PkImcCsovR39byv4Tz83tAPsYs2CiTPOmDSplhe0lsIFVYJyd7rzJ7fbm41vSNsF/lnO+Ob5n/jgMookwY0pww== +styled-jsx@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-4.0.0.tgz#f7b90e7889d0a4f4635f8d1ae9ac32f3acaedc57" + integrity sha512-2USeoWMoJ/Lx5s2y1PxuvLy/cz2Yrr8cTySV3ILHU1Vmaw1bnV7suKdblLPjnyhMD+qzN7B1SWyh4UZTARn/WA== dependencies: - "@babel/types" "7.8.3" - babel-plugin-syntax-jsx "6.18.0" + "@babel/plugin-syntax-jsx" "7.14.5" + "@babel/types" "7.15.0" convert-source-map "1.7.0" loader-utils "1.2.3" source-map "0.7.3" From 6a32d854fcbb8bb513371db0584375c17c219815 Mon Sep 17 00:00:00 2001 From: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com> Date: Mon, 9 Aug 2021 20:04:27 +0100 Subject: [PATCH 06/11] Update with-jest example (#27894) ## Documentation / Examples - [x] Make sure the linting passes This PR updates our current with-jest example to match the examples in upcoming docs, add module alias configuration and be more consistent with Jest conventions. --- examples/with-jest/.babelrc | 3 --- examples/with-jest/__mocks__/fileMock.js | 1 + examples/with-jest/__mocks__/styleMock.js | 4 +++ .../__tests__/__snapshots__/snapshot.js.snap | 4 +-- .../with-jest/__tests__/testing-library.js | 16 ++++++----- .../with-jest/config/jest/cssTransform.js | 8 ------ examples/with-jest/jest.config.js | 27 ++++++++++++++----- examples/with-jest/jest.setup.js | 6 +++++ examples/with-jest/jsconfig.json | 8 ++++++ examples/with-jest/setupTests.js | 6 ----- 10 files changed, 51 insertions(+), 32 deletions(-) delete mode 100644 examples/with-jest/.babelrc create mode 100644 examples/with-jest/__mocks__/fileMock.js create mode 100644 examples/with-jest/__mocks__/styleMock.js delete mode 100644 examples/with-jest/config/jest/cssTransform.js create mode 100644 examples/with-jest/jest.setup.js create mode 100644 examples/with-jest/jsconfig.json delete mode 100644 examples/with-jest/setupTests.js diff --git a/examples/with-jest/.babelrc b/examples/with-jest/.babelrc deleted file mode 100644 index 1ff94f7ed28e16b..000000000000000 --- a/examples/with-jest/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["next/babel"] -} diff --git a/examples/with-jest/__mocks__/fileMock.js b/examples/with-jest/__mocks__/fileMock.js new file mode 100644 index 000000000000000..0e56c5b5f76550e --- /dev/null +++ b/examples/with-jest/__mocks__/fileMock.js @@ -0,0 +1 @@ +module.exports = 'test-file-stub' diff --git a/examples/with-jest/__mocks__/styleMock.js b/examples/with-jest/__mocks__/styleMock.js new file mode 100644 index 000000000000000..8ad91008c30a016 --- /dev/null +++ b/examples/with-jest/__mocks__/styleMock.js @@ -0,0 +1,4 @@ +// Mock CSS files. +// If you're using CSS modules, this file can be deleted. + +module.exports = {} diff --git a/examples/with-jest/__tests__/__snapshots__/snapshot.js.snap b/examples/with-jest/__tests__/__snapshots__/snapshot.js.snap index e470032f1b78b8d..6b1a9c622ce41fd 100644 --- a/examples/with-jest/__tests__/__snapshots__/snapshot.js.snap +++ b/examples/with-jest/__tests__/__snapshots__/snapshot.js.snap @@ -8,7 +8,7 @@ exports[`renders homepage unchanged 1`] = `

- Welcome to + Welcome to @@ -18,7 +18,7 @@ exports[`renders homepage unchanged 1`] = `

- Get started by editing + Get started by editing pages/index.js diff --git a/examples/with-jest/__tests__/testing-library.js b/examples/with-jest/__tests__/testing-library.js index 8f41a1ecdc4ea87..333e1cb9fe622eb 100644 --- a/examples/with-jest/__tests__/testing-library.js +++ b/examples/with-jest/__tests__/testing-library.js @@ -2,10 +2,14 @@ import React from 'react' import { render } from '@testing-library/react' import Index from '../pages/index' -test('renders deploy link', () => { - const { getByText } = render() - const linkElement = getByText( - /Instantly deploy your Next\.js site to a public URL with Vercel\./ - ) - expect(linkElement).toBeInTheDocument() +describe('App', () => { + it('renders a heading', () => { + const { getByRole } = render() + + const heading = getByRole('heading', { + name: /welcome to next\.js!/i, + }) + + expect(heading).toBeInTheDocument() + }) }) diff --git a/examples/with-jest/config/jest/cssTransform.js b/examples/with-jest/config/jest/cssTransform.js deleted file mode 100644 index 24f38118fcdb601..000000000000000 --- a/examples/with-jest/config/jest/cssTransform.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - process() { - return 'module.exports = {};' - }, - getCacheKey() { - return 'cssTransform' - }, -} diff --git a/examples/with-jest/jest.config.js b/examples/with-jest/jest.config.js index 3863e5c0490dbe9..15c4717b8e12284 100644 --- a/examples/with-jest/jest.config.js +++ b/examples/with-jest/jest.config.js @@ -4,17 +4,30 @@ module.exports = { '!**/*.d.ts', '!**/node_modules/**', ], - setupFilesAfterEnv: ['/setupTests.js'], - testPathIgnorePatterns: ['/node_modules/', '/.next/'], + moduleNameMapper: { + // Handle CSS imports (with CSS modules) + // https://jestjs.io/docs/webpack#mocking-css-modules + '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy', + + // Handle CSS imports (without CSS modules) + '^.+\\.(css|sass|scss)$': '/__mocks__/styleMock.js', + + // Handle image imports + // https://jestjs.io/docs/webpack#handling-static-assets + '^.+\\.(jpg|jpeg|png|gif|webp|svg)$': `/__mocks__/fileMock.js`, + + // Handle module aliases + '^@/components/(.*)$': '/components/$1', + }, + setupFilesAfterEnv: ['/jest.setup.js'], + testPathIgnorePatterns: ['/node_modules/', '/.next/'], transform: { - '^.+\\.(js|jsx|ts|tsx)$': '/node_modules/babel-jest', - '^.+\\.css$': '/config/jest/cssTransform.js', + // Use babel-jest to transpile tests with the next/babel preset + // https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object + '^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }], }, transformIgnorePatterns: [ '/node_modules/', '^.+\\.module\\.(css|sass|scss)$', ], - moduleNameMapper: { - '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy', - }, } diff --git a/examples/with-jest/jest.setup.js b/examples/with-jest/jest.setup.js new file mode 100644 index 000000000000000..996e74a2ba7bfd7 --- /dev/null +++ b/examples/with-jest/jest.setup.js @@ -0,0 +1,6 @@ +// Optional: configure or set up a testing framework before each test. +// If you delete this file, remove `setupFilesAfterEnv` from `jest.config.js` + +// Used for __tests__/testing-library.js +// Learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom/extend-expect' diff --git a/examples/with-jest/jsconfig.json b/examples/with-jest/jsconfig.json new file mode 100644 index 000000000000000..e81aa88c59ff160 --- /dev/null +++ b/examples/with-jest/jsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/components/*": ["components/*"] + } + } +} diff --git a/examples/with-jest/setupTests.js b/examples/with-jest/setupTests.js deleted file mode 100644 index 5aa7dfce10a7eb1..000000000000000 --- a/examples/with-jest/setupTests.js +++ /dev/null @@ -1,6 +0,0 @@ -// optional: configure or set up a testing framework before each test -// if you delete this file, remove `setupFilesAfterEnv` from `jest.config.js` - -// used for __tests__/testing-library.js -// learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom/extend-expect' From 97174ac6515e40419b1dc19b3859bccccfd515ea Mon Sep 17 00:00:00 2001 From: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com> Date: Mon, 9 Aug 2021 21:57:17 +0100 Subject: [PATCH 07/11] Add with-cypress example (#27900) This PR adds a with-cypress example to match the examples in upcoming docs. ## Documentation / Examples - [ ] Make sure the linting passes **Note:** This PR does not pass linting because ESLint needs to have the [eslint-plugin-cypress](https://github.com/cypress-io/eslint-plugin-cypress) installed globally to ignore the Cypress methods. --- examples/with-cypress/.gitignore | 34 +++++ examples/with-cypress/README.md | 27 ++++ examples/with-cypress/cypress.json | 3 + .../cypress/fixtures/example.json | 5 + .../cypress/integration/app.spec.js | 20 +++ .../with-cypress/cypress/plugins/index.js | 22 ++++ .../with-cypress/cypress/support/commands.js | 25 ++++ .../with-cypress/cypress/support/index.js | 20 +++ examples/with-cypress/package.json | 23 ++++ examples/with-cypress/pages/_app.js | 7 + examples/with-cypress/pages/about.js | 17 +++ examples/with-cypress/pages/index.js | 77 +++++++++++ examples/with-cypress/public/favicon.ico | Bin 0 -> 25931 bytes examples/with-cypress/public/vercel.svg | 4 + examples/with-cypress/styles/Home.module.css | 121 ++++++++++++++++++ examples/with-cypress/styles/globals.css | 16 +++ 16 files changed, 421 insertions(+) create mode 100644 examples/with-cypress/.gitignore create mode 100644 examples/with-cypress/README.md create mode 100644 examples/with-cypress/cypress.json create mode 100644 examples/with-cypress/cypress/fixtures/example.json create mode 100644 examples/with-cypress/cypress/integration/app.spec.js create mode 100644 examples/with-cypress/cypress/plugins/index.js create mode 100644 examples/with-cypress/cypress/support/commands.js create mode 100644 examples/with-cypress/cypress/support/index.js create mode 100644 examples/with-cypress/package.json create mode 100644 examples/with-cypress/pages/_app.js create mode 100644 examples/with-cypress/pages/about.js create mode 100644 examples/with-cypress/pages/index.js create mode 100644 examples/with-cypress/public/favicon.ico create mode 100644 examples/with-cypress/public/vercel.svg create mode 100644 examples/with-cypress/styles/Home.module.css create mode 100644 examples/with-cypress/styles/globals.css diff --git a/examples/with-cypress/.gitignore b/examples/with-cypress/.gitignore new file mode 100644 index 000000000000000..1437c53f70bc211 --- /dev/null +++ b/examples/with-cypress/.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-cypress/README.md b/examples/with-cypress/README.md new file mode 100644 index 000000000000000..e8fe010feae3027 --- /dev/null +++ b/examples/with-cypress/README.md @@ -0,0 +1,27 @@ +# Next.js + Cypress + +This example shows how to configure Cypress to work with Next.js. + +## Preview + +Preview the example live on [StackBlitz](http://stackblitz.com/): + +[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-cypress) + +## Deploy your own + +Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example): + +[![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-cypress&project-name=with-cypress&repository-name=with-cypress) + +## How to use + +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-cypress with-cypress-app +# or +yarn create next-app --example with-cypress with-cypress-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-cypress/cypress.json b/examples/with-cypress/cypress.json new file mode 100644 index 000000000000000..17ef242e711f0f7 --- /dev/null +++ b/examples/with-cypress/cypress.json @@ -0,0 +1,3 @@ +{ + "baseUrl": "http://localhost:3000" +} diff --git a/examples/with-cypress/cypress/fixtures/example.json b/examples/with-cypress/cypress/fixtures/example.json new file mode 100644 index 000000000000000..02e4254378e9785 --- /dev/null +++ b/examples/with-cypress/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} diff --git a/examples/with-cypress/cypress/integration/app.spec.js b/examples/with-cypress/cypress/integration/app.spec.js new file mode 100644 index 000000000000000..a1330a1a907bacf --- /dev/null +++ b/examples/with-cypress/cypress/integration/app.spec.js @@ -0,0 +1,20 @@ +/* eslint-disable */ +// Disable ESLint to prevent failing linting inside the Next.js repo. +// If you're using ESLint on your project, we recommend installing the ESLint Cypress plugin instead: +// https://github.com/cypress-io/eslint-plugin-cypress + +describe('Navigation', () => { + it('should navigate to the about page', () => { + // Start from the index page + cy.visit('http://localhost:3000/') + + // Find a link with an href attribute containing "about" and click it + cy.get('a[href*="about"]').click() + + // The new url should include "/about" + cy.url().should('include', '/about') + + // The new page should contain an h1 with "About page" + cy.get('h1').contains('About Page') + }) +}) diff --git a/examples/with-cypress/cypress/plugins/index.js b/examples/with-cypress/cypress/plugins/index.js new file mode 100644 index 000000000000000..59b2bab6e4e6059 --- /dev/null +++ b/examples/with-cypress/cypress/plugins/index.js @@ -0,0 +1,22 @@ +/// +// *********************************************************** +// This example plugins/index.js can be used to load plugins +// +// You can change the location of this file or turn off loading +// the plugins file with the 'pluginsFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/plugins-guide +// *********************************************************** + +// This function is called when a project is opened or re-opened (e.g. due to +// the project's config changing) + +/** + * @type {Cypress.PluginConfig} + */ +// eslint-disable-next-line no-unused-vars +module.exports = (on, config) => { + // `on` is used to hook into various events Cypress emits + // `config` is the resolved Cypress config +} diff --git a/examples/with-cypress/cypress/support/commands.js b/examples/with-cypress/cypress/support/commands.js new file mode 100644 index 000000000000000..119ab03f7cda1f8 --- /dev/null +++ b/examples/with-cypress/cypress/support/commands.js @@ -0,0 +1,25 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) diff --git a/examples/with-cypress/cypress/support/index.js b/examples/with-cypress/cypress/support/index.js new file mode 100644 index 000000000000000..d68db96df2697e0 --- /dev/null +++ b/examples/with-cypress/cypress/support/index.js @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' + +// Alternatively you can use CommonJS syntax: +// require('./commands') diff --git a/examples/with-cypress/package.json b/examples/with-cypress/package.json new file mode 100644 index 000000000000000..966a833f699b43a --- /dev/null +++ b/examples/with-cypress/package.json @@ -0,0 +1,23 @@ +{ + "name": "with-cypress", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "cypress": "cypress open", + "cypress:headless": "cypress run", + "e2e": "start-server-and-test dev http://localhost:3000 cypress", + "e2e:headless": "start-server-and-test dev http://localhost:3000 cypress:headless" + }, + "dependencies": { + "next": "latest", + "react": "17.0.2", + "react-dom": "17.0.2" + }, + "devDependencies": { + "cypress": "8.2.0", + "start-server-and-test": "1.13.1" + } +} diff --git a/examples/with-cypress/pages/_app.js b/examples/with-cypress/pages/_app.js new file mode 100644 index 000000000000000..1e1cec92425c8b3 --- /dev/null +++ b/examples/with-cypress/pages/_app.js @@ -0,0 +1,7 @@ +import '../styles/globals.css' + +function MyApp({ Component, pageProps }) { + return +} + +export default MyApp diff --git a/examples/with-cypress/pages/about.js b/examples/with-cypress/pages/about.js new file mode 100644 index 000000000000000..0db64404746b191 --- /dev/null +++ b/examples/with-cypress/pages/about.js @@ -0,0 +1,17 @@ +import styles from '../styles/Home.module.css' +import Link from 'next/link' + +export default function About() { + return ( +

+ ) +} diff --git a/examples/with-cypress/pages/index.js b/examples/with-cypress/pages/index.js new file mode 100644 index 000000000000000..7af20bc61f52635 --- /dev/null +++ b/examples/with-cypress/pages/index.js @@ -0,0 +1,77 @@ +import Head from 'next/head' +import Image from 'next/image' +import Link from 'next/link' +import styles from '../styles/Home.module.css' + +export default function Home() { + return ( + + ) +} diff --git a/examples/with-cypress/public/favicon.ico b/examples/with-cypress/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..718d6fea4835ec2d246af9800eddb7ffb276240c GIT binary patch literal 25931 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 LrJugUA?W`A8`#=m literal 0 HcmV?d00001 diff --git a/examples/with-cypress/public/vercel.svg b/examples/with-cypress/public/vercel.svg new file mode 100644 index 000000000000000..fbf0e25a651c289 --- /dev/null +++ b/examples/with-cypress/public/vercel.svg @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/examples/with-cypress/styles/Home.module.css b/examples/with-cypress/styles/Home.module.css new file mode 100644 index 000000000000000..35454bb748190db --- /dev/null +++ b/examples/with-cypress/styles/Home.module.css @@ -0,0 +1,121 @@ +.container { + min-height: 100vh; + padding: 0 0.5rem; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100vh; +} + +.main { + padding: 5rem 0; + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.footer { + width: 100%; + height: 100px; + border-top: 1px solid #eaeaea; + display: flex; + justify-content: center; + align-items: center; +} + +.footer a { + display: flex; + justify-content: center; + align-items: center; + flex-grow: 1; +} + +.title a { + color: #0070f3; + text-decoration: none; +} + +.title a:hover, +.title a:focus, +.title a:active { + text-decoration: underline; +} + +.title { + margin: 0; + line-height: 1.15; + font-size: 4rem; +} + +.title, +.description { + text-align: center; +} + +.description { + line-height: 1.5; + font-size: 1.5rem; +} + +.code { + background: #fafafa; + border-radius: 5px; + padding: 0.75rem; + font-size: 1.1rem; + font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, + Bitstream Vera Sans Mono, Courier New, monospace; +} + +.grid { + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; + max-width: 800px; + margin-top: 3rem; +} + +.card { + margin: 1rem; + padding: 1.5rem; + text-align: left; + color: inherit; + text-decoration: none; + border: 1px solid #eaeaea; + border-radius: 10px; + transition: color 0.15s ease, border-color 0.15s ease; + width: 45%; +} + +.card:hover, +.card:focus, +.card:active { + color: #0070f3; + border-color: #0070f3; +} + +.card h2 { + margin: 0 0 1rem 0; + font-size: 1.5rem; +} + +.card p { + margin: 0; + font-size: 1.25rem; + line-height: 1.5; +} + +.logo { + height: 1em; + margin-left: 0.5rem; +} + +@media (max-width: 600px) { + .grid { + width: 100%; + flex-direction: column; + } +} diff --git a/examples/with-cypress/styles/globals.css b/examples/with-cypress/styles/globals.css new file mode 100644 index 000000000000000..e5e2dcc23baf192 --- /dev/null +++ b/examples/with-cypress/styles/globals.css @@ -0,0 +1,16 @@ +html, +body { + padding: 0; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, + Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; +} + +a { + color: inherit; + text-decoration: none; +} + +* { + box-sizing: border-box; +} From 8cbaa409ca7dce8786cef5625700df094c9c7cd9 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Tue, 10 Aug 2021 11:01:53 +0200 Subject: [PATCH 08/11] v11.0.2-canary.28 --- 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/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/package.json | 12 ++++++------ packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- 14 files changed, 20 insertions(+), 20 deletions(-) diff --git a/lerna.json b/lerna.json index 9f16bf000a20962..ab5ea144cecd904 100644 --- a/lerna.json +++ b/lerna.json @@ -17,5 +17,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "11.0.2-canary.27" + "version": "11.0.2-canary.28" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index cb13283260cfe97..5e45f970d1b23cd 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "11.0.2-canary.27", + "version": "11.0.2-canary.28", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 13411ff9bb7a551..6cb91f75a753521 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "11.0.2-canary.27", + "version": "11.0.2-canary.28", "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": "11.0.2-canary.27", + "@next/eslint-plugin-next": "11.0.2-canary.28", "@rushstack/eslint-patch": "^1.0.6", "@typescript-eslint/parser": "^4.20.0", "eslint-import-resolver-node": "^0.3.4", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 6b3dc63120eb412..0b85d4968780e21 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": "11.0.2-canary.27", + "version": "11.0.2-canary.28", "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 fa589266006fdd1..8c54cd8cf2b5fa8 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "11.0.2-canary.27", + "version": "11.0.2-canary.28", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index dfcbd0e250b33a9..25123341feb00f3 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "11.0.2-canary.27", + "version": "11.0.2-canary.28", "license": "MIT", "dependencies": { "chalk": "4.1.0", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 5947f0fcf15472b..58faa3ba21c90c6 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "11.0.2-canary.27", + "version": "11.0.2-canary.28", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index db6d6fe40aca0ce..12be25f1f7efbdf 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "11.0.2-canary.27", + "version": "11.0.2-canary.28", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 403eeaf20aea929..346b72a33729a7f 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "11.0.2-canary.27", + "version": "11.0.2-canary.28", "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 e0a432a5d1cb5bb..e1bd9d0059801d4 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "11.0.2-canary.27", + "version": "11.0.2-canary.28", "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 635a25c71849011..0d39510fc776374 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "11.0.2-canary.27", + "version": "11.0.2-canary.28", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next/package.json b/packages/next/package.json index eac16043299154f..7746a906adcbef8 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "11.0.2-canary.27", + "version": "11.0.2-canary.28", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -65,10 +65,10 @@ "dependencies": { "@babel/runtime": "7.12.5", "@hapi/accept": "5.0.2", - "@next/env": "11.0.2-canary.27", - "@next/polyfill-module": "11.0.2-canary.27", - "@next/react-dev-overlay": "11.0.2-canary.27", - "@next/react-refresh-utils": "11.0.2-canary.27", + "@next/env": "11.0.2-canary.28", + "@next/polyfill-module": "11.0.2-canary.28", + "@next/react-dev-overlay": "11.0.2-canary.28", + "@next/react-refresh-utils": "11.0.2-canary.28", "@node-rs/helper": "1.2.1", "assert": "2.0.0", "ast-types": "0.13.2", @@ -153,7 +153,7 @@ "@babel/traverse": "^7.12.10", "@babel/types": "7.12.12", "@napi-rs/cli": "1.1.0", - "@next/polyfill-nomodule": "11.0.2-canary.27", + "@next/polyfill-nomodule": "11.0.2-canary.28", "@taskr/clear": "1.1.0", "@taskr/esnext": "1.1.0", "@taskr/watch": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index c261286a13dcc98..a08d3b4e8900899 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": "11.0.2-canary.27", + "version": "11.0.2-canary.28", "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 868709de54f4d8d..5a6eea88cac66b7 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": "11.0.2-canary.27", + "version": "11.0.2-canary.28", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", From 0cc4a980416c8afd979558dbaf17d42fbd75633c Mon Sep 17 00:00:00 2001 From: ahmed osama <76496317+ahmedosama7450@users.noreply.github.com> Date: Tue, 10 Aug 2021 14:01:14 +0200 Subject: [PATCH 09/11] Little typo (#27911) ## 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 - [ ] Make sure the linting passes --- docs/routing/dynamic-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/routing/dynamic-routes.md b/docs/routing/dynamic-routes.md index f8a74550610f1bd..9f0b7f66517f4bf 100644 --- a/docs/routing/dynamic-routes.md +++ b/docs/routing/dynamic-routes.md @@ -145,7 +145,7 @@ For more information on what to do next, we recommend the following sections: From eb871d30915d668dd9ba897d4d04ced207ce2e6d Mon Sep 17 00:00:00 2001 From: stefanprobst Date: Tue, 10 Aug 2021 17:51:08 +0200 Subject: [PATCH 10/11] Replace `placeholder` with `blurDataURL` in global `StaticImageData` type (#27916) I think the global `StaticImageData` type does not currently match what actually gets imported, and what the `Image` component expects (see [here](https://github.com/vercel/next.js/blob/canary/packages/next/client/image.tsx#L60-L65)). This PR changes `placeholder` to `blurDataURL`. ## 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 - [ ] Make sure the linting passes --- packages/next/image-types/global.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/image-types/global.d.ts b/packages/next/image-types/global.d.ts index 394e4bf3a47e2bb..a41a6c6a5a04ae1 100644 --- a/packages/next/image-types/global.d.ts +++ b/packages/next/image-types/global.d.ts @@ -5,7 +5,7 @@ interface StaticImageData { src: string height: number width: number - placeholder?: string + blurDataURL?: string } declare module '*.png' { From 43393d53bedfb101dd49cce44309e7c3bc9b7cbc Mon Sep 17 00:00:00 2001 From: Janicklas Ralph Date: Tue, 10 Aug 2021 10:41:26 -0700 Subject: [PATCH 11/11] Fix `next/script` unhandled promise rejection (#27903) ## Bug - [x] fixes #27747 - [x] Integration tests added --- packages/next/client/script.tsx | 19 ++++++++++--------- test/integration/script-loader/pages/page3.js | 8 ++++++++ .../script-loader/test/index.test.js | 6 ++++++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/packages/next/client/script.tsx b/packages/next/client/script.tsx index 8968f0e77b19856..782925de8c0cdca 100644 --- a/packages/next/client/script.tsx +++ b/packages/next/client/script.tsx @@ -10,8 +10,8 @@ const LoadCache = new Set() export interface ScriptProps extends ScriptHTMLAttributes { strategy?: 'afterInteractive' | 'lazyOnload' | 'beforeInteractive' id?: string - onLoad?: () => void - onError?: () => void + onLoad?: (e: any) => void + onError?: (e: any) => void children?: React.ReactNode } @@ -56,18 +56,19 @@ const loadScript = (props: ScriptProps): void => { const el = document.createElement('script') const loadPromise = new Promise((resolve, reject) => { - el.addEventListener('load', function () { + el.addEventListener('load', function (e) { resolve() if (onLoad) { - onLoad.call(this) + onLoad.call(this, e) } }) - el.addEventListener('error', function () { - reject() - if (onError) { - onError() - } + el.addEventListener('error', function (e) { + reject(e) }) + }).catch(function (e) { + if (onError) { + onError(e) + } }) if (src) { diff --git a/test/integration/script-loader/pages/page3.js b/test/integration/script-loader/pages/page3.js index 8da988ec5077993..7a8a05a9ebf69ec 100644 --- a/test/integration/script-loader/pages/page3.js +++ b/test/integration/script-loader/pages/page3.js @@ -15,6 +15,14 @@ const Page = () => { src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptLazyOnload" strategy="lazyOnload" > +