Skip to content

Commit

Permalink
Merge branch 'release/v2.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
andreashuber69 committed Jan 11, 2025
2 parents a4e1c81 + 5e255b7 commit 413af4c
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 96 deletions.
223 changes: 130 additions & 93 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,125 +29,162 @@ This is a comprehensive and carefully curated
[shareable eslint config](https://eslint.org/docs/latest/developer-guide/shareable-configs) for
[TypeScript](https://www.typescriptlang.org/) projects.

## Rationale

A search for **eslint-config** and **typescript** on [npm](https://npmjs.com) lists well over 2500 packages. Despite
this abundance, I've failed to find a package that satisfies what I was looking for, namely:

- Leverage the best eslint-plugins to thoroughly inspect code. To get an idea of what this config tries to achieve, it's
probably best to compare the number of active rules recommended for **TypeScript** projects
([see TS eslint quick start](https://typescript-eslint.io/getting-started#quickstart)) with
[React](https://react.dev/) support (see [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react)) to
the number of active rules in this configuration. At the time of writing the count is **only 101** for the recommended
set compared to **620 rules in this package**.
More specifically, ...
- flag as many problems and as much inconsistent formatting as possible while keeping false positives low. Developers
should be able to correct most errors and warnings by rewriting the code as opposed to sprinkling it with
`eslint-disable`.
- treat developers as responsible human beings and trust that they have a good sense of how much and what
documentation is necessary. Forcing developers to write docs usually leads to text that is not actually helpful and
therefore a waste of time.
- enforce established ES and TS naming conventions.
- Make installation, configuration and maintenance as easy as possible. With npm >= 7.0 you only need to install and
update this package. All dependencies are kept up to date automatically, see [Getting Started](#getting-started) for
more information.
- Closely track the versions of all dependencies and release new config versions as necessary.
- Last but not least: **Automatically test the configuration**, such that changes in **eslint** and the plugins (e.g.
added or removed rules) are detected and the rules listed in the configuration are always in sync with the rules
provided. With 7 plugins adding rules to this package, it's hard to overstate the importance of testing for
completeness and consistency. No other eslint configuration out there seems to do that, which is probably why some of
them still needlessly turn off **eslint** base rules in favor of their **@typescript-eslint** counterparts, even
though they extend from the **@typescript-eslint/recommended** list (which already does that).
## Prerequisites

To see how the linted code will look like, you can look at
[async-css-plugin](https://github.com/andreashuber69/async-css-plugin/tree/develop/src) and
[verify-coldcard-dice-seed](https://github.com/andreashuber69/verify-coldcard-dice-seed/tree/develop/src). If the code
looks sensible to you, you might want to give this package a try in your project. Of course, you can tweak everything to
your liking, see below.
The configuration provided by this package and the instructions below are designed to quickly add linting to
**TypeScript** projects. Towards that end, the new
[project service feature](https://typescript-eslint.io/blog/announcing-typescript-eslint-v8/#project-service) of
[typescript-eslint](https://typescript-eslint.io/) is employed. For this to work correctly, ...

1. the node version **must** be >=18.18 (imposed by eslint).
1. all code in a direct or indirect subfolder of the project root that is not explicitly excluded from linting
**must** be included by a *tsconfig.json* file located in the same folder as an included file or a direct or indirect
parent folder.
1. the handful of code files in the root folder of the project (like *eslint.config.mjs*, see below)
**should not** be included by a *tsconfig.json* file.
1. the root directory of the project **should** contain a *tsconfig.json* file.
1. it is recommended to have your *tsconfig.json* file(s) extend from a strict configuration. Here's an example for
node:

```jsonc
{
"extends": [
"@tsconfig/strictest/tsconfig",
"@tsconfig/node-lts/tsconfig"
],
"compilerOptions": {
// Additional compiler options to the ones set by @tsconfig
},
"include": ["src/**/*"]
}
```

## Prerequisites
If your project already satisfies to the requirements above, then you can get up and running simply by following the
steps under [Getting Started](#getting-started).

The configuration provided by this package and the instructions below are designed to work out of the box for already
setup **TypeScript** projects. That is, there must be a _tsconfig.json_ file in a direct or indirect parent folder of
every linted _.ts_ file, see [this article](https://typescript-eslint.io/blog/parser-options-project-true/) for details.
Also, while not required, it is recommended to have your _tsconfig.json_ extend from a strict configuration. Here's an
example for node:

```jsonc
{
"extends": [
"@tsconfig/strictest/tsconfig",
"@tsconfig/node-lts/tsconfig"
],
"compilerOptions": {
// Additional compiler options to the ones set by @tsconfig
},
"include": [
"src/**/*"
]
}
```
Note that only the first and second points above are hard requirements. For 3 & 4, there are ways to make linting work
even if your project does not follow these rules, see [Advanced Configuration](#advanced-configuration)

## Getting Started

### Installation

On the command line, first enter `npm -v` to see what version of `npm` you have installed. If you have a version
>=7.0.0, please use this command:

```bash
npm install --save-dev @andreashuber69/eslint-config
```

Otherwise, please use this command:

```bash
npx install-peerdeps @andreashuber69/eslint-config --dev
```

On npm 7 and newer, peer dependencies
[are installed automatically](https://github.com/npm/rfcs/blob/main/implemented/0025-install-peer-deps.md). On
older versions of npm, you can use the tool `install-peerdeps` as shown above or install the peer dependencies
manually.

### Configuration

1. Create the new file _.eslintrc.cjs_ in the root folder of your project, with the following contents:
1. Create the new file *eslint.config.mjs* in the root folder of your project, with the following contents:

```js
module.exports = {
env: {
// You need to set your execution environment (node, browser, etc.), for more information please see
// https://eslint.org/docs/latest/user-guide/configuring/language-options#specifying-environments
node: true,
import config from "@andreashuber69/eslint-config";

// eslint-disable-next-line import/no-anonymous-default-export, import/no-default-export
export default [
...config,
{
// List the folders of your project that are excluded from linting.
// This is typically a superset of the folders listed in .gitignore
ignores: ["coverage/", "dist/", "doc/"],
},
extends: ["@andreashuber69"],
rules: {
// Customize rules as you see fit
{
// Only necessary if you'd like to change or turn off rules
rules: {
// Change to your liking, e.g.
"@typescript-eslint/return-await": "off",
"unicorn/switch-case-braces": "off",
},
},
};
];
```

This is typically enough, as **eslint** will merge the above with `parserOptions: { ecmaVersion: "latest" }`,
`env: { es2024: true }` and other defaults. To see the complete configuration you might want to run ...

```bash
npx eslint --print-config .eslintrc.cjs >eslint-config.json
```

... and inspect _eslint-config.json_. Note that for a typical TS project you want to parse according to the latest
standard because the **TypeScript** compiler will downlevel language features depending on the `target` setting in
_tsconfig.json_.

2. Add the following line to the `scripts` section of your _package.json_ (assuming your code resides in the _src_
folder):
1. Add the following line to the `scripts` section of your *package.json*:

```json
"lint": "eslint --ext .js,.ts --report-unused-disable-directives './src'",
"lint": "eslint",
```

### Lint

```bash
npm run lint
```

## Advanced Configuration

A more flexible template for *eslint.config.mjs* looks as follows:

```js
import config from "@andreashuber69/eslint-config";

// eslint-disable-next-line import/no-anonymous-default-export, import/no-default-export
export default [
...config,
{
// List the folders of your project that are excluded from linting.
// This is typically a superset of the folders listed in .gitignore
ignores: ["coverage/", "dist/", "doc/"],
},
{
languageOptions: {
parserOptions: {
projectService: {
// Globs relative to the root folder matching at most 8 code files not included by a tsconfig.json
// (can be empty).
allowDefaultProject: ["*.js", "*.cjs", "*.mjs", "*.ts", "*.cts", "*.mts"],
// The relative path to a tsconfig.json that will be used to lint the files matched with
// allowDefaultProject.
defaultProject: "tsconfig.json",
},
},
},
// Only necessary if you'd like to change or turn off rules
rules: {
// Change to your liking, e.g.
"@typescript-eslint/return-await": "off",
"unicorn/switch-case-braces": "off",
},
},
];
```

Above, the values for [`allowDefaultProject`](https://typescript-eslint.io/packages/parser/#allowdefaultproject) and
[`defaultProject`](https://typescript-eslint.io/packages/parser/#defaultproject) show what is assumed with the
simpler template under [Configuration](#configuration). Therefore, if your project does not satisfy the
requirements 3 and/or 4 (see [Prerequisites](#prerequisites)), you can modify these to suit your needs.

## Rationale

A search for **eslint-config** and **typescript** on [npm](https://npmjs.com) lists well over 2500 packages. Despite
this abundance, I've failed to find a package that satisfies what I was looking for, namely:

- Leverage the best eslint-plugins to thoroughly inspect code. To get an idea of what this config tries to achieve, it's
probably best to compare the number of active rules recommended for **TypeScript** projects
([see TS eslint quick start](https://typescript-eslint.io/getting-started#quickstart)) with
[React](https://react.dev/) support (see [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react)) to
the number of active rules in this configuration. At the time of writing the count is **only 101** for the recommended
set compared to **621 rules in this package**.
More specifically, ...
- flag as many problems and as much inconsistent formatting as possible while keeping false positives low. Developers
should be able to correct most errors and warnings by rewriting the code as opposed to sprinkling it with
`eslint-disable`.
- treat developers as responsible human beings and trust that they have a good sense of how much and what
documentation is necessary. Forcing developers to write docs usually leads to text that is not actually helpful and
therefore a waste of time.
- enforce established ES and TS naming conventions.
- Make installation, configuration and maintenance as easy as possible. You only need to install and update this
package. All dependencies are kept up to date automatically.
- Closely track the versions of all dependencies and release new config versions as necessary.
- Last but not least: **Automatically test the configuration**, such that changes in **eslint** and the plugins (e.g.
added or removed rules) are detected and the rules listed in the configuration are always in sync with the rules
provided. With 7 plugins adding rules to this package, it's hard to overstate the importance of testing for
completeness and consistency. No other eslint configuration out there seems to do that, which is probably why some of
them still needlessly turn off **eslint** base rules in favor of their **@typescript-eslint** counterparts, even
though they extend from the **tseslint.configs.recommended** list (which already does that).

To see how the linted code will look like, you can look at
[async-css-plugin](https://github.com/andreashuber69/async-css-plugin/tree/develop/src) and
[verify-coldcard-dice-seed](https://github.com/andreashuber69/verify-coldcard-dice-seed/tree/develop/src). If the code
looks sensible to you, you might want to give this package a try in your project. Of course, you can tweak everything to
your liking, see above.
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@andreashuber69/eslint-config",
"version": "2.0.0-rc.0",
"version": "2.0.0",
"description": "Provides a comprehensive, carefullly curated and tested shareable eslint config for TypeScript projects.",
"keywords": [
"eslint",
Expand Down

0 comments on commit 413af4c

Please sign in to comment.