Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ESLint] Introduce a new setup process when next lint is run for the first time #26584

Merged
merged 15 commits into from
Aug 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 55 additions & 49 deletions docs/basic-features/eslint.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,63 +18,67 @@ Then run `npm run lint` or `yarn lint`:
yarn lint
```

If you don't already have ESLint configured in your application, you will be guided through the installation of the required packages.
If you don't already have ESLint configured in your application, you will be guided through the installation and configuration process.

```bash
yarn lint

# You'll see instructions like these:
# You'll see a prompt like this:
#
# Please install eslint and eslint-config-next by running:
# ? How would you like to configure ESLint?
#
# yarn add --dev eslint eslint-config-next
#
# ...
# Base configuration + Core Web Vitals rule-set (recommended)
# Base configuration
# None
```

If no ESLint configuration is present, Next.js will create an `.eslintrc` file in the root of your project and automatically configure it with the base configuration:
One of the following three options can be selected:

```js
{
"extends": "next"
}
```
- **Strict**: Includes Next.js' base ESLint configuration along with a stricter [Core Web Vitals rule-set](/docs/basic-features/eslint.md#core-web-vitals). This is the recommended configuration for developers setting up ESLint for the first time.

You can now run `next lint` every time you want to run ESLint to catch errors.
```json
{
"extends": "next/core-web-vitals"
}
```

> The default base configuration (`"extends": "next"`) can be updated at any time and will only be included if no ESLint configuration is present.
- **Base**: Includes Next.js' base ESLint configuration.

We recommend using an appropriate [integration](https://eslint.org/docs/user-guide/integrations#editors) to view warnings and errors directly in your code editor during development.
```json
{
"extends": "next"
}
```

## Linting During Builds
- **Cancel**: Does not include any ESLint configuration. Only select this option if you plan on setting up your own custom ESLint configuration.

Once ESLint has been set up, it will automatically run during every build (`next build`). Errors will fail the build, while warnings will not.
If either of the two configuration options are selected, Next.js will automatically install `eslint` and `eslint-config-next` as development dependencies in your application and create an `.eslintrc.json` file in the root of your project that includes your selected configuration.

If you do not want ESLint to run as a build step, refer to the documentation for [Ignoring ESLint](/docs/api-reference/next.config.js/ignoring-eslint.md):
You can now run `next lint` every time you want to run ESLint to catch errors. Once ESLint has been set up, it will also automatically run during every build (`next build`). Errors will fail the build, while warnings will not.

## Linting Custom Directories
> If you do not want ESLint to run during `next build`, refer to the documentation for [Ignoring ESLint](/docs/api-reference/next.config.js/ignoring-eslint.md).

By default, Next.js will run ESLint for all files in the `pages/`, `components/`, and `lib/` directories. However, you can specify which directories using the `dirs` option in the `eslint` config in `next.config.js`:
We recommend using an appropriate [integration](https://eslint.org/docs/user-guide/integrations#editors) to view warnings and errors directly in your code editor during development.

```js
module.exports = {
eslint: {
dirs: ['pages', 'utils'], // Only run ESLint on the 'pages' and 'utils' directories (next build and next lint)
},
}
```
## ESLint Config

Also, the `--dir` flag can be used for `next lint`:
The default configuration (`eslint-config-next`) includes everything you need to have an optimal out-of-the-box linting experience in Next.js. If you do not have ESLint already configured in your application, we recommend using `next lint` to set up ESLint along with this configuration.

```bash
yarn lint --dir pages --dir utils
```
> If you would like to use `eslint-config-next` along with other ESLint configurations, refer to the [Additional Configurations](/docs/basic-features/eslint.md#additional-configurations) section to learn how to do so without causing any conflicts.

Recommended rule-sets from the following ESLint plugins are all used within `eslint-config-next`:

- [`eslint-plugin-react`](https://www.npmjs.com/package/eslint-plugin-react)
- [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks)
- [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-next)

You can see the full details of the shareable configuration in the [`eslint-config-next`](https://www.npmjs.com/package/eslint-config-next) package.

This will take precedence over the configuration from `next.config.js`.

## ESLint Plugin

Next.js provides an ESLint plugin, [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-next), making it easier to catch common issues and problems in a Next.js application. The full set of rules is as follows:
Next.js provides an ESLint plugin, [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-next), already bundled within the base configuration that makes it possible to catch common issues and problems in a Next.js application. The full set of rules is as follows:

| | Rule | Description |
| :-: | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
Expand All @@ -94,34 +98,36 @@ Next.js provides an ESLint plugin, [`eslint-plugin-next`](https://www.npmjs.com/

- ✔: Enabled in the recommended configuration

## Base Configuration
If you already have ESLint configured in your application, we recommend extending from this plugin directly instead of including `eslint-config-next` unless a few conditions are met. Refer to the [Recommended Plugin Ruleset](/docs/basic-features/eslint.md#recommended-plugin-ruleset) to learn more.

The Next.js base ESLint configuration is automatically generated when `next lint` is run for the first time:
## Linting Custom Directories

By default, Next.js will run ESLint for all files in the `pages/`, `components/`, and `lib/` directories. However, you can specify which directories using the `dirs` option in the `eslint` config in `next.config.js` for production builds:

```js
{
"extends": "next"
module.exports = {
eslint: {
dirs: ['pages', 'utils'], // Only run ESLint on the 'pages' and 'utils' directories during production builds (next build)
},
}
```

This configuration extends recommended rule sets from various ESLint plugins:

- [`eslint-plugin-react`](https://www.npmjs.com/package/eslint-plugin-react)
- [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks)
- [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-next)
Similarly, the `--dir` flag can be used for `next lint`:

You can see the full details of the shareable configuration in the [`eslint-config-next`](https://www.npmjs.com/package/eslint-config-next) package.
```bash
next lint --dir pages --dir utils
```

## Disabling Rules

If you would like to modify or disable any rules provided by the supported plugins (`react`, `react-hooks`, `next`), you can directly change them using the `rules` property in your `.eslintrc`:

```js
```json
{
"extends": "next",
"rules": {
"react/no-unescaped-entities": "off",
"@next/next/no-page-custom-font": "off",
"@next/next/no-page-custom-font": "off"
}
}
```
Expand All @@ -140,23 +146,23 @@ If you would like to modify or disable any rules provided by the supported plugi

### Core Web Vitals

A stricter `next/core-web-vitals` rule set can also be added in `.eslintrc`:
The `next/core-web-vitals` rule set is enabled when `next lint` is run for the first time and the **strict** option is selected.

```
```json
{
"extends": ["next", "next/core-web-vitals"]
"extends": "next/core-web-vitals"
}
```

`next/core-web-vitals` updates `eslint-plugin-next` to error on a number of rules that are warnings by default if they affect [Core Web Vitals](https://web.dev/vitals/).

> Both `next` and `next/core-web-vitals` entry points are automatically included for new applications built with [Create Next App](/docs/api-reference/create-next-app.md).
> The `next/core-web-vitals` entry point is automatically included for new applications built with [Create Next App](/docs/api-reference/create-next-app.md).

## Usage with Prettier

ESLint also contains code formatting rules, which can conflict with your existing [Prettier](https://prettier.io/) setup. We recommend including [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) in your ESLint config to make ESLint and Prettier work together.

```js
```json
{
"extends": ["next", "prettier"]
}
Expand Down
2 changes: 1 addition & 1 deletion packages/create-next-app/create-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ export async function createApp({
rename: (name) => {
switch (name) {
case 'gitignore':
case 'eslintrc': {
case 'eslintrc.json': {
styfle marked this conversation as resolved.
Show resolved Hide resolved
return '.'.concat(name)
}
// README.md is ignored by webpack-asset-relocator-loader used by ncc:
Expand Down
3 changes: 0 additions & 3 deletions packages/create-next-app/templates/default/eslintrc

This file was deleted.

3 changes: 3 additions & 0 deletions packages/create-next-app/templates/default/eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
3 changes: 0 additions & 3 deletions packages/create-next-app/templates/typescript/eslintrc

This file was deleted.

3 changes: 3 additions & 0 deletions packages/create-next-app/templates/typescript/eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
10 changes: 8 additions & 2 deletions packages/next/cli/next-lint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const nextLint: cliCommand = async (argv) => {
'--help': Boolean,
'--base-dir': String,
'--dir': [String],
'--strict': Boolean,

// Aliases
'-h': '--help',
Expand Down Expand Up @@ -100,6 +101,9 @@ const nextLint: cliCommand = async (argv) => {
--ext [String] Specify JavaScript file extensions - default: .js, .jsx, .ts, .tsx
--resolve-plugins-relative-to path::String A folder where plugins should be resolved from, CWD by default

Initial setup:
--strict Creates an .eslintrc.json file using the Next.js strict configuration (only possible if no .eslintrc.json file is present)

Specifying rules:
--rulesdir [path::String] Use additional rules from this directory

Expand Down Expand Up @@ -156,6 +160,7 @@ const nextLint: cliCommand = async (argv) => {
const reportErrorsOnly = Boolean(args['--quiet'])
const maxWarnings = args['--max-warnings'] ?? -1
const formatter = args['--format'] || null
const strict = Boolean(args['--strict'])

runLintCheck(
baseDir,
Expand All @@ -164,7 +169,8 @@ const nextLint: cliCommand = async (argv) => {
eslintOptions(args),
reportErrorsOnly,
maxWarnings,
formatter
formatter,
strict
)
.then(async (lintResults) => {
const lintOutput =
Expand Down Expand Up @@ -193,7 +199,7 @@ const nextLint: cliCommand = async (argv) => {

if (lintOutput) {
console.log(lintOutput)
} else {
} else if (lintResults && !lintOutput) {
console.log(chalk.green('✔ No ESLint warnings or errors'))
}
})
Expand Down
21 changes: 21 additions & 0 deletions packages/next/compiled/cli-select/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2018 Cyril Wanner

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
1 change: 1 addition & 0 deletions packages/next/compiled/cli-select/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/next/compiled/cli-select/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"cli-select","main":"index.js","author":"Cyril Wanner <[email protected]>","license":"MIT"}
21 changes: 21 additions & 0 deletions packages/next/compiled/cross-spawn/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2018 Made With MOXY Lda <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Loading