From 3ff21ed1780f53b1a6f6a22d31be435c352ef450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Fri, 16 Sep 2022 23:54:58 +0200 Subject: [PATCH] refactor: split up `CONTRIBUTING.md` (#40515) Continues #39778 Closes #40499 ## 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 by running `pnpm lint` - [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples) Co-authored-by: Tim Neutkens Co-authored-by: JJ Kasper --- .github/pull_request_template.md | 8 +- .vscode/launch.json | 65 ++-- bench/nested-deps/package.json | 8 +- contributing.md | 349 +----------------- contributing/core/adding-error-links.md | 12 + contributing/core/building.md | 13 + .../core/developing-using-local-app.md | 50 +++ contributing/core/developing.md | 44 +++ contributing/core/testing.md | 63 ++++ contributing/core/vscode-debugger.md | 27 ++ contributing/docs/adding-documentation.md | 40 ++ contributing/examples/adding-examples.md | 57 +++ contributing/examples/run-example-apps.md | 22 ++ contributing/repository/linting.md | 37 ++ .../repository/pull-request-descriptions.md | 7 + .../repository/release-channels-publishing.md | 25 ++ contributing/repository/triaging.md | 21 ++ errors/template.txt | 4 + package.json | 1 + .../next/bundles/webpack/packages/webpack.js | 2 +- packages/next/compiled/webpack/webpack.js | 2 +- plopfile.js | 20 +- scripts/run-for-change.js | 1 + test/readme.md | 37 +- 24 files changed, 498 insertions(+), 417 deletions(-) create mode 100644 contributing/core/adding-error-links.md create mode 100644 contributing/core/building.md create mode 100644 contributing/core/developing-using-local-app.md create mode 100644 contributing/core/developing.md create mode 100644 contributing/core/testing.md create mode 100644 contributing/core/vscode-debugger.md create mode 100644 contributing/docs/adding-documentation.md create mode 100644 contributing/examples/adding-examples.md create mode 100644 contributing/examples/run-example-apps.md create mode 100644 contributing/repository/linting.md create mode 100644 contributing/repository/pull-request-descriptions.md create mode 100644 contributing/repository/release-channels-publishing.md create mode 100644 contributing/repository/triaging.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index f6cb16be0bfdf71..cf3c20b02d63d0c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,6 +1,6 @@ @@ -8,7 +8,7 @@ Choose the right checklist for the change that you're making: - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added -- [ ] Errors have helpful link attached, see `contributing.md` +- [ ] Errors have a helpful link attached, see `contributing.md` ## Feature @@ -17,9 +17,9 @@ Choose the right checklist for the change that you're making: - [ ] 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` +- [ ] Errors have a helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm lint` -- [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples) +- [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md) diff --git a/.vscode/launch.json b/.vscode/launch.json index 16184462f33f1e1..e88773d91c2cac1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,13 +9,11 @@ "type": "node", "request": "launch", "cwd": "${workspaceFolder}", - "runtimeExecutable": "yarn", - "runtimeArgs": ["run", "debug-react-exp", "dev", "test/e2e/app-dir/app"], + "runtimeExecutable": "pnpm", + "runtimeArgs": ["debug-react-exp", "dev", "test/e2e/app-dir/app"], "skipFiles": ["/**"], - "outFiles": ["${workspaceFolder}/packages/next/dist/**/*"], - "port": 9229, "env": { - "NEXT_PRIVATE_LOCAL_WEBPACK5": "1" + "NEXT_PRIVATE_LOCAL_WEBPACK": "1" } }, { @@ -23,13 +21,11 @@ "type": "node", "request": "launch", "cwd": "${workspaceFolder}", - "runtimeExecutable": "yarn", - "runtimeArgs": ["run", "debug", "dev", "bench/nested-deps"], + "runtimeExecutable": "pnpm", + "runtimeArgs": ["debug", "dev", "examples/hello-world"], "skipFiles": ["/**"], - "outFiles": ["${workspaceFolder}/packages/next/dist/**/*"], - "port": 9229, "env": { - "NEXT_PRIVATE_LOCAL_WEBPACK5": "1" + "NEXT_PRIVATE_LOCAL_WEBPACK": "1" } }, { @@ -37,64 +33,57 @@ "type": "node", "request": "launch", "cwd": "${workspaceFolder}", - "runtimeExecutable": "yarn", - "runtimeArgs": ["run", "debug", "build", "bench/nested-deps"], + "runtimeExecutable": "pnpm", + "runtimeArgs": ["debug", "build", "examples/hello-world"], "skipFiles": ["/**"], - "port": 9229, - "outFiles": ["${workspaceFolder}/packages/next/dist/**/*"], "env": { - "NEXT_PRIVATE_LOCAL_WEBPACK5": "1" + "NEXT_PRIVATE_LOCAL_WEBPACK": "1" } }, { - "name": "Launch app build trace jaeger", + "name": "Launch app production", "type": "node", "request": "launch", "cwd": "${workspaceFolder}", - "runtimeExecutable": "yarn", - "runtimeArgs": ["run", "clean-trace-jaeger"], + "runtimeExecutable": "pnpm", + "runtimeArgs": ["debug", "start", "examples/hello-world"], "skipFiles": ["/**"], - "port": 9229, - "outFiles": ["${workspaceFolder}/packages/next/dist/**/*"], "env": { - "NEXT_PRIVATE_LOCAL_WEBPACK5": "1" + "NEXT_PRIVATE_LOCAL_WEBPACK": "1" } }, { - "name": "Launch app production", + "name": "Launch current directory in development", "type": "node", "request": "launch", "cwd": "${workspaceFolder}", - "runtimeExecutable": "yarn", - "runtimeArgs": ["run", "debug", "start", "bench/nested-deps"], + "runtimeExecutable": "pnpm", + "runtimeArgs": ["debug", "dev", "${fileDirname}"], "skipFiles": ["/**"], - "port": 9229, "env": { - "NEXT_PRIVATE_LOCAL_WEBPACK5": "1" + "NEXT_PRIVATE_LOCAL_WEBPACK": "1" } }, { + "name": "Launch app build trace jaeger", "type": "node", - "request": "attach", - "name": "Attach to existing debugger", - "port": 9229, + "request": "launch", + "cwd": "${workspaceFolder}", + "runtimeExecutable": "pnpm", + "runtimeArgs": ["clean-trace-jaeger"], "skipFiles": ["/**"], - "outFiles": ["${workspaceFolder}/packages/next/dist/**/*"], "env": { - "NEXT_PRIVATE_LOCAL_WEBPACK5": "1" + "NEXT_PRIVATE_LOCAL_WEBPACK": "1" } }, { - "name": "Launch this example", "type": "node", - "request": "launch", - "cwd": "${workspaceFolder}", - "runtimeExecutable": "yarn", - "runtimeArgs": ["run", "debug", "dev", "${fileDirname}"], - "skipFiles": ["/**"], + "request": "attach", + "name": "Attach to existing debugger", "port": 9229, + "skipFiles": ["/**"], "env": { - "NEXT_PRIVATE_LOCAL_WEBPACK5": "1" + "NEXT_PRIVATE_LOCAL_WEBPACK": "1" } } ] diff --git a/bench/nested-deps/package.json b/bench/nested-deps/package.json index e1be9e25267f29d..91c3fca60c60c61 100644 --- a/bench/nested-deps/package.json +++ b/bench/nested-deps/package.json @@ -1,11 +1,11 @@ { "scripts": { "prepare": "rimraf components && mkdir components && node ./fuzzponent.js -d 2 -s 206 -o components", - "dev": "cross-env NEXT_PRIVATE_LOCAL_WEBPACK5=1 node ../../node_modules/next/dist/bin/next dev", - "build": "cross-env NEXT_PRIVATE_LOCAL_WEBPACK5=1 node ../../node_modules/next/dist/bin/next build", - "start": "cross-env NEXT_PRIVATE_LOCAL_WEBPACK5=1 node ../../node_modules/next/dist/bin/next start", + "dev": "cross-env NEXT_PRIVATE_LOCAL_WEBPACK=1 node ../../node_modules/next/dist/bin/next dev", + "build": "cross-env NEXT_PRIVATE_LOCAL_WEBPACK=1 node ../../node_modules/next/dist/bin/next build", + "start": "cross-env NEXT_PRIVATE_LOCAL_WEBPACK=1 node ../../node_modules/next/dist/bin/next start", "dev-nocache": "rimraf .next && yarn dev", - "dev-cpuprofile-nocache": "rimraf .next && cross-env NEXT_PRIVATE_LOCAL_WEBPACK5=1 node --cpu-prof ../../node_modules/next/dist/bin/next", + "dev-cpuprofile-nocache": "rimraf .next && cross-env NEXT_PRIVATE_LOCAL_WEBPACK=1 node --cpu-prof ../../node_modules/next/dist/bin/next", "build-nocache": "rimraf .next && yarn build" }, "devDependencies": { diff --git a/contributing.md b/contributing.md index e5403bdef11bae9..32733ca5e4002dc 100644 --- a/contributing.md +++ b/contributing.md @@ -2,345 +2,32 @@ [Watch the 40-minute walkthrough video on how to contribute to Next.js.](https://www.youtube.com/watch?v=cuoNzXFLitc) ---- - - Read about our [Commitment to Open Source](https://vercel.com/oss). -- To contribute to [our examples](examples), please see [Adding examples](#adding-examples) below. - Before jumping into a PR be sure to search [existing PRs](https://github.com/vercel/next.js/pulls) or [issues](https://github.com/vercel/next.js/issues) for an open or closed item that relates to your submission. -## Developing - -The development branch is `canary`. This is the branch that all pull -requests should be made against. The changes on the `canary` -branch are published to the `@canary` tag on npm regularly. - -To develop locally: - -1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your - own GitHub account and then - [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device. - - If you don't need the whole git history, you can clone with depth 1 to reduce the download size (~1.6GB): - - ```sh - git clone --depth=1 https://github.com/vercel/next.js - ``` - -2. Create a new branch: - ``` - git checkout -b MY_BRANCH_NAME - ``` -3. Enable pnpm: - ``` - corepack enable pnpm - ``` -4. Install the dependencies with: - ``` - pnpm install - ``` -5. Start developing and watch for code changes: - ``` - pnpm dev - ``` -6. In a new terminal, run `pnpm types` to compile declaration files from - TypeScript. - - _Note: You may need to repeat this step if your types get outdated._ - -For instructions on how to build a project with your local version of the CLI, -see **[Developing with your local version of Next.js](#developing-with-your-local-version-of-nextjs)** -below. (Naively linking the binary is not sufficient to develop locally.) - -## Building - -You can build the project, including all type definitions, with: - -```bash -pnpm build -# - or - -pnpm prepublishOnly -``` - -By default, the latest canary of the next-swc binaries will be installed and used. If you are actively working on Rust code or you need to test out the most recent Rust code that hasn't been published as a canary yet you can [install Rust](https://www.rust-lang.org/tools/install) and run `pnpm --filter=@next/swc build-native`. - -If you want to test out the wasm build locally, you will need to [install wasm-pack](https://rustwasm.github.io/wasm-pack/installer/). Run `pnpm --filter=@next/swc build-wasm --target ` to build and `node ./scripts/setup-wasm.mjs` to copy it into your `node_modules`. Run next with `NODE_OPTIONS='--no-addons'` to force it to use the wasm binary. - -If you need to clean the project for any reason, use `pnpm clean`. - -## Testing - -See the [testing readme](./test/readme.md) for information on writing tests. - -### Running tests - -```sh -pnpm testonly -``` - -If you would like to run the tests in headless mode (with the browser windows hidden) you can do - -```sh -pnpm testheadless -``` - -Running a specific test suite (e.g. `production`) inside of the `test/integration` directory: - -```sh -pnpm testonly --testPathPattern "production" -``` - -Running one test in the `production` test suite: - -```sh -pnpm testonly --testPathPattern "production" -t "should allow etag header support" -``` - -### Linting - -To check the formatting of your code: - -```sh -pnpm lint -``` - -If you get errors, you can fix them with: - -```sh -pnpm lint-fix -``` - -### Running the example apps - -Running examples can be done with: - -```sh -pnpm next ./examples/basic-css/ -``` - -To figure out which pages are available for the given example, you can run: - -```sh -EXAMPLE=./test/integration/basic -(\ - cd $EXAMPLE/pages; \ - find . -type f \ - | grep -v '\.next' \ - | sed 's#^\.##' \ - | sed 's#index\.js##' \ - | sed 's#\.js$##' \ - | xargs -I{} echo localhost:3000{} \ -) -``` - -## Developing with your local version of Next.js - -There are two options to develop with your local version of the codebase: - -### Set as a local dependency in package.json - -1. In your app's `package.json`, replace: - - ```json - "next": "", - ``` - - with: - - ```json - "next": "link:/path/to/next.js/packages/next", - ``` - -2. In your app's root directory, make sure to remove `next` from `node_modules` with: - - ```sh - rm -rf ./node_modules/next - ``` - -3. In your app's root directory, run: - - ```sh - pnpm i - ``` - - to re-install all of the dependencies. - - Note that Next will be copied from the locally compiled version as opposed to being downloaded from the NPM registry. - -4. Run your application as you normally would. - -5. To update your app's dependencies, after you've made changes to your local `next` repository. In your app's root directory, run: - - ```sh - pnpm install --force - ``` - -#### Troubleshooting - -- If you see the below error while running `pnpm dev` with next: - -``` -Failed to load SWC binary, see more info here: https://nextjs.org/docs/messages/failed-loading-swc -``` - -Try to add the below section to your `package.json`, then run again - -```json -"optionalDependencies": { - "@next/swc-linux-x64-gnu": "canary", - "@next/swc-win32-x64-msvc": "canary", - "@next/swc-darwin-x64": "canary", - "@next/swc-darwin-arm64": "canary" -}, -``` - -### Develop inside the monorepo - -1. Move your app inside of the Next.js monorepo. - -2. Run with `pnpm next-with-deps ./app-path-in-monorepo` - -This will use the version of `next` built inside of the Next.js monorepo and the -main `pnpm dev` monorepo command can be running to make changes to the local -Next.js version at the same time (some changes might require re-running `pnpm next-with-deps` to take effect). - -## Updating documentation paths - -Our documentation currently leverages a [manifest file](/docs/manifest.json) which is how documentation entries are checked. - -When adding a new entry under an existing category you only need to add an entry with `{title: '', path: '/docs/path/to/file.md'}`. The "title" is what is shown on the sidebar. - -When moving the location/url of an entry the "title" field can be removed from the existing entry and the ".md" extension removed from the "path", then a "redirect" field with the shape of `{permanent: true/false, destination: '/some-url'}` can be added. A new entry should be added with the "title" and "path" fields if the document was renamed within the [`docs` folder](/docs) that points to the new location in the folder e.g. `/docs/some-url.md` - -Example of moving documentation file: - -Before: - -```json -[ - { - "path": "/docs/original.md", - "title": "Hello world" - } -] -``` - -After: - -```json -[ - { - "path": "/docs/original", - "redirect": { - "permanent": false, - "destination": "/new" - } - } - { - "path": "/docs/new.md", - "title": "Hello world" - }, -] -``` - -Note: the manifest is checked automatically in the "lint" step in CI when opening a PR. - -## Adding warning/error descriptions - -In Next.js we have a system to add helpful links to warnings and errors. - -This allows for the logged message to be short while giving a broader description and instructions on how to solve the warning/error. - -In general, all warnings and errors added should have these links attached. - -Below are the steps to add a new link: - -1. Run `pnpm new-error` which will create the error document and update the manifest automatically. -2. Add the following url to your warning/error: - `https://nextjs.org/docs/messages/`. - - For example, to link to `errors/api-routes-static-export.md` you use the url: - `https://nextjs.org/docs/messages/api-routes-static-export` - -## Adding examples - -When you add an example to the [examples](examples) directory, please follow these guidelines to ensure high-quality examples: - -- TypeScript should be leveraged for new examples (no need for separate JavaScript and TypeScript examples, converting old JavaScript examples is preferred) -- Examples should not add custom ESLint configuration (we have specific templates for ESLint) -- If API routes aren't used in an example, they should be omitted -- If an example exists for a certain library and you would like to showcase a specific feature of that library, the existing example should be updated (instead of adding a new example) -- Package manager specific config should not be added (e.g. `resolutions` in `package.json`) -- In `package.json` the version of `next` (and `eslint-config-next`) should be `latest` -- In `package.json` the dependency versions should be up-to-date -- Use `export default function` for page components and API Routes instead of `const`/`let` (The exception is if the page has `getInitialProps`, in which case [`NextPage`](https://nextjs.org/docs/api-reference/data-fetching/get-initial-props#typescript) could be useful) -- CMS example directories should be prefixed with `cms-` -- Example directories should not be prefixed with `with-` -- Make sure linting passes (you can run `pnpm lint-fix`) - -Also, don’t forget to add a `README.md` file with the following format: - -- Replace `DIRECTORY_NAME` with the directory name you’re adding. -- Fill in `Example Name` and `Description`. -- Examples should be TypeScript first, if possible. -- Omit the `name` and `version` fields from your `package.json`. -- Ensure all your dependencies are up to date. -- Ensure you’re using [`next/image`](https://nextjs.org/docs/api-reference/next/image). -- To add additional installation instructions, please add it where appropriate. -- To add additional notes, add `## Notes` section at the end. -- Remove the `Deploy your own` section if your example can’t be immediately deployed to Vercel. - -````markdown -# Example Name - -Description - -## 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/DIRECTORY_NAME&project-name=DIRECTORY_NAME&repository-name=DIRECTORY_NAME) - -## 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), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example: - -```bash -npx create-next-app --example DIRECTORY_NAME DIRECTORY_NAME-app -``` - -```bash -yarn create next-app --example DIRECTORY_NAME DIRECTORY_NAME-app -``` - -```bash -pnpm create next-app --example DIRECTORY_NAME DIRECTORY_NAME-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)). -```` - -## Publishing - -Repository maintainers can use `yarn publish-canary` to publish a new version of all packages to npm. - -## Triaging - -Repository maintainers triage every issue and PR opened in the repository. +## Repository -Issues are opened with one of these labels: +- [Triaging](./contributing/repository/triaging.md) +- [Linting](./contributing/repository/linting.md) +- [Release Channels and Publishing](./contributing/repository/release-channels-publishing.md) +- [Pull Request Descriptions](./contributing/repository/pull-request-descriptions.md) -- `template: story` - a feature request, converted to an [💡 Ideas discussion](https://github.com/vercel/next.js/discussions/categories/ideas) -- `template: bug` - unverified issue with Next.js itself, or one of the examples in the [`examples`](https://github.com/vercel/next.js/tree/canary/examples) folder -- `template: documentation` - feedback for improvement or an unverified issue with the Next.js documentation +## Documentation -In the case of a bug report, a maintainer looks at the provided reproduction. If the reproduction is missing or insufficient, a `please add a complete reproduction` label is added. If a reproduction is not provided for more than 30 days, the issue becomes stale and will be automatically closed. If a reproduction is provided within 30 days, the `please add a complete reproduction` label is removed and the issue will not become stale anymore. +- [Adding Documentation](./contributing/docs/adding-documentation.md) -Bug reports must be verified against the `next@canary` release. 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 before opening a new issue. Issues not verified against `next@canary` will be closed after 30 days. +## Examples -If the issue is specific to the project and not to Next.js itself, it might be converted to a [🎓️ Help discussion](https://github.com/vercel/next.js/discussions/categories/help) +To contribute to [our examples](./examples), please see -If the bug is verified, it will receive the `kind: bug` label and will be tracked by the maintainers. An `area:` label can be added to indicate which part of Next.js is affected. +- [Adding Examples](./contributing/examples/adding-examples.md) +- [Run Example Apps](./contributing/examples/run-example-apps.md) -Confirmed issues never become stale or are closed before resolution. +## Core -All **closed** PRs and Issues will be locked after 30 days of inactivity (eg.: comment, referencing from elsewhere). +- [Developing](./contributing/core/developing.md) +- [Building](./contributing/core/building.md) +- [Testing](./contributing/core/testing.md) +- [Adding Error Links](./contributing/core/adding-error-links.md) +- [Developing Using Local App](./contributing/core/developing-using-local-app.md) + diff --git a/contributing/core/adding-error-links.md b/contributing/core/adding-error-links.md new file mode 100644 index 000000000000000..0f6ccb3d662276b --- /dev/null +++ b/contributing/core/adding-error-links.md @@ -0,0 +1,12 @@ +# Adding Warning and Error Descriptions + +Next.js has a system to add helpful links to warnings and errors. + +This allows the logged message to be short while giving a broader description and instructions on how to solve the warning/error on the documentation. + +In general, all warnings and errors added should have these links attached. + +Below are the steps to add a new link: + +1. Run `pnpm new-error` which will create the error document and update the manifest automatically. +2. At the end of the command the URL for the error will be provided, add that to your error. diff --git a/contributing/core/building.md b/contributing/core/building.md new file mode 100644 index 000000000000000..afe3c67cd568a46 --- /dev/null +++ b/contributing/core/building.md @@ -0,0 +1,13 @@ +# Building + +You can build Next.js, including all type definitions and packages, with: + +```bash +pnpm build +``` + +By default, the latest canary of the `next-swc` binaries will be installed and used. If you are actively working on Rust code or you need to test out the most recent Rust code that hasn't been published as a canary yet you can [install Rust](https://www.rust-lang.org/tools/install) and run `pnpm --filter=@next/swc build-native`. + +If you want to test out the wasm build locally, you will need to [install wasm-pack](https://rustwasm.github.io/wasm-pack/installer/). Run `pnpm --filter=@next/swc build-wasm --target ` to build and `node ./scripts/setup-wasm.mjs` to copy it into your `node_modules`. Run next with `NODE_OPTIONS='--no-addons'` to force it to use the wasm binary. + +If you need to clean the project for any reason, use `pnpm clean`. diff --git a/contributing/core/developing-using-local-app.md b/contributing/core/developing-using-local-app.md new file mode 100644 index 000000000000000..bb7a5e51c35f26f --- /dev/null +++ b/contributing/core/developing-using-local-app.md @@ -0,0 +1,50 @@ +# Developing Using Your Local Version of Next.js + +There are two options to develop with your local version of the codebase: + +## Develop inside the monorepo + +This will use the version of `next` built inside of the Next.js monorepo. You can also let `pnpm dev` run in a separate terminal. This will let you make changes to Next.js at the same time (note that some changes might require re-running `pnpm next-with-deps` or `pnpm next`). + +If your app does not have dependencies, you can create a directory inside the monorepo (eg.: `dev-app`) and run `pnpm next ./dev-app` without creating a `package.json` file. + +If you already have an app and it has dependencies, you can follow these steps: + +1. Move your app inside of the Next.js monorepo. + +2. Run with `pnpm next-with-deps ./app-path-in-monorepo` + +## Set as a local dependency in package.json + +1. Run `pnpm dev` in the background in the Next.js monorepo. + +2. In your app's root directory, run: + + ```sh + pnpm add ./path/to/next.js/{packages/next,node_modules/{react,react-dom}} + ``` + + to re-install all of the dependencies and point `next`, `react` and `react-dom` to the monorepo versions. + + Note that Next.js will be copied from the locally compiled version as opposed to being downloaded from the NPM registry. + +3. Run your application as you normally would. + +### Troubleshooting + +- If you see the below error while running `pnpm dev` with `next`: + +``` +Failed to load SWC binary, see more info here: https://nextjs.org/docs/messages/failed-loading-swc +``` + +Try to add the below section to your `package.json`, then run again + +```json +"optionalDependencies": { + "@next/swc-linux-x64-gnu": "canary", + "@next/swc-win32-x64-msvc": "canary", + "@next/swc-darwin-x64": "canary", + "@next/swc-darwin-arm64": "canary" +}, +``` diff --git a/contributing/core/developing.md b/contributing/core/developing.md new file mode 100644 index 000000000000000..09e60062198b004 --- /dev/null +++ b/contributing/core/developing.md @@ -0,0 +1,44 @@ +# Developing + +- The development branch is `canary`. +- All pull requests should be opened against `canary`. +- The changes on the `canary` branch are published to the `@canary` tag on npm regularly. + +To develop locally: + +1. Install the [GitHub CLI](https://github.com/cli/cli#installation). +1. Clone the Next.js repository: + ``` + gh repo clone vercel/next.js` + ``` +1. Create a new branch: + ``` + git checkout -b MY_BRANCH_NAME origin/canary + ``` +1. Enable pnpm: + ``` + corepack enable pnpm + ``` +1. Install the dependencies with: + ``` + pnpm install + ``` +1. Start developing and watch for code changes: + ``` + pnpm dev + ``` +1. In a new terminal, run `pnpm types` to compile declaration files from + TypeScript. + _Note: You may need to repeat this step if your types get outdated._ +1. When you changes are finished commit them to the branch: + ``` + git add . + git commit -m "DESCRIBE_YOUR_CHANGES_HERE" + ``` +1. To open a pull request you can use the GitHub CLI which automatically forks and sets up a remote branch. Follow the prompts when running: + ``` + gh pr create + ``` + +For instructions on how to build a project with your local version of the CLI, +see **[Developing Using Your Local Version of Next.js](./developing-using-local-app.md)** as linking the package is not sufficient to develop locally. diff --git a/contributing/core/testing.md b/contributing/core/testing.md new file mode 100644 index 000000000000000..5f197ef5177bef4 --- /dev/null +++ b/contributing/core/testing.md @@ -0,0 +1,63 @@ +# Testing + +## Running tests + +We recommend running the tests in headless mode (with the browser windows hidden) and with a specific directory pattern and/or test name (`-t`) which ensures only a small part of the test suite is run locally: + +For example, running one test in the production test suite: + +Running one test in the `test/integration/production` test suite: + +```sh +pnpm testheadless test/integration/production/ -t "should allow etag header support" +``` + +Running all tests in the `test/integration/production` test suite: + +```sh +pnpm testheadless test/integration/production/ +``` + +When you want to debug a particular test you can replace `pnpm testheadless` with `pnpm testonly` to opt out of the headless browser. +When the test runs it will open the browser that is in the background by default, allowing you to inspect what is on the screen. + +```sh +pnpm testonly test/integration/production/ -t "should allow etag header support" +``` + +## Writing tests for Next.js + +### Getting Started + +You can set up a new test using `pnpm new-test` which will start from a template related to the test type. + +### Test Types in Next.js + +- e2e: Runs against `next dev`, `next start`, and deployed to Vercel. +- development: Runs against `next dev`. +- production: Runs against `next start`. +- integration: Historical location of tests. Runs misc checks and modes. Ideally, we don't add new test suites here anymore as these tests are not isolated from the monorepo. +- unit: Very fast tests that should run without a browser or run `next` and should be testing a specific utility. + +For the e2e, development, and production tests the `createNext` utility should be used and an example is available [here](../../test/e2e/example.txt). This creates an isolated Next.js install to ensure nothing in the monorepo is relied on accidentally causing incorrect tests. + +All new test suites should be written in TypeScript either `.ts` (or `.tsx` for unit tests). This will help ensure we catch smaller issues in tests that could cause flakey or incorrect tests. + +If a test suite already exists that relates closely to the item being tested (e.g. hash navigation relates to existing navigation test suites) the new checks can be added to the existing test suite. + +### Best Practices + +- When checking for a condition that might take time, ensure it is waited for either using the browser `waitForElement` or using the `check` util in `next-test-utils`. +- When applying a fix, ensure the test fails without the fix. This makes sure the test will properly catch regressions. + +### Helpful environment variables + +Some test-specific environment variables can be used to help debug isolated tests better, these can be leveraged by prefixing the `pnpm test` command. + +- When investigating failures in isolated tests you can use `NEXT_TEST_SKIP_CLEANUP=1` to prevent deleting the temp folder created for the test, then you can run `pnpm next` while inside of the temp folder to debug the fully set-up test project. +- You can also use `NEXT_SKIP_ISOLATE=1` if the test doesn't need to be installed to debug and it will run inside of the Next.js repo instead of the temp directory, this can also reduce test times locally but is not compatible with all tests. +- The `NEXT_TEST_MODE` env variable allows toggling specific test modes for the `e2e` folder, it can be used when not using `pnpm test-dev` or `pnpm test-start` directly. Valid test modes can be seen here: https://github.com/vercel/next.js/blob/aa664868c102ddc5adc618415162d124503ad12e/test/lib/e2e-utils.ts#L46 + +### Debugging + +When tests are run in CI and a test failure occurs we attempt to capture traces of the playwright run to make debugging the failure easier. A test-trace artifact should be uploaded after the workflow completes which can be downloaded, unzipped, and then inspected with `pnpm playwright show-trace ./path/to/trace` diff --git a/contributing/core/vscode-debugger.md b/contributing/core/vscode-debugger.md new file mode 100644 index 000000000000000..d240b0af040bb1e --- /dev/null +++ b/contributing/core/vscode-debugger.md @@ -0,0 +1,27 @@ +# Using the VS Code Debugger + +## Debug configurations + +The Next.js monorepo provides configurations in the [`.vscode/launch.json`](../../.vscode/launch.json) file to help you [debug Next.js from VS Code](https://code.visualstudio.com/docs/editor/debugging). + +The common configurations are: + +- Launch app development: Run `next dev` with an attached debugger +- Launch app build: Run `next build` with an attached debugger +- Launch app production: Run `next start` with an attached debugger + +### Run a specific app + +Any Next.js app inside the monorepo can be debugged with these configurations. For example to run "Launch app development" against `examples/hello-world`: + +1. Open the [`.vscode/launch.json`](../../.vscode/launch.json) file. +2. Find the configuration "Launch app development". +3. Edit the `runtimeArgs` array's last item to be `"examples/hello-world"`. +4. Save the file. +5. Now you can start the debugger and it will run against the `examples/hello-world` app! + +To see the changes you make to the Next.js codebase during development, you can run `pnpm dev` in the root directory, which will watch for file changes in `packages/next` and recompile the Next.js source code on any file saves. + +## Breakpoints + +When developing/debugging Next.js, you can set breakpoints anywhere in the `packages/next` source code that will stop the debugger at certain locations so you can examine the behavior. Read more about [breakpoints in the VS Code documentation](https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_breakpoints). diff --git a/contributing/docs/adding-documentation.md b/contributing/docs/adding-documentation.md new file mode 100644 index 000000000000000..cb7b3614c25bc33 --- /dev/null +++ b/contributing/docs/adding-documentation.md @@ -0,0 +1,40 @@ +# Updating Documentation Paths + +Our documentation currently leverages a [manifest file](/docs/manifest.json) which is how documentation entries are checked. + +When adding a new entry under an existing category you only need to add an entry with `{title: '', path: '/docs/path/to/file.md'}`. The "title" is what is shown on the sidebar. + +When moving the location/url of an entry the "title" field can be removed from the existing entry and the ".md" extension removed from the "path", then a "redirect" field with the shape of `{permanent: true/false, destination: '/some-url'}` can be added. A new entry should be added with the "title" and "path" fields if the document was renamed within the [`docs` folder](/docs) that points to the new location in the folder e.g. `/docs/some-url.md` + +Example of moving documentation file: + +Before: + +```json +[ + { + "path": "/docs/original.md", + "title": "Hello world" + } +] +``` + +After: + +```json +[ + { + "path": "/docs/original", + "redirect": { + "permanent": false, + "destination": "/new" + } + } + { + "path": "/docs/new.md", + "title": "Hello world" + }, +] +``` + +Note: the manifest is checked automatically in the "lint" step in CI when opening a PR. diff --git a/contributing/examples/adding-examples.md b/contributing/examples/adding-examples.md new file mode 100644 index 000000000000000..180d34f5446b32d --- /dev/null +++ b/contributing/examples/adding-examples.md @@ -0,0 +1,57 @@ +## Adding examples + +When you add an example to the [examples](examples) directory, please follow these guidelines to ensure high-quality examples: + +- TypeScript should be leveraged for new examples (no need for separate JavaScript and TypeScript examples, converting old JavaScript examples is preferred) +- Examples should not add custom ESLint configuration (we have specific templates for ESLint) +- If API routes aren't used in an example, they should be omitted +- If an example exists for a certain library and you would like to showcase a specific feature of that library, the existing example should be updated (instead of adding a new example) +- Package manager specific config should not be added (e.g. `resolutions` in `package.json`) +- In `package.json` the version of `next` (and `eslint-config-next`) should be `latest` +- In `package.json` the dependency versions should be up-to-date +- Use `export default function` for page components and API Routes instead of `const`/`let` (The exception is if the page has `getInitialProps`, in which case [`NextPage`](https://nextjs.org/docs/api-reference/data-fetching/get-initial-props#typescript) could be useful) +- CMS example directories should be prefixed with `cms-` +- Example directories should not be prefixed with `with-` +- Make sure linting passes (you can run `pnpm lint-fix`) + +Also, don’t forget to add a `README.md` file with the following format: + +- Replace `DIRECTORY_NAME` with the directory name you’re adding. +- Fill in `Example Name` and `Description`. +- Examples should be TypeScript first, if possible. +- Omit the `name` and `version` fields from your `package.json`. +- Ensure all your dependencies are up to date. +- Ensure you’re using [`next/image`](https://nextjs.org/docs/api-reference/next/image). +- To add additional installation instructions, please add it where appropriate. +- To add additional notes, add `## Notes` section at the end. +- Remove the `Deploy your own` section if your example can’t be immediately deployed to Vercel. + +````markdown +# Example Name + +Description + +## 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/DIRECTORY_NAME&project-name=DIRECTORY_NAME&repository-name=DIRECTORY_NAME) + +## 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), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example: + +```bash +npx create-next-app --example DIRECTORY_NAME DIRECTORY_NAME-app +``` + +```bash +yarn create next-app --example DIRECTORY_NAME DIRECTORY_NAME-app +``` + +```bash +pnpm create next-app --example DIRECTORY_NAME DIRECTORY_NAME-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/contributing/examples/run-example-apps.md b/contributing/examples/run-example-apps.md new file mode 100644 index 000000000000000..c95c20cd35a5ccf --- /dev/null +++ b/contributing/examples/run-example-apps.md @@ -0,0 +1,22 @@ +# Running Example Apps + +Running examples can be done with: + +```sh +pnpm next ./examples/basic-css/ +``` + +To figure out which pages are available for the given example, you can run: + +```sh +EXAMPLE=./test/integration/basic +(\ + cd $EXAMPLE/pages; \ + find . -type f \ + | grep -v '\.next' \ + | sed 's#^\.##' \ + | sed 's#index\.js##' \ + | sed 's#\.js$##' \ + | xargs -I{} echo localhost:3000{} \ +) +``` diff --git a/contributing/repository/linting.md b/contributing/repository/linting.md new file mode 100644 index 000000000000000..513797ce7e280fc --- /dev/null +++ b/contributing/repository/linting.md @@ -0,0 +1,37 @@ +# Linting + +The Next.js repository runs [ESLint](https://eslint.org), [Prettier](https://prettier.io) and [alex](https://alexjs.com) to lint and format all code and documentation. + +To lint all code you can run: + +```sh +pnpm lint +``` + +If you get errors, you can run the ESLint and Prettier auto-fix using: + +```sh +pnpm lint-fix +``` + +Not all rules can be auto-fixed, those require manual changes. + +If you get a warning by alex, follow the instructions to correct the language. + +## ESLint + +We recommend installing the [ESLint plugin for VS Code](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint). + +You can find the enabled rules in the [ESLint config](../../.eslintrc.json). + +## Prettier + +We recommend installing the [Prettier plugin for VS Code](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode). + +You can find the format configuration in the [Prettier config](../../.prettierrc.json). + +## alex + +We recommend installing the [AlexJS Linter extension for VSCode](https://marketplace.visualstudio.com/items?itemName=TLahmann.alex-linter) + +You can find the configuration in the [alex config](../../.alexrc). diff --git a/contributing/repository/pull-request-descriptions.md b/contributing/repository/pull-request-descriptions.md new file mode 100644 index 000000000000000..ab217c271b0d4bf --- /dev/null +++ b/contributing/repository/pull-request-descriptions.md @@ -0,0 +1,7 @@ +# Pull Request Descriptions + +Pull Requests opened against the repository have a default template to guide you in creating a descriptive explanation of what the PR is for. + +Please make sure to explain the purpose and link any related issues. + +Check out the [`pull_request_template.md`](../../.github/pull_request_template.md) for more details. diff --git a/contributing/repository/release-channels-publishing.md b/contributing/repository/release-channels-publishing.md new file mode 100644 index 000000000000000..8eb4dce091f4341 --- /dev/null +++ b/contributing/repository/release-channels-publishing.md @@ -0,0 +1,25 @@ +# Release Channels and Publishing + +Next.js has two release channels: `stable` and `canary`. + +## Stable + +The stable release is what is installed when you `npm install next`. This channel is used by the majority of Next.js users. + +This channel is published at a regular cadence and follows [semantic versioning](https://semver.org). + +Repository maintainers can publish a new stable version using: `pnpm publish-stable`. +The command will ask what version to publish `major`, `minor`, or `patch`. + +## Canary + +The canary channel has to be explicitly installed by users through `npm install next@canary`. + +This channel is published early based on the `canary` branch. It holds all changes that are waiting to be published to the stable channel. + +`canary` is used to test the latest features and bugfixes on real-world applications. + +By installing `next@canary` from time to time you can check if your application is affected by any changes that have not been published yet. + +Repository maintainers can publish a new canary version using: `pnpm publish-canary`. +The command will automatically decide the new version tag as it's an increment from the previous version. diff --git a/contributing/repository/triaging.md b/contributing/repository/triaging.md new file mode 100644 index 000000000000000..71eb1636c63fac1 --- /dev/null +++ b/contributing/repository/triaging.md @@ -0,0 +1,21 @@ +# Triaging + +Repository maintainers triage every issue and PR opened in the repository. + +Issues are opened with one of these labels: + +- `template: story` - a feature request, converted to an [💡 Ideas discussion](https://github.com/vercel/next.js/discussions/categories/ideas) +- `template: bug` - unverified issue with Next.js itself, or one of the examples in the [`examples`](https://github.com/vercel/next.js/tree/canary/examples) folder +- `template: documentation` - feedback for improvement or an unverified issue with the Next.js documentation + +In the case of a bug report, a maintainer looks at the provided reproduction. If the reproduction is missing or insufficient, a `please add a complete reproduction` label is added. If a reproduction is not provided for more than 30 days, the issue becomes stale and will be automatically closed. If a reproduction is provided within 30 days, the `please add a complete reproduction` label is removed and the issue will not become stale anymore. + +Bug reports must be verified against the `next@canary` release. 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 before opening a new issue. Issues not verified against `next@canary` will be closed after 30 days. + +If the issue is specific to the project and not to Next.js itself, it might be converted to a [🎓️ Help discussion](https://github.com/vercel/next.js/discussions/categories/help) + +If the bug is verified, it will receive the `kind: bug` label and will be tracked by the maintainers. An `area:` label can be added to indicate which part of Next.js is affected. + +Confirmed issues never become stale or are closed before resolution. + +All **closed** PRs and Issues will be locked after 30 days of inactivity (eg.: comment, referencing from elsewhere). diff --git a/errors/template.txt b/errors/template.txt index 3aa3e131acac519..5905279b8626637 100644 --- a/errors/template.txt +++ b/errors/template.txt @@ -4,10 +4,14 @@ +{{why}} + #### Possible Ways to Fix It +{{fix}} + ### Useful Links diff --git a/package.json b/package.json index 4703f015ee00bbd..019ab72308b514d 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "test-dev": "cross-env NEXT_TEST_MODE=dev pnpm testheadless", "test-start": "cross-env NEXT_TEST_MODE=start pnpm testheadless", "test-deploy": "cross-env NEXT_TEST_MODE=deploy pnpm testheadless", + "test": "cross-env HEADLESS=true pnpm testonly", "testonly": "pnpm jest --runInBand", "testheadless": "cross-env HEADLESS=true pnpm testonly", "genstats": "cross-env LOCAL_STATS=true node .github/actions/next-stats-action/src/index.js", diff --git a/packages/next/bundles/webpack/packages/webpack.js b/packages/next/bundles/webpack/packages/webpack.js index e4eccb4b126a3a4..11c019e0d676343 100644 --- a/packages/next/bundles/webpack/packages/webpack.js +++ b/packages/next/bundles/webpack/packages/webpack.js @@ -3,7 +3,7 @@ exports.__esModule = true exports.default = undefined exports.init = function () { - if (process.env.NEXT_PRIVATE_LOCAL_webpack) { + if (process.env.NEXT_PRIVATE_LOCAL_WEBPACK) { Object.assign(exports, { // eslint-disable-next-line import/no-extraneous-dependencies BasicEvaluatedExpression: require('webpack/lib/javascript/BasicEvaluatedExpression'), diff --git a/packages/next/compiled/webpack/webpack.js b/packages/next/compiled/webpack/webpack.js index e4eccb4b126a3a4..11c019e0d676343 100644 --- a/packages/next/compiled/webpack/webpack.js +++ b/packages/next/compiled/webpack/webpack.js @@ -3,7 +3,7 @@ exports.__esModule = true exports.default = undefined exports.init = function () { - if (process.env.NEXT_PRIVATE_LOCAL_webpack) { + if (process.env.NEXT_PRIVATE_LOCAL_WEBPACK) { Object.assign(exports, { // eslint-disable-next-line import/no-extraneous-dependencies BasicEvaluatedExpression: require('webpack/lib/javascript/BasicEvaluatedExpression'), diff --git a/plopfile.js b/plopfile.js index 44cbe6eec120d2b..e8277c7bb19f428 100644 --- a/plopfile.js +++ b/plopfile.js @@ -50,14 +50,29 @@ module.exports = function (plop) { plop.setGenerator('error', { description: 'Create a new error document', prompts: [ + { + name: 'urlPath', + type: 'input', + message: 'Url path with dashes. E.g. circular-structure', + }, { name: 'title', type: 'input', - message: 'Title for the error', + message: 'Title for the error. E.g. Circular Structure', + }, + { + name: 'why', + type: 'input', + message: 'What caused the error to happen?', + }, + { + name: 'fix', + type: 'input', + message: 'What are the possible ways to fix it?', }, ], actions: function (data) { - const fileName = getFileName(data.title) + const fileName = getFileName(data.urlPath) return [ { type: 'add', @@ -76,6 +91,7 @@ module.exports = function (plop) { return JSON.stringify(manifestData, null, 2) }, }, + `Url for the error: https://nextjs.org/docs/messages/${fileName}`, ] }, }) diff --git a/scripts/run-for-change.js b/scripts/run-for-change.js index 7b7475c802f09ee..846a20c98440fe7 100644 --- a/scripts/run-for-change.js +++ b/scripts/run-for-change.js @@ -11,6 +11,7 @@ const CHANGE_ITEM_GROUPS = { 'examples', 'UPGRADING.md', 'contributing.md', + 'contributing', 'CODE_OF_CONDUCT.md', 'readme.md', ], diff --git a/test/readme.md b/test/readme.md index b9c28639e55f513..dd1c42796809687 100644 --- a/test/readme.md +++ b/test/readme.md @@ -1,36 +1 @@ -# Writing tests for Next.js - -## Getting Started - -You can set-up a new test using `pnpnm new-test` which will start from a template related to the test type. - -## Test Types in Next.js - -- e2e: These tests will run against `next dev`, `next start`, and deployed to Vercel -- development: These tests only run against `next dev` -- production: These tests will run against `next start`. -- integration: These tests run misc checks and modes and is where tests used to be added before we added more specific folders. Ideally we don't add new test suites here as tests here are not isolated from the monorepo. -- unit: These are very fast tests that should run without a browser or running next and should be testing a specific utility. - -For the e2e, production, and development tests the `createNext` utility should be used and an example is available [here](./e2e/example.txt). This creates an isolated Next.js install to ensure nothing in the monorepo is relied on accidentally causing incorrect tests. - -All new test suites should be written in TypeScript either `.ts` (or `.tsx` for unit tests). This will help ensure we catch smaller issues in tests that could cause flakey or incorrect tests. - -If a test suite already exists that relates closely to the item being tested (e.g. hash navigation relates to existing navigation test suites) the new checks can be added in the existing test suite. - -## Best Practices - -- When checking for a condition that might take time, ensure it is waited for either using the browser `waitForElement` or using the `check` util in `next-test-utils`. -- When applying a fix, ensure the test fails without the fix. This makes sure the test will properly catch regressions. - -## Helpful environment variables - -There are some test specific environment variables that can be used to help debug isolated tests better, these can be leveraged by prefixing the `pnpm testheadless` command. - -- When investigating failures in isolated tests you can use `NEXT_TEST_SKIP_CLEANUP=1` to prevent deleting the temp folder created for the test, then you can run `pnpm next` while inside of the temp folder to debug the fully setup test project. -- You can also use `NEXT_SKIP_ISOLATE=1` if the test doesn't need to be installed to debug and it will run inside of the Next.js repo instead of the temp directory, this can also reduce test times locally but is not compatible with all tests. -- The `NEXT_TEST_MODE` env variable allows toggling specific test modes for the `e2e` folder, it can be used when not using `pnpm test-dev` or `pnpm test-start` directly. Valid test modes can be seen here: https://github.com/vercel/next.js/blob/aa664868c102ddc5adc618415162d124503ad12e/test/lib/e2e-utils.ts#L46 - -## Debugging - -When tests are run in CI and a test failure occurs we attempt to capture traces of the playwright run to make debugging the failure easier. A test-trace artifact should be uploaded after the workflow completes which can be downloaded, unzipped, and then inspected with `pnpm playwright show-trace ./path/to/trace` +See [Testing](../contributing/core/testing.md) for more information on how you can run/write/debug tests for Next.js.