Skip to content

Commit ec210f2

Browse files
authored
Migrate to flat config (#86)
1 parent e669d26 commit ec210f2

10 files changed

+177
-66
lines changed

.eslintrc.cjs

-1
This file was deleted.

.github/workflows/main.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
node-version:
13-
- 16
14-
- 14
15-
- 12
13+
- 22
14+
- 20
15+
- 18
1616
steps:
1717
- uses: actions/checkout@v4
1818
- uses: actions/setup-node@v4

browser.js

+23-15
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
1-
'use strict';
2-
const path = require('path');
3-
const confusingBrowserGlobals = require('confusing-browser-globals');
1+
import globals from 'globals';
2+
import confusingBrowserGlobals from 'confusing-browser-globals';
3+
import eslintConfigXo from './index.js';
44

5-
module.exports = {
6-
extends: path.join(__dirname, 'index.js'),
7-
env: {
8-
node: false,
9-
browser: true,
10-
},
11-
rules: {
12-
'no-restricted-globals': [
13-
'error',
14-
...confusingBrowserGlobals,
15-
],
5+
const [config] = eslintConfigXo;
6+
7+
export default [
8+
{
9+
...config,
10+
languageOptions: {
11+
...config.languageOptions,
12+
globals: {
13+
...globals.es2021,
14+
...globals.browser,
15+
},
16+
},
17+
rules: {
18+
...config.rules,
19+
'no-restricted-globals': [
20+
'error',
21+
...confusingBrowserGlobals,
22+
],
23+
},
1624
},
17-
};
25+
];

eslint.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {default} from './index.js';

index.js

+15-10
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
'use strict';
1+
import globals from 'globals';
22

3-
module.exports = {
4-
parserOptions: {
5-
ecmaVersion: 'latest',
3+
const config = {
4+
languageOptions: {
65
sourceType: 'module',
7-
ecmaFeatures: {
8-
jsx: true,
6+
parserOptions: {
7+
ecmaFeatures: {
8+
jsx: true,
9+
},
10+
},
11+
globals: {
12+
...globals.es2021,
13+
...globals.node,
914
},
1015
},
11-
env: {
12-
es2021: true,
13-
node: true,
16+
linterOptions: {
17+
reportUnusedDisableDirectives: 'error',
1418
},
15-
reportUnusedDisableDirectives: true,
1619
rules: {
1720
'comma-dangle': [
1821
'error',
@@ -693,3 +696,5 @@ module.exports = {
693696
],
694697
},
695698
};
699+
700+
export default [config];

package.json

+14-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
"version": "0.45.0",
44
"description": "ESLint shareable config for XO",
55
"license": "MIT",
6+
"type": "module",
7+
"exports": {
8+
".": "./index.js",
9+
"./browser": "./browser.js",
10+
"./space": "./space.js",
11+
"./space/browser": "./space-browser.js"
12+
},
613
"repository": "xojs/eslint-config-xo",
714
"funding": "https://github.com/sponsors/sindresorhus",
815
"author": {
@@ -19,7 +26,9 @@
1926
},
2027
"files": [
2128
"index.js",
22-
"browser.js"
29+
"browser.js",
30+
"space.js",
31+
"space-browser.js"
2332
],
2433
"keywords": [
2534
"eslintconfig",
@@ -50,12 +59,12 @@
5059
"simple"
5160
],
5261
"dependencies": {
53-
"confusing-browser-globals": "1.0.11"
62+
"confusing-browser-globals": "1.0.11",
63+
"globals": "^15.3.0"
5464
},
5565
"devDependencies": {
56-
"ava": "^2.4.0",
57-
"eslint": "^8.56.0",
58-
"is-plain-obj": "^3.0.0"
66+
"ava": "^6.1.3",
67+
"eslint": "^9.4.0"
5968
},
6069
"peerDependencies": {
6170
"eslint": ">=8.56.0"

readme.md

+32-19
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,44 @@ npm install --save-dev eslint-config-xo
1616

1717
## Usage
1818

19-
Add some ESLint config to your `package.json`:
20-
21-
```json
22-
{
23-
"name": "my-awesome-project",
24-
"eslintConfig": {
25-
"extends": "xo"
26-
}
27-
}
19+
Add some ESLint config to your `eslint.config.js`:
20+
21+
```js
22+
import eslintConfigXo from 'eslint-config-xo';
23+
24+
export default [
25+
...eslintConfigXo,
26+
];
27+
```
28+
29+
This package also exposes [`eslint-config-xo/browser`](browser.js) if you're in the browser:
30+
31+
```js
32+
import eslintConfigXoBrowser from 'eslint-config-xo/browser';
33+
34+
export default [
35+
...eslintConfigXoBrowser,
36+
];
2837
```
2938

30-
Or to `.eslintrc`:
39+
This package also exposes [`eslint-config-xo/space`](space.js) if you're in favor of 2-space indent:
3140

32-
```json
33-
{
34-
"extends": "xo"
35-
}
41+
```js
42+
import eslintConfigXoSpace from 'eslint-config-xo/space';
43+
44+
export default [
45+
...eslintConfigXoSpace,
46+
];
3647
```
3748

38-
This package also exposes [`xo/browser`](browser.js) if you're in the browser:
49+
This package also exposes [`eslint-config-xo/space/browser`](space-browser.js) if you're in favor of 2-space indent and in browser:
50+
51+
```js
52+
import eslintConfigXoSpaceBrowser from 'eslint-config-xo/space/browser';
3953

40-
```json
41-
{
42-
"extends": "xo/browser"
43-
}
54+
export default [
55+
...eslintConfigXoSpaceBrowser,
56+
];
4457
```
4558

4659
## Use the XO CLI instead

space-browser.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import eslintConfigXoBrowser from './browser.js';
2+
3+
const [config] = eslintConfigXoBrowser;
4+
5+
export default [
6+
{
7+
...config,
8+
rules: {
9+
...config.rules,
10+
indent: [
11+
'error',
12+
2,
13+
{
14+
SwitchCase: 1,
15+
},
16+
],
17+
},
18+
},
19+
];

space.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import eslintConfigXo from './index.js';
2+
3+
const [config] = eslintConfigXo;
4+
5+
export default [
6+
{
7+
...config,
8+
rules: {
9+
...config.rules,
10+
indent: [
11+
'error',
12+
2,
13+
{
14+
SwitchCase: 1,
15+
},
16+
],
17+
},
18+
},
19+
];

test/test.js

+51-13
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import test from 'ava';
2-
import isPlainObj from 'is-plain-obj';
32
import {ESLint} from 'eslint';
3+
import eslintConfigXoNode from '../index.js';
4+
import eslintConfigXoBrowser from '../browser.js';
5+
import eslintConfigXoSpaceNode from '../space.js';
6+
import eslintConfigXoSpaceBrowser from '../space-browser.js';
47

58
const hasRule = (errors, ruleId) => errors.some(error => error.ruleId === ruleId);
69

710
async function runEslint(string, config) {
811
const eslint = new ESLint({
9-
useEslintrc: false,
12+
overrideConfigFile: true,
1013
overrideConfig: config,
1114
});
1215

@@ -15,21 +18,56 @@ async function runEslint(string, config) {
1518
return firstResult.messages;
1619
}
1720

18-
test('main', async t => {
19-
const config = require('../index.js');
21+
test('node', async t => {
22+
for (const config of [eslintConfigXoNode, eslintConfigXoSpaceNode]) {
23+
t.true(Array.isArray(config));
2024

21-
t.true(isPlainObj(config));
22-
t.true(isPlainObj(config.rules));
23-
24-
const errors = await runEslint('\'use strict\';\nconsole.log("unicorn")\n', config);
25-
t.true(hasRule(errors, 'quotes'), JSON.stringify(errors));
25+
// eslint-disable-next-line no-await-in-loop
26+
const errors = await runEslint('\'use strict\';\nconsole.log("unicorn")\n', config);
27+
t.true(hasRule(errors, 'quotes'), JSON.stringify(errors));
28+
}
2629
});
2730

2831
test('browser', async t => {
29-
const config = require('../browser.js');
32+
for (const config of [eslintConfigXoBrowser, eslintConfigXoSpaceBrowser]) {
33+
t.true(Array.isArray(config));
34+
35+
// eslint-disable-next-line no-await-in-loop
36+
const errors = await runEslint('\'use strict\';\nprocess.exit();\n', config);
37+
t.true(hasRule(errors, 'no-undef'), JSON.stringify(errors));
38+
}
39+
});
3040

31-
t.true(isPlainObj(config));
41+
test('space', async t => {
42+
const fixture = `
43+
export function foo() {
44+
\treturn true;
45+
}
46+
`.trim();
3247

33-
const errors = await runEslint('\'use strict\';\nprocess.exit();\n', config);
34-
t.true(hasRule(errors, 'no-undef'), JSON.stringify(errors));
48+
for (const {
49+
expected,
50+
config,
51+
} of [
52+
{
53+
config: eslintConfigXoSpaceNode,
54+
expected: true,
55+
},
56+
{
57+
config: eslintConfigXoSpaceBrowser,
58+
expected: true,
59+
},
60+
{
61+
config: eslintConfigXoNode,
62+
expected: false,
63+
},
64+
{
65+
config: eslintConfigXoBrowser,
66+
expected: false,
67+
},
68+
]) {
69+
// eslint-disable-next-line no-await-in-loop
70+
const errors = await runEslint(fixture, config);
71+
t.is(hasRule(errors, 'indent'), expected, JSON.stringify(errors));
72+
}
3573
});

0 commit comments

Comments
 (0)