Skip to content

Commit 03c79b9

Browse files
authored
One config to rule them all (#175)
Fixes #173. Fixes #174.
1 parent 72ce4d7 commit 03c79b9

19 files changed

+271
-351
lines changed

.eslintrc.base.js

+9-10
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// This file is only used in `./.eslintrc.js` and in the tests – it’s not part
44
// of the eslint-config-prettier npm package.
55

6-
const fs = require("fs");
6+
const config = require(".");
77

88
module.exports = {
99
extends: [
@@ -15,13 +15,12 @@ module.exports = {
1515
],
1616
plugins: [
1717
"prettier",
18-
...fs
19-
.readdirSync(__dirname)
20-
.filter(
21-
(file) =>
22-
!file.startsWith(".") && file.endsWith(".js") && file !== "index.js"
23-
)
24-
.map((ruleFileName) => ruleFileName.replace(/\.js$/, "")),
18+
...new Set(
19+
Object.keys(config.rules)
20+
.map((ruleName) => ruleName.split("/"))
21+
.filter((parts) => parts.length > 1)
22+
.map((parts) => parts[0])
23+
),
2524
],
2625
parserOptions: {
2726
parser: "babel-eslint",
@@ -38,10 +37,10 @@ module.exports = {
3837
node: true,
3938
},
4039
rules: {
41-
indent: "off",
40+
"indent": "off",
4241
"linebreak-style": "off",
4342
"no-dupe-keys": "error",
44-
strict: "error",
43+
"strict": "error",
4544
"prefer-spread": "off",
4645
"require-jsdoc": "off",
4746
"prettier/prettier": "error",

.eslintrc.js

+2-10
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,8 @@
66
// as an “eat your own dogfood” test. That feels like a good test, but
77
// complicates things a little sometimes.
88

9-
const fs = require("fs");
10-
119
module.exports = {
12-
extends: [
13-
"./.eslintrc.base.js",
14-
...fs
15-
.readdirSync(__dirname)
16-
.filter((file) => !file.startsWith(".") && file.endsWith(".js"))
17-
.map((ruleFileName) => `./${ruleFileName}`),
18-
],
10+
extends: ["./.eslintrc.base.js", "./index.js", "./prettier.js"],
1911
rules: {
2012
"prettier/prettier": "off",
2113
},
@@ -32,7 +24,7 @@ module.exports = {
3224
"The comma operator is confusing and a common mistake. Don’t use it!",
3325
},
3426
],
35-
quotes: [
27+
"quotes": [
3628
"error",
3729
"double",
3830
{ avoidEscape: true, allowTemplateLiterals: false },

.prettierrc.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"proseWrap": "never"
2+
"proseWrap": "never",
3+
"quoteProps": "consistent"
34
}

@typescript-eslint.js

-22
This file was deleted.

README.md

+8-46
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Then, add eslint-config-prettier to the "extends" array in your `.eslintrc.*` fi
5757
}
5858
```
5959

60-
A few ESLint plugins are supported as well:
60+
That’s it! Extending `"prettier"` turns off a bunch of core ESLint rules, as well as a few rules from these plugins:
6161

6262
- [@typescript-eslint/eslint-plugin]
6363
- [eslint-plugin-babel]
@@ -68,40 +68,7 @@ A few ESLint plugins are supported as well:
6868
- [eslint-plugin-unicorn]
6969
- [eslint-plugin-vue]
7070

71-
Add extra exclusions for the plugins you use like so:
72-
73-
<!-- prettier-ignore -->
74-
```json
75-
{
76-
"extends": [
77-
"some-other-config-you-use",
78-
"prettier",
79-
"prettier/@typescript-eslint",
80-
"prettier/babel",
81-
"prettier/flowtype",
82-
"prettier/prettier",
83-
"prettier/react",
84-
"prettier/standard",
85-
"prettier/unicorn",
86-
"prettier/vue"
87-
]
88-
}
89-
```
90-
91-
If you extend a config which uses a plugin, it is recommended to add `"prettier/that-plugin"` (if available). For example, [eslint-config-airbnb] enables [eslint-plugin-react] rules, so `"prettier/react"` is needed:
92-
93-
<!-- prettier-ignore -->
94-
```json
95-
{
96-
"extends": [
97-
"airbnb",
98-
"prettier",
99-
"prettier/react"
100-
]
101-
}
102-
```
103-
104-
If you’re unsure which plugins are used, you can usually find them in your `package.json`.
71+
> Note: You might find guides on the Internet saying you should also extend stuff like `"prettier/react"`. Since version 8.0.0 of eslint-config-prettier, all you need to extend is `"prettier"`! That includes all plugins.
10572
10673
### Excluding deprecated rules
10774

@@ -163,14 +130,16 @@ For maximum ease of use, the special rules are disabled by default (provided tha
163130

164131
**These rules might cause problems if using [eslint-plugin-prettier] and `--fix`.**
165132

166-
See [`arrow-body-style` and `prefer-arrow-callback` issue][eslint-plugin-prettier-autofix-issue] for details.
133+
See the [`arrow-body-style` and `prefer-arrow-callback` issue][eslint-plugin-prettier-autofix-issue] for details.
167134

168135
There are a couple of ways to turn these rules off:
169136

170137
- Put `"prettier/prettier"` in your `"extends"`. (Yes, there’s both a _rule_ called `"prettier/prettier"` and a _config_ called `"prettier/prettier"`.)
171138
- Use [eslint-plugin-prettier’s recommended config][eslint-plugin-prettier-recommended], which also turns off these two rules.
172139
- Remove them from your config or turn them off manually.
173140

141+
It doesn’t matter which approach you use – they’re all the same.
142+
174143
Note: The CLI tool only reports these as problematic if the `"prettier/prettier"` _rule_ is enabled for the same file.
175144

176145
These rules are safe to use if you don’t use [eslint-plugin-prettier]. In other words, if you run `eslint --fix` and `prettier --write` as separate steps.
@@ -698,17 +667,11 @@ Have new rules been added since those versions? Have we missed any rules? Is the
698667

699668
If you’d like to add support for eslint-plugin-foobar, this is how you’d go about it:
700669

701-
First, create `foobar.js`:
670+
First, add rules to `index.js`:
702671

703672
<!-- prettier-ignore -->
704673
```js
705-
"use strict";
706-
707-
module.exports = {
708-
rules: {
709-
"foobar/some-rule": "off"
710-
}
711-
};
674+
"foobar/some-rule": "off"
712675
```
713676

714677
Then, create `test-lint/foobar.js`:
@@ -729,7 +692,7 @@ Finally, you need to mention the plugin in several places:
729692

730693
- Add eslint-plugin-foobar to the "devDependencies" field in `package.json`.
731694
- Make sure that at least one rule from eslint-plugin-foobar gets used in `.eslintrc.base.js`.
732-
- Add it to the list of supported plugins and to the Contributing section in `README.md`.
695+
- Add it to the lists of supported plugins and in this `README.md`.
733696

734697
When you’re done, run `npm test` to verify that you got it all right. It runs several other npm scripts:
735698

@@ -751,7 +714,6 @@ When you’re done, run `npm test` to verify that you got it all right. It runs
751714
[arrow-body-style]: https://eslint.org/docs/rules/arrow-body-style
752715
[babel/quotes]: https://github.com/babel/eslint-plugin-babel#rules
753716
[curly]: https://eslint.org/docs/rules/curly
754-
[eslint-config-airbnb]: https://www.npmjs.com/package/eslint-config-airbnb
755717
[eslint-plugin-babel]: https://github.com/babel/eslint-plugin-babel
756718
[eslint-plugin-flowtype]: https://github.com/gajus/eslint-plugin-flowtype
757719
[eslint-plugin-prettier-autofix-issue]: https://github.com/prettier/eslint-plugin-prettier#arrow-body-style-and-prefer-arrow-callback-issue

babel.js

-10
This file was deleted.

bin/cli.js

+52-45
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
"use strict";
44

5-
const fs = require("fs");
6-
const path = require("path");
75
const validators = require("./validators");
6+
const config = require("..");
7+
const prettier = require("../prettier");
88

99
// Require locally installed eslint, for `npx eslint-config-prettier` support
1010
// with no local eslint-config-prettier installation.
@@ -15,6 +15,9 @@ const { ESLint } = require(require.resolve("eslint", {
1515
const SPECIAL_RULES_URL =
1616
"https://github.com/prettier/eslint-config-prettier#special-rules";
1717

18+
const PRETTIER_RULES_URL =
19+
"https://github.com/prettier/eslint-config-prettier#arrow-body-style-and-prefer-arrow-callback";
20+
1821
if (module === require.main) {
1922
const args = process.argv.slice(2);
2023

@@ -28,8 +31,8 @@ if (module === require.main) {
2831
Promise.all(args.map((file) => eslint.calculateConfigForFile(file)))
2932
.then((configs) => {
3033
const rules = [].concat(
31-
...configs.map((config, index) =>
32-
Object.entries(config.rules).map((entry) => [...entry, args[index]])
34+
...configs.map(({ rules }, index) =>
35+
Object.entries(rules).map((entry) => [...entry, args[index]])
3336
)
3437
);
3538
const result = processRules(rules);
@@ -68,24 +71,13 @@ https://github.com/prettier/eslint-config-prettier#cli-helper-tool
6871
}
6972

7073
function processRules(configRules) {
71-
// This used to look at "files" in package.json, but that is not reliable due
72-
// to an npm bug. See:
73-
// https://github.com/prettier/eslint-config-prettier/issues/57
74-
const allRules = Object.assign(
75-
Object.create(null),
76-
...fs
77-
.readdirSync(path.join(__dirname, ".."))
78-
.filter((name) => !name.startsWith(".") && name.endsWith(".js"))
79-
.map((ruleFileName) => require(`../${ruleFileName}`).rules)
80-
);
81-
82-
const regularRules = filterRules(allRules, (_, value) => value === "off");
74+
const regularRules = filterRules(config.rules, (_, value) => value === "off");
8375
const optionsRules = filterRules(
84-
allRules,
76+
config.rules,
8577
(ruleName, value) => value === 0 && ruleName in validators
8678
);
8779
const specialRules = filterRules(
88-
allRules,
80+
config.rules,
8981
(ruleName, value) => value === 0 && !(ruleName in validators)
9082
);
9183

@@ -99,7 +91,7 @@ function processRules(configRules) {
9991
.filter(Boolean);
10092

10193
const flaggedRules = enabledRules.filter(
102-
({ ruleName }) => ruleName in allRules
94+
({ ruleName }) => ruleName in config.rules
10395
);
10496

10597
const regularFlaggedRuleNames = filterRuleNames(
@@ -109,37 +101,21 @@ function processRules(configRules) {
109101
const optionsFlaggedRuleNames = filterRuleNames(
110102
flaggedRules,
111103
({ ruleName, ...rule }) =>
112-
ruleName in optionsRules && !validators[ruleName](rule, enabledRules)
104+
ruleName in optionsRules && !validators[ruleName](rule)
113105
);
114106
const specialFlaggedRuleNames = filterRuleNames(
115107
flaggedRules,
116108
({ ruleName }) => ruleName in specialRules
117109
);
118-
119-
if (
120-
regularFlaggedRuleNames.length === 0 &&
121-
optionsFlaggedRuleNames.length === 0
122-
) {
123-
const baseMessage =
124-
"No rules that are unnecessary or conflict with Prettier were found.";
125-
126-
const message =
127-
specialFlaggedRuleNames.length === 0
128-
? baseMessage
129-
: [
130-
baseMessage,
131-
"",
132-
"However, the following rules are enabled but cannot be automatically checked. See:",
133-
SPECIAL_RULES_URL,
134-
"",
135-
printRuleNames(specialFlaggedRuleNames),
136-
].join("\n");
137-
138-
return {
139-
stdout: message,
140-
code: 0,
141-
};
142-
}
110+
const prettierFlaggedRuleNames = filterRuleNames(
111+
enabledRules,
112+
({ ruleName, source }) =>
113+
ruleName in prettier.rules &&
114+
enabledRules.some(
115+
(rule) =>
116+
rule.ruleName === "prettier/prettier" && rule.source === source
117+
)
118+
);
143119

144120
const regularMessage = [
145121
"The following rules are unnecessary or might conflict with Prettier:",
@@ -161,10 +137,41 @@ function processRules(configRules) {
161137
printRuleNames(specialFlaggedRuleNames),
162138
].join("\n");
163139

140+
const prettierMessage = [
141+
"The following rules can cause issues when using eslint-plugin-prettier at the same time.",
142+
"Only enable them if you know what you are doing! See:",
143+
PRETTIER_RULES_URL,
144+
"",
145+
printRuleNames(prettierFlaggedRuleNames),
146+
].join("\n");
147+
148+
if (
149+
regularFlaggedRuleNames.length === 0 &&
150+
optionsFlaggedRuleNames.length === 0
151+
) {
152+
const message =
153+
specialFlaggedRuleNames.length === 0 &&
154+
prettierFlaggedRuleNames.length === 0
155+
? "No rules that are unnecessary or conflict with Prettier were found."
156+
: [
157+
specialFlaggedRuleNames.length === 0 ? null : specialMessage,
158+
prettierFlaggedRuleNames.length === 0 ? null : prettierMessage,
159+
"Other than that, no rules that are unnecessary or conflict with Prettier were found.",
160+
]
161+
.filter(Boolean)
162+
.join("\n\n");
163+
164+
return {
165+
stdout: message,
166+
code: 0,
167+
};
168+
}
169+
164170
const message = [
165171
regularFlaggedRuleNames.length === 0 ? null : regularMessage,
166172
optionsFlaggedRuleNames.length === 0 ? null : optionsMessage,
167173
specialFlaggedRuleNames.length === 0 ? null : specialMessage,
174+
prettierFlaggedRuleNames.length === 0 ? null : prettierMessage,
168175
]
169176
.filter(Boolean)
170177
.join("\n\n");

0 commit comments

Comments
 (0)