Skip to content

Commit 0bcbb21

Browse files
Convert to ESLint 9 flat config and move to pnpm (#19)
* Convert to ESLint 9 flat config and move to pnpm * Update instrcutions * Remove yarn.lock * Add changelog entry * Use newest packages
1 parent f82f270 commit 0bcbb21

13 files changed

+3872
-3246
lines changed

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
# These are org-wide files (https://github.com/exercism/org-wide-files/)
55
/.github/labels.yml
6+
/.github/workflows/pause-community-contributions.yml
67
/.github/workflows/sync-labels.yml
78

89
/CODE_OF_CONDUCT.md

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## 0.7.0
4+
5+
- Use pnpm 9.6.0
6+
- Update to eslint 9+
7+
- Migrate to flat config
8+
39
## 0.6.0
410

511
- Upgrade to eslint 8+

README.md

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,70 @@
11
# @exercism/eslint-config-javascript
22

3-
This is the shared [`eslint`][web-eslint] configuration used by the [JavaScript track][git-javascript] (for students) and the files contributors and maintainers touch. [Shareable configs][web-shareable-configs] are designed to work with the `extends` feature of `.eslintrc` files. This means you can use the same configuration you're used to on [Exercism][web-exercism] in your on projects!
3+
This is the shared [`eslint`][web-eslint] configuration used by the [JavaScript track][git-javascript] (for students) and the files contributors and maintainers touch.
4+
[Shareable configs][web-shareable-configs] are designed to work with the `extends` feature of ESLint configuration files.
5+
This means you can use the same configuration you're used to on [Exercism][web-exercism] in your on projects!
46

57
## Usage
68

7-
To use the configuration for students, open your [eslint configuration][web-eslint-configuration] file, and add the following value to `extends`. For example, for JSON based configuration files:
9+
To use the configuration for students, open your [eslint configuration][web-eslint-configuration] file, and import the following file for the flat config.
10+
For example, for flat config configuration files:
811

9-
```json
10-
{
11-
"extends": "@exercism/eslint-config-javascript"
12-
}
12+
```javascript
13+
import baseConfig from '@exercism/eslint-config-javascript';
14+
15+
// ...
16+
export default [
17+
...baseConfig,
18+
// ... your configuration
19+
];
1320
```
1421

15-
To use the configuration used by contributors and maintainers, add the following to `extends`:
22+
To use the configuration used by contributors and maintainers, add the following:
23+
24+
```javascript
25+
import baseConfig from '@exercism/eslint-config-javascript/maintainers';
1626

17-
```json
18-
{
19-
"extends": "@exercism/eslint-config-javascript/maintainers"
20-
}
27+
// ...
28+
export default [
29+
...baseConfig,
30+
// ... your configuration
31+
];
2132
```
2233

2334
## Students configuration
2435

25-
Find the student configuration [here](index.js). It's goal is to help detect and prevent common problems, without making _any_ decisions about code-style.
36+
Find the student configuration [here](index.mjs).
37+
It's goal is to help detect and prevent common problems, without making _any_ decisions about code-style.
2638

2739
The rules are based on:
2840

2941
- [`eslint:recommended`][web-eslint-recommended]
30-
- [`plugin:import`][git-eslint-plugin-import]
3142
- A few extra rules that catch common issues but are not enabled via the recommended plugin. See [this PR][git-javascript-pr-1094] for a bit of discussion and rationale.
3243

33-
Because the [Exercism JavaScript track][git-javascript] is primarily focussing on running the exercises on Node, only `node` and `es2021` are turned on as environment, but when extending this configuration, you can add more (or turn those off).
44+
Because the [Exercism JavaScript track][git-javascript] is primarily focussing on running the exercises on Node, only `node` globals are turned on in the environment, but when extending this configuration, you can add more (or turn those off).
3445

3546
## Maintainers configuration
3647

37-
Similar to the students configuration, and found [here](maintainers.js), it also includes the [`prettier` plugin][git-eslint-plugin-prettier] because we use [`prettier`][web-prettier] to achieve consistent code formatting. This plugin turns _off_ rules that conflict with formatting.
48+
Similar to the students configuration, and found [here](maintainers.mjs), it also includes the [`prettier` plugin][git-eslint-plugin-prettier] because we use [`prettier`][web-prettier] to achieve consistent code formatting.
49+
This plugin turns _off_ rules that conflict with formatting.
3850

3951
Additionally, it doesn't have warnings but errors for most/all of the rules in the students configuration.
4052

4153
## Tooling configuration
4254

43-
Because the tooling (such as the [JavaScript Analyzer][git-javascript-analyzer], [Representer][git-javascript-representer], and [Test Runner][git-javascript-test-runner]) are written in TypeScript, they don't use the same configuration files. If you're looking for those, or to build your own tools in TypeScript, go to [@exercism/eslint-config-tooling][git-eslint-config-tooling].
55+
Because the tooling (such as the [JavaScript Analyzer][git-javascript-analyzer], [Representer][git-javascript-representer], and [Test Runner][git-javascript-test-runner]) are written in TypeScript, they don't use the same configuration files.
56+
If you're looking for those, or to build your own tools in TypeScript, go to [@exercism/eslint-config-tooling][git-eslint-config-tooling].
57+
58+
## Development
59+
60+
If you want to work on this repository, install the dependencies using `corepack` and `pnpm`:
61+
62+
```shell
63+
corepack enable pnpm
64+
corepack pnpm install
65+
```
66+
67+
Because pnpm is configured to use isolated `node_modules` (symlinked), everything such as your tools and plugins inside your editor should keep working as expected.
4468

4569
[git-eslint-config-tooling]: https://github.com/exercism/eslint-config-tooling
4670
[git-eslint-plugin-import]: https://github.com/benmosher/eslint-plugin-import

babel.config.cjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
presets: ['@exercism/babel-preset-javascript'],
3+
plugins: [],
4+
};

