Skip to content

Commit a8a5c12

Browse files
committed
feat: add eslint-plugin-peer-deps blog
1 parent f689d70 commit a8a5c12

File tree

6 files changed

+70
-28
lines changed

6 files changed

+70
-28
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
{"rule":"MORFOLOGIK_RULE_EN_US","sentence":"^\\Q[NPM version]npm-url [GitHub NodeJS]github-action-url\\E$"}
22
{"rule":"HOW_TO_HYPHEN","sentence":"^\\QI would recommend having a quick read through of the How to TypeScript section, and then check out the Supporting Tools section to find out how to set up your project, and use the rest of the book for reference as you need them.\\E$"}
3+
4+
{"rule":"COMMA_PARENTHESIS_WHITESPACE","sentence":"^\\Q- ...\\node_modules\\@typescript-eslint\\eslint-plugin\\dist\\index.js (loaded in \".eslintrc.json\")\n- ...\\node_modules\\eslint-config-react-app\\node_modules\\@typescript-eslint\\eslint-plugin\\dist\\index.js (loaded in \".eslintrc.json » eslint-config-react-app#overrides[0]\")\n```\\E$"}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"extends": [
3+
"react-app"
4+
],
5+
"plugins": [
6+
"@typescript-eslint"
7+
]
8+
}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "@unional/eslint-plugin-peer",
3+
"private": true,
4+
"scripts": {
5+
"lint": "eslint --ext=ts ."
6+
},
7+
"devDependencies": {
8+
"@typescript-eslint/eslint-plugin": "5.4",
9+
"eslint": "^8.15.0",
10+
"eslint-config-react-app": "^7.0.1"
11+
}
12+
}
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const empty = {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
slug: 2022-eslint-plugin-peer-deps
3+
title: "@typescript-eslint/eslint-plugin should be a peer dependency"
4+
authors: [unional]
5+
tags: [typescript, eslint, "@typescript-eslint"]
6+
---
7+
8+
# The Problem
9+
10+
Recently I run into this problem:
11+
12+
```sh
13+
ESLint couldn't determine the plugin "@typescript-eslint" uniquely.
14+
15+
- ...\node_modules\@typescript-eslint\eslint-plugin\dist\index.js (loaded in ".eslintrc.json")
16+
- ...\node_modules\eslint-config-react-app\node_modules\@typescript-eslint\eslint-plugin\dist\index.js (loaded in ".eslintrc.json » eslint-config-react-app#overrides[0]")
17+
```
18+
19+
It is caused by [eslint-config-react-app] using [@typescript-eslint/eslint-plugin] as a `dependency` instead of a `peer dependency`.
20+
21+
Here is the [GitHub issue] for [eslint-config-react-app].
22+
23+
## Plugin and dependency
24+
25+
The problem is when one plugin uses another plugin,
26+
it should always declare the dependency as a `peer dependency`.
27+
28+
The reason is simple.
29+
30+
The host application (ESLint in this case) controls and loads its plugins.
31+
If the host application is not designed to support loading multiple versions of the same plugin at the same time,
32+
which most of them don't, then the result is an undefined behavior.
33+
34+
That's why ESLint plainly detects and disallows it.
35+
36+
Yes, that means the consuming repository needs to add the dependency themselves.
37+
Any version incompatibility in the dependency graph would lead to the [doppelgängers] problem.
38+
39+
That is an inherited problem of NodeJS resolution algorithm, and is a topic for another day.
40+
41+
Happy coding, 🧑‍💻
42+
43+
[@typescript-eslint/eslint-plugin]: https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/eslint-plugin
44+
[eslint-config-react-app]: https://github.com/facebook/create-react-app/tree/main/packages/eslint-config-react-app
45+
[GitHub issue]: https://github.com/facebook/create-react-app/issues/12400
46+
[doppelgängers]: https://rushjs.io/pages/advanced/npm_doppelgangers/

yarn.lock

+1-28
Original file line numberDiff line numberDiff line change
@@ -3286,7 +3286,7 @@ __metadata:
32863286
languageName: node
32873287
linkType: hard
32883288

3289-
"@typescript-eslint/experimental-utils@npm:^5.0.0, @typescript-eslint/experimental-utils@npm:^5.23.0":
3289+
"@typescript-eslint/experimental-utils@npm:^5.0.0":
32903290
version: 5.23.0
32913291
resolution: "@typescript-eslint/experimental-utils@npm:5.23.0"
32923292
dependencies:
@@ -3442,9 +3442,7 @@ __metadata:
34423442
dependencies:
34433443
"@typescript-eslint/eslint-plugin": 5.4
34443444
eslint: ^8.15.0
3445-
eslint-config-prettier: ^8.5.0
34463445
eslint-config-react-app: ^7.0.1
3447-
eslint-plugin-harmony: ^7.0.1
34483446
languageName: unknown
34493447
linkType: soft
34503448

@@ -6030,17 +6028,6 @@ __metadata:
60306028
languageName: node
60316029
linkType: hard
60326030

6033-
"eslint-config-prettier@npm:^8.5.0":
6034-
version: 8.5.0
6035-
resolution: "eslint-config-prettier@npm:8.5.0"
6036-
peerDependencies:
6037-
eslint: ">=7.0.0"
6038-
bin:
6039-
eslint-config-prettier: bin/cli.js
6040-
checksum: 0d0f5c32e7a0ad91249467ce71ca92394ccd343178277d318baf32063b79ea90216f4c81d1065d60f96366fdc60f151d4d68ae7811a58bd37228b84c2083f893
6041-
languageName: node
6042-
linkType: hard
6043-
60446031
"eslint-config-react-app@npm:^7.0.1":
60456032
version: 7.0.1
60466033
resolution: "eslint-config-react-app@npm:7.0.1"
@@ -6099,20 +6086,6 @@ __metadata:
60996086
languageName: node
61006087
linkType: hard
61016088

6102-
"eslint-plugin-harmony@npm:^7.0.1":
6103-
version: 7.0.1
6104-
resolution: "eslint-plugin-harmony@npm:7.0.1"
6105-
dependencies:
6106-
"@typescript-eslint/experimental-utils": ^5.23.0
6107-
peerDependencies:
6108-
"@typescript-eslint/eslint-plugin": ^5.0.0
6109-
"@typescript-eslint/parser": ^5.0.0
6110-
eslint: ">=8.4.0"
6111-
eslint-config-prettier: ^8.0.0
6112-
checksum: 2131f12e75f37aa7b3cd9f4ec85a0fa681ac522941fc3064200b5586c352665f2f4be4cdaf9f5a8b009a7d7f5c22e223714dd6a0be647c2d9acb163841c42772
6113-
languageName: node
6114-
linkType: hard
6115-
61166089
"eslint-plugin-import@npm:^2.25.3":
61176090
version: 2.26.0
61186091
resolution: "eslint-plugin-import@npm:2.26.0"

0 commit comments

Comments
 (0)