Skip to content

Commit ea912dd

Browse files
committed
Update ESLint to v10.0.2
1 parent 2da60bf commit ea912dd

5 files changed

Lines changed: 72 additions & 42 deletions

File tree

.dockerignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
!.clang-format
33
!.editorconfig
44
!entry.ts
5-
!eslint.config.js
5+
!eslint.config.mjs
66
!ruff.toml
77
!stylesheet.xml
88
!svgo.config.js

Dockerfile

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,24 +58,12 @@ echo 'source /black21-venv/bin/activate && black "$@"' > /usr/bin/black21
5858
chmod +x /usr/bin/black21
5959

6060
# Install Node dependencies
61-
#
62-
# We stay on eslint-plugin-unicorn 56.0.1 because 57+ removed support for
63-
# importing this plugin into the ESLint config as CommonJS. (We use CommonJS
64-
# instead of ESM in the ESLint config mainly because the latter requires a new
65-
# local package.json file that declares `"type": "module"`, which interferes
66-
# with other tools like SVGO). I couldn't get the `deasync` hack to work - it
67-
# just hung forever. TODO: Try updating this plugin after updating Node.js to
68-
# v22+, which has experimental support for synchronously require()-ing ESM?
69-
# https://github.com/sindresorhus/eslint-plugin-unicorn/releases/tag/v57.0.0
70-
# https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
71-
# https://nodejs.org/en/blog/announcements/v22-release-announce#support-requireing-synchronous-esm-graphs
72-
# https://github.com/eslint/eslint/issues/13684#issuecomment-722949152
7361
npm install -g \
7462
@prettier/plugin-xml@3.4.2 \
75-
eslint@9.39.2 \
63+
eslint@10.0.2 \
7664
eslint-plugin-jsdoc@62.7.1 \
77-
eslint-plugin-sort-keys@2.3.5 \
78-
eslint-plugin-unicorn@56.0.1 \
65+
eslint-plugin-perfectionist@5.6.0 \
66+
eslint-plugin-unicorn@63.0.0 \
7967
prettier@3.8.1 \
8068
svgo@4.0.1 \
8169
typescript-eslint@8.56.1
@@ -132,3 +120,5 @@ COPY --from=entry /entry.js /entry
132120
ENV COURSIER_CACHE=/tmp/coursier-cache
133121
ENV COURSIER_JVM_CACHE=/tmp/coursier-jvm-cache
134122
ENV NODE_PATH=/usr/local/lib/node_modules
123+
# .mjs import resolution doesn't respect NODE_PATH
124+
RUN ln -s /usr/local/lib/node_modules /node_modules

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This repo contains [pre-commit](https://pre-commit.com/) hooks for Duolingo deve
77
The main hook that runs several code formatters in parallel:
88

99
- [Prettier](https://github.com/prettier/prettier) v3.8.1 for CSS, HTML, JS, JSX, Markdown, Sass, TypeScript, XML, YAML
10-
- [ESLint](https://eslint.org/) v9.39.2 for JS, TypeScript
10+
- [ESLint](https://eslint.org/) v10.0.2 for JS, TypeScript
1111
- [Ruff](https://docs.astral.sh/ruff/) v0.15.5 for Python 3
1212
- [Black](https://github.com/psf/black) v21.12b0 for Python 2
1313
- [autoflake](https://github.com/myint/autoflake) v1.7.8 for Python <!-- TODO: Upgrade to v2+, restrict to Python 2, and reenable Ruff rule F401 once our Python 3 repos that were converted from Python 2 no longer use type hint comments: https://github.com/PyCQA/autoflake/issues/222#issuecomment-1419089254 -->

entry.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ const HOOKS: Record<HookName, Hook> = {
183183
"eslint",
184184
"--fix",
185185
"--config",
186-
"/eslint.config.js",
186+
"/eslint.config.mjs",
187187
...sources,
188188
);
189189
} catch {
@@ -255,7 +255,7 @@ const HOOKS: Record<HookName, Hook> = {
255255
},
256256
[HookName.Prettier]: {
257257
action: sources => run("prettier", ...PRETTIER_OPTIONS, ...sources),
258-
include: /\.(css|html?|markdown|md|scss|tsx?|ya?ml)$/,
258+
include: /\.(css|html?|markdown|md|mjs|scss|tsx?|ya?ml)$/,
259259
runAfter: [HookName.Sed, HookName.EsLint],
260260
},
261261
[HookName.PrettierJs]: {
@@ -490,7 +490,11 @@ const HOOKS: Record<HookName, Hook> = {
490490

491491
/** Files that match this pattern should never be processed */
492492
const GLOBAL_EXCLUDES = (() => {
493-
const FOLDER_EXCLUDES = [".claude/skills/.generated", "build", "node_modules"];
493+
const FOLDER_EXCLUDES = [
494+
".claude/skills/.generated",
495+
"build",
496+
"node_modules",
497+
];
494498
const FILE_EXCLUDES = [
495499
"AGENTS.md", // Generated by sync-ai-rules pre-commit hook
496500
"copilot-instructions.md", // Generated by sync-ai-rules pre-commit hook

eslint.config.js renamed to eslint.config.mjs

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
const { defineConfig } = require("eslint/config");
2-
const jsdoc = require("eslint-plugin-jsdoc");
3-
const sortKeys = require("eslint-plugin-sort-keys");
4-
const unicorn = require("eslint-plugin-unicorn");
5-
const tseslint = require("typescript-eslint");
1+
import { defineConfig } from "eslint/config";
2+
import jsdoc from "eslint-plugin-jsdoc";
3+
import perfectionist from "eslint-plugin-perfectionist";
4+
import unicorn from "eslint-plugin-unicorn";
5+
import tseslint from "typescript-eslint";
66

77
const config = {
88
files: ["**/*.{js,jsx,ts,tsx}"],
@@ -19,7 +19,7 @@ const config = {
1919
plugins: {
2020
"@typescript-eslint": tseslint.plugin,
2121
jsdoc,
22-
"sort-keys": sortKeys,
22+
perfectionist,
2323
unicorn,
2424
},
2525
//
@@ -80,17 +80,7 @@ const config = {
8080
// "prefer-object-has-own": "error",
8181
// "prefer-object-spread": "error",
8282
"prefer-template": "error",
83-
// This only sorts members within an individual import statement, not import
84-
// statements ("declarations") themselves. We disable that because this
85-
// rule sorts in a weird way: by first member rather than by module name.
86-
// The `import/order` rule provided by eslint-plugin-import does sort
87-
// declarations by module name, but we forgo that too because it groups
88-
// declarations based on environmental factors (e.g. node_modules, Node
89-
// version) that we can't easily determine or reproduce here in a
90-
// repo-agnostic way. One compromise might be to use `import/order` and
91-
// simply disable its regrouping feature in favor of whatever groups are
92-
// found in the source code to be formatted, but no such option exists :/
93-
"sort-imports": ["error", { ignoreDeclarationSort: true }],
83+
// "sort-imports": "error", // Replaced by perfectionist/sort-imports and perfectionist/sort-named-imports
9484
"sort-vars": "error",
9585
// "strict": "error",
9686
// "unicode-bom": "error",
@@ -132,8 +122,54 @@ const config = {
132122
// "jsdoc/tag-lines": "error",
133123
// "jsdoc/text-escaping": "error",
134124

135-
// sort-keys rules. https://github.com/namnm/eslint-plugin-sort-keys
136-
"sort-keys/sort-keys-fix": ["error", "asc", { natural: true }],
125+
// perfectionist rules. https://perfectionist.dev/rules
126+
"perfectionist/sort-enums": [
127+
"error",
128+
{ order: "asc", partitionByNewLine: true, type: "natural" },
129+
],
130+
"perfectionist/sort-heritage-clauses": [
131+
"error",
132+
{ order: "asc", partitionByNewLine: true, type: "natural" },
133+
],
134+
"perfectionist/sort-imports": [
135+
"error",
136+
{
137+
newlinesBetween: "ignore",
138+
newlinesInside: "ignore",
139+
order: "asc",
140+
partitionByNewLine: true,
141+
type: "natural",
142+
},
143+
],
144+
"perfectionist/sort-interfaces": [
145+
"error",
146+
{ order: "asc", partitionByNewLine: true, type: "natural" },
147+
],
148+
"perfectionist/sort-intersection-types": [
149+
"error",
150+
{ order: "asc", partitionByNewLine: true, type: "natural" },
151+
],
152+
"perfectionist/sort-named-exports": [
153+
"error",
154+
{ order: "asc", partitionByNewLine: true, type: "natural" },
155+
],
156+
"perfectionist/sort-named-imports": [
157+
"error",
158+
{ order: "asc", type: "natural" },
159+
],
160+
"perfectionist/sort-object-types": [
161+
"error",
162+
{ order: "asc", partitionByNewLine: true, type: "natural" },
163+
],
164+
"perfectionist/sort-objects": [
165+
"error",
166+
{ order: "asc", partitionByNewLine: true, type: "natural" },
167+
],
168+
// "perfectionist/sort-switch-case" // TODO: Enable once it supports partitionByNewLine
169+
"perfectionist/sort-union-types": [
170+
"error",
171+
{ order: "asc", partitionByNewLine: true, type: "natural" },
172+
],
137173

138174
// typescript-eslint rules. We exclude rules that require type info because
139175
// they're prohibitively slow. Get the list of autofixable rules by running
@@ -189,10 +225,9 @@ const config = {
189225
// "unicorn/new-for-builtins": "error",
190226
// "unicorn/no-array-for-each": "error", // Bug: fixer deletes comments
191227
// "unicorn/no-array-method-this-argument": "error",
192-
// "unicorn/no-array-push-push": "error", // Bug: fixer deletes comments
193228
// "unicorn/no-await-expression-member": "error",
194229
"unicorn/no-console-spaces": "error",
195-
// "unicorn/no-for-loop": "error", // Bug: https://github.com/sindresorhus/eslint-plugin-unicorn/issues/1802
230+
"unicorn/no-for-loop": "error",
196231
// "unicorn/no-hex-escape": "error",
197232
// "unicorn/no-lonely-if": "error", // Bug: Moves comments around
198233
"unicorn/no-negated-condition": "error",
@@ -249,6 +284,7 @@ const config = {
249284
"unicorn/prefer-regexp-test": "error",
250285
// "unicorn/prefer-set-has": "error",
251286
"unicorn/prefer-set-size": "error",
287+
// "unicorn/prefer-single-call": "error", // Bug: fixer deletes comments
252288
// "unicorn/prefer-spread": "error", // Bug: https://github.com/sindresorhus/eslint-plugin-unicorn/issues/2041
253289
// "unicorn/prefer-string-raw": "error",
254290
// "unicorn/prefer-string-replace-all": "error",
@@ -272,4 +308,4 @@ const config = {
272308
},
273309
};
274310

275-
module.exports = defineConfig([config]);
311+
export default defineConfig([config]);

0 commit comments

Comments
 (0)