eslint.config.mjs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import maintainers from './maintainers.mjs';
2+
3+
export default [
4+
...maintainers,
5+
{
6+
ignores: [
7+
'.appends/**/*',
8+
'.github/**/*',
9+
'.vscode/**/*',
10+
'.yarn/**/*',
11+
'.pnp.*',
12+
],
13+
},
14+
];

index.js

Lines changed: 0 additions & 41 deletions
This file was deleted.

index.mjs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import babelParser from '@babel/eslint-parser';
2+
import fs from 'fs';
3+
4+
import eslint from '@eslint/js';
5+
import jestPlugin from 'eslint-plugin-jest';
6+
import prettierConfig from 'eslint-config-prettier';
7+
8+
import globals from 'globals';
9+
10+
const pkg = JSON.parse(
11+
fs.readFileSync(new URL('./package.json', import.meta.url), 'utf8'),
12+
);
13+
14+
/** @type {import('eslint').ESLint.Plugin} */
15+
const plugin = {
16+
meta: {
17+
name: pkg.name + '/maintainers',
18+
version: pkg.version,
19+
},
20+
};
21+
22+
/** @type {import('eslint').Linter.Config} */
23+
export default [
24+
{
25+
...eslint.configs.recommended,
26+
plugins: {
27+
jest: jestPlugin,
28+
[plugin.meta.name]: plugin,
29+
},
30+
languageOptions: {
31+
parser: babelParser,
32+
parserOptions: {
33+
ecmaVersion: 'latest',
34+
},
35+
globals: {
36+
...globals.node,
37+
},
38+
},
39+
40+
rules: {
41+
...eslint.configs.recommended.rules,
42+
43+
// eslint rules
44+
'array-callback-return': ['warn', { checkForEach: false }],
45+
'default-param-last': 'error',
46+
eqeqeq: ['warn', 'smart'],
47+
'linebreak-style': 'off',
48+
'no-eval': ['error', { allowIndirect: true }],
49+
'no-extend-native': 'warn',
50+
'no-implicit-coercion': 'warn',
51+
'no-promise-executor-return': 'warn',
52+
'no-shadow': 'warn',
53+
'no-unreachable-loop': 'warn',
54+
'no-unsafe-optional-chaining': 'error',
55+
'require-atomic-updates': 'warn',
56+
},
57+
},
58+
59+
{
60+
// enable jest rules on test files
61+
files: ['test/**', '**/*.spec.js*', '**/*.test.js*'],
62+
...jestPlugin.configs['flat/recommended'],
63+
rules: {
64+
...jestPlugin.configs['flat/recommended'].rules,
65+
'jest/no-disabled-tests': 'off',
66+
'jest/no-test-prefixes': 'off',
67+
},
68+
languageOptions: {
69+
globals: {
70+
// Don't make jest globals available! These should not be available
71+
// but imported from @jest/globals.
72+
//
73+
// ...globals.jest,
74+
},
75+
},
76+
},
77+
78+
// https://github.com/import-js/eslint-plugin-import/pull/3018
79+
// missing: import/* plugins
80+
81+
prettierConfig,
82+
];

