Skip to content

Commit

Permalink
feat!: update typescript-eslint dependency to v8
Browse files Browse the repository at this point in the history
Closes #1
Closes #2
  • Loading branch information
Kenneth-Sills authored Aug 25, 2024
1 parent d088c1e commit 932dea1
Show file tree
Hide file tree
Showing 6 changed files with 512 additions and 337 deletions.
5 changes: 5 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
const stylisticPlugin = require('@stylistic/eslint-plugin');

module.exports = {
extends: ['eslint-config-airbnb-base', './base.js', 'prettier'],
parserOptions: {
project: './tsconfig.json',
},
rules: Object.fromEntries(
Object.keys(stylisticPlugin.configs['all-flat'].rules ?? {}).map((key) => [key, 'off']),
),
};
195 changes: 126 additions & 69 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,121 +2,178 @@

[![Version](https://img.shields.io/npm/v/eslint-config-airbnb-typescript.svg?style=flat-square)](https://www.npmjs.com/package/eslint-config-airbnb-typescript?activeTab=versions) [![Downloads](https://img.shields.io/npm/dt/eslint-config-airbnb-typescript.svg?style=flat-square)](https://www.npmjs.com/package/eslint-config-airbnb-typescript) [![Last commit](https://img.shields.io/github/last-commit/iamturns/eslint-config-airbnb-typescript.svg?style=flat-square)](https://github.com/iamturns/eslint-config-airbnb-typescript/graphs/commit-activity) [![Build](https://img.shields.io/circleci/project/github/iamturns/eslint-config-airbnb-typescript/master.svg?style=flat-square)](https://circleci.com/gh/iamturns/eslint-config-airbnb-typescript) [![License](https://img.shields.io/github/license/iamturns/eslint-config-airbnb-typescript.svg?style=flat-square)](https://github.com/iamturns/eslint-config-airbnb-typescript/blob/master/LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/iamturns/eslint-config-airbnb-typescript/blob/master/CONTRIBUTING.md) [![Code of conduct](https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square)](https://github.com/iamturns/eslint-config-airbnb-typescript/blob/master/CODE_OF_CONDUCT.md)

Enhances Airbnb's ESLint config with TypeScript support
Enhances [Airbnb's ESLint config](https://www.npmjs.com/package/eslint-config-airbnb) with TypeScript support.

> [!WARNING]
> We currently **do not** support ESLint v9 or above. Please see issue #331 to track progress.
## Setup

### 1) Setup regular Airbnb config
### Installation

Start by installing both ESLint and Typescript in your project. Afterwards, you can install this config through your favorite package manager normally:

Make sure you have the regular Airbnb config setup. If you are using React, use [eslint-config-airbnb](https://www.npmjs.com/package/eslint-config-airbnb), or if you aren't using React, use [eslint-config-airbnb-base](https://www.npmjs.com/package/eslint-config-airbnb-base).
```sh
npm install -D eslint-config-airbnb-typescript
```

### 2) Install dependencies (and peer dependencies)
If you're using React, you'll also need to install the appropriate Airbnb rules separately:

```bash
npm install eslint-config-airbnb-typescript \
@typescript-eslint/eslint-plugin@^7.0.0 \
@typescript-eslint/parser@^7.0.0 \
--save-dev
```sh
npm install -D eslint-config-airbnb
```

### 3) Configure ESLint
> [!NOTE]
> While current versions of NPM will automatically install peer dependencies, if you're using a version of NPM prior to v7, you will need to install them manually instead:
>
> ```sh
> npm install -D \
> eslint@^8.56 \
> eslint-config-airbnb-base \
> @stylistic/eslint-plugin \
> @typescript-eslint/eslint-plugin@^8 \
> @typescript-eslint/parser@^8
> ```
Within your ESLint config file:
### Configuration
```diff
extends: [
'airbnb',
+ 'airbnb-typescript'
]
```
Next, tell ESLint to extend from this configuration. And since we need to access type information, a `tsconfig.json` and some setup for [`@typescript-eslint/parser`](https://typescript-eslint.io/packages/parser/) to recognize it are required.
If you don't need React support:
> [!IMPORTANT]
> These instructions assume you are on the current LTS version of Node. If you are using a Node version older than v20, you will need to update any references to `import.meta.dirname` to use [a `__dirname` workaround](https://github.com/iamturns/eslint-config-airbnb-typescript/issues/307#issuecomment-2153373493) instead.
```diff
extends: [
'airbnb-base',
+ 'airbnb-typescript/base'
]
#### Recommended - Flat Config
Since we don't yet have first-class support for the new flat configuration format (see #307 for progress), [ESLint's compatability utility](https://www.npmjs.com/package/@eslint/eslintrc) is needed:
```sh
npm install -D @eslint/eslintrc
```
### 4) Configure the ESLint TypeScript parser
Then you'll want to set up your `eslint.config.js` something like this:

```js
import { FlatCompat } from '@eslint/eslintrc';

const compat = new FlatCompat({
baseDirectory: import.meta.dirname,
});

export default [
// Without React
...compat.extends('airbnb-base'),
...compat.extends('airbnb-typescript/base'),

// With React
...compat.extends('airbnb'),
...compat.extends('airbnb-typescript'),

// Either way
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
];
```

This config requires knowledge of your TypeScript config.
#### Legacy Config

In your ESLint config, set [parserOptions.project](https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/parser#parseroptionsproject) to the path of your `tsconfig.json`.
If you're stuck on the legacy `.eslintrc` format, you'll want to set up your `.eslintrc.js` similar to this:

For example:
```js
module.exports = {
extends: [
// Without React
'airbnb-base',
'airbnb-typescript/base'

```diff
{
extends: ['airbnb', 'airbnb-typescript'],
+ parserOptions: {
+ project: './tsconfig.json'
+ }
}
// With React
'airbnb',
'airbnb-typescript'
],
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
};
```

### 5) Run ESLint
### Running ESLint

Open a terminal to the root of your project, and run the following command:
Once set up, you can use ESLint as you would normally. In the root directory of your project, run:

```
```sh
npx eslint . --ext .js,.jsx,.ts,.tsx
```

ESLint will lint all .js, .jsx, .ts, and .tsx files within the current folder, and output results to your terminal.

You can also get results in realtime inside most IDEs via a plugin.
You can also get results in realtime inside most IDEs via a plugin. See [ESLint's integration documentation](https://eslint.org/docs/latest/use/integrations) for more details.

## FAQ

### I get this error when running ESLint: "The file must be included in at least one of the projects provided"

This means you are attempting to lint a file that `tsconfig.json` doesn't include.
Please refer to the [`typescript-eslint`](https://typescript-eslint.io/troubleshooting/typed-linting#traditional-project-issues) FAQ on how best to resolve this.

A common fix is to create a `tsconfig.eslint.json` file, which extends your `tsconfig.json` file and includes all files you are linting.

```json
{
"extends": "./tsconfig.json",
"include": ["src/**/*.ts", "src/**/*.js", "test/**/*.ts"]
}
```
### I wish this config would support [...]

Update your ESLint config file:
This config simply enhances the Airbnb with TypeScript support. It's not a single config to cater for all TypeScript linting requirements. For additional functionality, alter your ESLint config file. For example:

```diff
parserOptions: {
- project: './tsconfig.json',
+ project: './tsconfig.eslint.json',
}
```js
import typescriptPlugin from 'typescript-eslint';

// ...

export default [
...compat.extends('airbnb-base'),
...compat.extends('airbnb/hooks'),
...compat.extends('airbnb-typescript/base'),
...typescriptPlugin.configs.recommendedTypeChecked,
...typescriptPlugin.configs.stylisticTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
];
```

### Why do I need the peer dependencies?
### I use Prettier / StandardJS, how do I remove formatting rules?

`@typescript-eslint/eslint-plugin` is a peer dependency due to a limitation within ESLint. See [issue](https://github.com/eslint/eslint/issues/3458), [RFC](https://github.com/eslint/rfcs/tree/master/designs/2019-config-simplification), and [progress](https://github.com/eslint/eslint/issues/13481).
There are a couple of approaches to achieve this.

`@typescript-eslint/parser` is a peer dependency because the version number must match `@typescript-eslint/eslint-plugin`.
#### Configuration

### I wish this config would support [...]
Since the base Airbnb configs still use ESLint's legacy formatting rules, you can extend [`eslint-config-prettier`](https://github.com/prettier/eslint-config-prettier) to disable them. However, with ESLint [deprecating all formatting rules](https://eslint.org/blog/2023/10/deprecating-formatting-rules/) and [`typescript-eslint` outright removing them](https://typescript-eslint.io/users/what-about-formatting/), all our styling rules now originate from [ESLint Stylistic](https://eslint.style), which is not supported by the Prettier config (see upstream issue [#283](https://github.com/prettier/eslint-config-prettier/issues/283) to track progress).

This config simply enhances the Airbnb with TypeScript support. It's not a single config to cater for all TypeScript linting requirements. For additional functionality, alter your ESLint config file. For example:
Therefore, you'll need to disable all these rules manually. Luckily, this is pretty easy with flat configurations:

```js
module.exports = {
extends: [
'airbnb',
'airbnb-typescript',
'airbnb/hooks',
'plugin:@typescript-eslint/recommended-type-checked', // @typescript-eslint @v6
'plugin:@typescript-eslint/stylistic-type-checked', // @typescript-eslint @v6
// 'plugin:@typescript-eslint/recommended', // @typescript-eslint @v5
// 'plugin:@typescript-eslint/recommended-requiring-type-checking', // @typescript-eslint @v5
],
};
import stylistic from '@stylistic/eslint-plugin';

export default [
// ...

{
rules: Object.fromEntries(
Object.keys(stylisticPlugin.configs['all-flat'].rules ?? {}).map((key) => [key, 'off']),
),
},
];
```
My personal ESLint config file with support for Jest, Promises, and Prettier can be found in [create-exposed-app](https://github.com/iamturns/create-exposed-app/blob/master/.eslintrc.js).
#### Combined Tooling
Another approach is to use [`prettier-eslint`](https://github.com/prettier/prettier-eslint), which keeps the styling rules enabled and just combines the execution of ESLint and Prettier so the conflicts aren't user-facing. The CLI tool itself can be found under [`prettier-eslint-cli`](https://github.com/prettier/prettier-eslint-cli).
### Why is `import/no-unresolved` disabled?
Expand Down
Loading

0 comments on commit 932dea1

Please sign in to comment.