maintainers.js

Lines changed: 0 additions & 48 deletions
This file was deleted.

maintainers.mjs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import babelParser from '@babel/eslint-parser';
2+
import fs from 'fs';
3+
4+
import eslint from '@eslint/js';
5+
import jestPlugin from 'eslint-plugin-jest';
6+
import prettierConfig from 'eslint-config-prettier';
7+
8+
import globals from 'globals';
9+
10+
const pkg = JSON.parse(
11+
fs.readFileSync(new URL('./package.json', import.meta.url), 'utf8'),
12+
);
13+
14+
/** @type {import('eslint').ESLint.Plugin} */
15+
const plugin = {
16+
meta: {
17+
name: pkg.name + '/maintainers',
18+
version: pkg.version,
19+
},
20+
};
21+
22+
/** @type {import('eslint').Linter.Config} */
23+
export default [
24+
{
25+
...eslint.configs.recommended,
26+
plugins: {
27+
jest: jestPlugin,
28+
[plugin.meta.name]: plugin,
29+
},
30+
languageOptions: {
31+
parser: babelParser,
32+
parserOptions: {
33+
ecmaVersion: 'latest',
34+
sourceType: undefined,
35+
},
36+
globals: {
37+
...globals.node,
38+
},
39+
},
40+
41+
rules: {
42+
...eslint.configs.recommended.rules,
43+
44+
// eslint rules
45+
'array-callback-return': ['error', { checkForEach: true }],
46+
'default-param-last': 'error',
47+
eqeqeq: ['error', 'smart'],
48+
'linebreak-style': 'off',
49+
'no-eval': ['error', { allowIndirect: true }],
50+
'no-extend-native': 'error',
51+
'no-implicit-coercion': 'error',
52+
'no-promise-executor-return': 'error',
53+
'no-shadow': 'error',
54+
'no-unreachable-loop': 'error',
55+
'no-unsafe-optional-chaining': 'error',
56+
'require-atomic-updates': 'error',
57+
},
58+
},
59+
60+
{
61+
// enable jest rules on test files
62+
files: ['test/**', '**/*.spec.js*', '**/*.test.js*'],
63+
...jestPlugin.configs['flat/recommended'],
64+
rules: {
65+
...jestPlugin.configs['flat/recommended'].rules,
66+
'jest/no-disabled-tests': 'off',
67+
'jest/no-test-prefixes': 'off',
68+
},
69+
languageOptions: {
70+
globals: {
71+
// Don't make jest globals available! These should not be available
72+
// but imported from @jest/globals.
73+
//
74+
// ...globals.jest,
75+
},
76+
},
77+
},
78+
79+
// https://github.com/import-js/eslint-plugin-import/pull/3018
80+
// missing: import/* plugins
81+
82+
prettierConfig,
83+
];

0 commit comments

Comments
 (0)