mirror of
https://github.com/outline/outline.git
synced 2025-12-21 10:39:41 -06:00
Migrate from ESLint to oxlint for 50x performance improvement (#9682)
* Migrate from ESLint to oxlint - Upgraded ESLint to v9 and created flat config for migration compatibility - Used @oxlint/migrate tool to generate .oxlintrc.json configuration - Installed oxlint v1.7.0 for 50-100x performance improvement - Updated package.json scripts to use oxlint instead of eslint - Updated lint-staged configuration for pre-commit hooks - Configured ignore patterns for migrations, scripts, and build files - Removed old ESLint dependencies and configuration files - Maintained equivalent linting behavior with much faster execution Performance improvement: ~17 seconds → ~350ms (48x faster) * rules * --prefer-offline to speed up yarn install --------- Co-authored-by: codegen-sh[bot] <131295404+codegen-sh[bot]@users.noreply.github.com> Co-authored-by: Tom Moor <tom@getoutline.com>
This commit is contained in:
@@ -1 +0,0 @@
|
||||
server/migrations/*.js
|
||||
183
.eslintrc
183
.eslintrc
@@ -1,183 +0,0 @@
|
||||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
"extraFileExtensions": [
|
||||
".json"
|
||||
],
|
||||
"project": "./tsconfig.json",
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
}
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:import/recommended",
|
||||
"plugin:import/typescript",
|
||||
"prettier"
|
||||
],
|
||||
"plugins": [
|
||||
"es",
|
||||
"react",
|
||||
"@typescript-eslint",
|
||||
"eslint-plugin-import",
|
||||
"eslint-plugin-node",
|
||||
"eslint-plugin-react",
|
||||
"eslint-plugin-lodash"
|
||||
],
|
||||
"rules": {
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"paths": [
|
||||
{
|
||||
"name": "reakit/Menu",
|
||||
"importNames": [
|
||||
"useMenuState"
|
||||
],
|
||||
"message": "Do not use useMenuState from reakit/Menu. Use useMenuState instead."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"eqeqeq": 2,
|
||||
"curly": 2,
|
||||
"no-console": "error",
|
||||
"arrow-body-style": [
|
||||
"error",
|
||||
"as-needed"
|
||||
],
|
||||
"spaced-comment": "error",
|
||||
"object-shorthand": "error",
|
||||
"no-mixed-operators": "off",
|
||||
"no-useless-escape": "off",
|
||||
"no-shadow": "off",
|
||||
"es/no-regexp-lookbehind-assertions": "error",
|
||||
"react/react-in-jsx-scope": "off",
|
||||
"react/self-closing-comp": [
|
||||
"error",
|
||||
{
|
||||
"component": true,
|
||||
"html": true
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-shadow": [
|
||||
"warn",
|
||||
{
|
||||
"allow": [
|
||||
"transaction"
|
||||
],
|
||||
"hoist": "all",
|
||||
"ignoreTypeValueShadow": true
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-require-imports": "off",
|
||||
"@typescript-eslint/no-explicit-any": "warn",
|
||||
"@typescript-eslint/no-floating-promises": "error",
|
||||
"@typescript-eslint/await-thenable": "error",
|
||||
"@typescript-eslint/no-misused-promises": [
|
||||
"error",
|
||||
{
|
||||
"checksVoidReturn": false
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
"argsIgnorePattern": "^_",
|
||||
"caughtErrorsIgnorePattern": "^_",
|
||||
"args": "after-used",
|
||||
"ignoreRestSiblings": true
|
||||
}
|
||||
],
|
||||
"padding-line-between-statements": [
|
||||
"error",
|
||||
{
|
||||
"blankLine": "always",
|
||||
"prev": "*",
|
||||
"next": "export"
|
||||
}
|
||||
],
|
||||
"lines-between-class-members": [
|
||||
"error",
|
||||
"always",
|
||||
{
|
||||
"exceptAfterSingleLine": true
|
||||
}
|
||||
],
|
||||
"lodash/import-scope": [
|
||||
"error",
|
||||
"method"
|
||||
],
|
||||
"import/no-named-as-default": "off",
|
||||
"import/no-named-as-default-member": "off",
|
||||
"import/newline-after-import": 2,
|
||||
"import/order": [
|
||||
"error",
|
||||
{
|
||||
"alphabetize": {
|
||||
"order": "asc"
|
||||
},
|
||||
"pathGroups": [
|
||||
{
|
||||
"pattern": "@shared/**",
|
||||
"group": "external",
|
||||
"position": "after"
|
||||
},
|
||||
{
|
||||
"pattern": "@server/**",
|
||||
"group": "external",
|
||||
"position": "after"
|
||||
},
|
||||
{
|
||||
"pattern": "~/stores",
|
||||
"group": "external",
|
||||
"position": "after"
|
||||
},
|
||||
{
|
||||
"pattern": "~/stores/**",
|
||||
"group": "external",
|
||||
"position": "after"
|
||||
},
|
||||
{
|
||||
"pattern": "~/models/**",
|
||||
"group": "external",
|
||||
"position": "after"
|
||||
},
|
||||
{
|
||||
"pattern": "~/scenes/**",
|
||||
"group": "external",
|
||||
"position": "after"
|
||||
},
|
||||
{
|
||||
"pattern": "~/components/**",
|
||||
"group": "external",
|
||||
"position": "after"
|
||||
},
|
||||
{
|
||||
"pattern": "~/**",
|
||||
"group": "external",
|
||||
"position": "after"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"settings": {
|
||||
"react": {
|
||||
"createClass": "createReactClass",
|
||||
"pragma": "React",
|
||||
"version": "detect"
|
||||
},
|
||||
"import/parsers": {
|
||||
"@typescript-eslint/parser": [
|
||||
".ts",
|
||||
".tsx"
|
||||
]
|
||||
},
|
||||
"import/resolver": {
|
||||
"typescript": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
.github/workflows/ci.yml
vendored
12
.github/workflows/ci.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
run: yarn install --frozen-lockfile --prefer-offline
|
||||
|
||||
lint:
|
||||
needs: build
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
with:
|
||||
node-version: 22.x
|
||||
cache: "yarn"
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn install --frozen-lockfile --prefer-offline
|
||||
- run: yarn lint
|
||||
|
||||
types:
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
with:
|
||||
node-version: 22.x
|
||||
cache: "yarn"
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn install --frozen-lockfile --prefer-offline
|
||||
- run: yarn tsc
|
||||
|
||||
changes:
|
||||
@@ -98,7 +98,7 @@ jobs:
|
||||
with:
|
||||
node-version: 22.x
|
||||
cache: "yarn"
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn install --frozen-lockfile --prefer-offline
|
||||
- run: yarn test:${{ matrix.test-group }}
|
||||
|
||||
test-server:
|
||||
@@ -130,7 +130,7 @@ jobs:
|
||||
with:
|
||||
node-version: 22.x
|
||||
cache: "yarn"
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn install --frozen-lockfile --prefer-offline
|
||||
- run: yarn sequelize db:migrate
|
||||
- name: Run server tests
|
||||
run: |
|
||||
@@ -147,7 +147,7 @@ jobs:
|
||||
with:
|
||||
node-version: 22.x
|
||||
cache: "yarn"
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn install --frozen-lockfile --prefer-offline
|
||||
- name: Set environment to production
|
||||
run: echo "NODE_ENV=production" >> $GITHUB_ENV
|
||||
- run: yarn vite:build
|
||||
|
||||
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
with:
|
||||
node-version: 20.x
|
||||
cache: "yarn"
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn install --frozen-lockfile --prefer-offline
|
||||
- run: yarn lint --fix
|
||||
|
||||
- name: Commit changes
|
||||
|
||||
129
.oxlintrc.json
Normal file
129
.oxlintrc.json
Normal file
@@ -0,0 +1,129 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": [],
|
||||
"env": {
|
||||
"builtin": true
|
||||
},
|
||||
"ignorePatterns": [
|
||||
"build/**",
|
||||
"node_modules/**",
|
||||
"public/**",
|
||||
"server/migrations/**",
|
||||
"server/scripts/**",
|
||||
"patches/**",
|
||||
"*.d.ts"
|
||||
],
|
||||
"rules": {
|
||||
"for-direction": "error",
|
||||
"no-async-promise-executor": "error",
|
||||
"no-case-declarations": "error",
|
||||
"no-class-assign": "error",
|
||||
"no-compare-neg-zero": "error",
|
||||
"no-cond-assign": "error",
|
||||
"no-const-assign": "error",
|
||||
"no-constant-binary-expression": "error",
|
||||
"no-constant-condition": "error",
|
||||
"no-control-regex": "error",
|
||||
"no-debugger": "error",
|
||||
"no-delete-var": "error",
|
||||
"no-dupe-class-members": "error",
|
||||
"no-dupe-else-if": "error",
|
||||
"no-dupe-keys": "error",
|
||||
"no-duplicate-case": "error",
|
||||
"no-empty": "error",
|
||||
"no-empty-character-class": "error",
|
||||
"no-empty-pattern": "error",
|
||||
"no-empty-static-block": "error",
|
||||
"no-ex-assign": "error",
|
||||
"no-extra-boolean-cast": "error",
|
||||
"no-fallthrough": "error",
|
||||
"no-func-assign": "error",
|
||||
"no-global-assign": "error",
|
||||
"no-import-assign": "error",
|
||||
"no-invalid-regexp": "error",
|
||||
"no-irregular-whitespace": "error",
|
||||
"no-loss-of-precision": "error",
|
||||
"no-new-native-nonconstructor": "error",
|
||||
"no-nonoctal-decimal-escape": "error",
|
||||
"no-obj-calls": "error",
|
||||
"no-prototype-builtins": "error",
|
||||
"no-redeclare": "error",
|
||||
"no-regex-spaces": "error",
|
||||
"no-self-assign": "error",
|
||||
"no-setter-return": "error",
|
||||
"no-shadow-restricted-names": "error",
|
||||
"no-sparse-arrays": "error",
|
||||
"no-this-before-super": "error",
|
||||
"no-unexpected-multiline": "error",
|
||||
"no-unsafe-finally": "error",
|
||||
"no-unsafe-negation": "error",
|
||||
"no-unsafe-optional-chaining": "error",
|
||||
"no-unused-labels": "error",
|
||||
"no-unused-private-class-members": "error",
|
||||
"no-unused-vars": "error",
|
||||
"no-useless-backreference": "error",
|
||||
"no-useless-catch": "error",
|
||||
"no-useless-escape": "error",
|
||||
"no-with": "error",
|
||||
"require-yield": "error",
|
||||
"use-isnan": "error",
|
||||
"valid-typeof": "error"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"**/*.{js,jsx,ts,tsx}"
|
||||
],
|
||||
"rules": {
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"paths": [
|
||||
{
|
||||
"name": "reakit/Menu",
|
||||
"importNames": [
|
||||
"useMenuState"
|
||||
],
|
||||
"message": "Do not use useMenuState from reakit/Menu. Use useMenuState instead."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"eqeqeq": "error",
|
||||
"curly": "error",
|
||||
"no-console": "error",
|
||||
"arrow-body-style": [
|
||||
"error",
|
||||
"as-needed"
|
||||
],
|
||||
"no-useless-escape": "off",
|
||||
"react/react-in-jsx-scope": "off",
|
||||
"react/self-closing-comp": [
|
||||
"error",
|
||||
{
|
||||
"component": true,
|
||||
"html": true
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-require-imports": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"import/no-named-as-default": "off",
|
||||
"import/no-named-as-default-member": "off",
|
||||
"no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
"argsIgnorePattern": "^_",
|
||||
"caughtErrorsIgnorePattern": "^_",
|
||||
"args": "after-used",
|
||||
"ignoreRestSiblings": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"plugins": [
|
||||
"react",
|
||||
"typescript",
|
||||
"import"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
export default {
|
||||
// Run prettier first for formatting, then eslint for linting, and translation updates on changes to JS and
|
||||
// Run prettier first for formatting, then oxlint for linting, and translation updates on changes to JS and
|
||||
// TypeScript files
|
||||
"**/*.[tj]s?(x)": [
|
||||
(f) => `prettier --write ${f.join(" ")}`,
|
||||
(f) => (f.length > 20 ? `yarn lint --fix` : `eslint ${f.join(" ")} --fix`),
|
||||
(f) => (f.length > 20 ? `yarn lint` : `oxlint ${f.join(" ")}`),
|
||||
() => `yarn build:i18n`,
|
||||
() => "git add shared/i18n/locales/en_US/translation.json",
|
||||
],
|
||||
|
||||
20
package.json
20
package.json
@@ -13,8 +13,8 @@
|
||||
"dev": "NODE_ENV=development yarn concurrently -n api,collaboration -c \"blue,magenta\" \"node --inspect=0.0.0.0 build/server/index.js --services=cron,collaboration,websockets,admin,web,worker\"",
|
||||
"dev:backend": "NODE_ENV=development nodemon --exec \"yarn build:server && yarn dev\" -e js,ts,tsx --ignore *.test.ts --ignore data/ --ignore build/ --ignore app/ --ignore shared/editor --ignore server/migrations",
|
||||
"dev:watch": "NODE_ENV=development yarn concurrently -n backend,frontend \"yarn dev:backend\" \"yarn vite:dev\"",
|
||||
"lint": "eslint app server shared plugins",
|
||||
"lint:changed": "git diff --name-only --diff-filter=ACMRTUXB | grep -E '\\.(js|jsx|ts|tsx)$' | xargs -r yarn eslint --fix",
|
||||
"lint": "oxlint app server shared plugins",
|
||||
"lint:changed": "git diff --name-only --diff-filter=ACMRTUXB | grep -E '\\.(js|jsx|ts|tsx)$' | xargs -r oxlint",
|
||||
"format": "prettier --write .",
|
||||
"format:check": "prettier --check .",
|
||||
"prepare": "husky install",
|
||||
@@ -275,6 +275,8 @@
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.28.0",
|
||||
"@babel/preset-typescript": "^7.27.1",
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@eslint/js": "^9.31.0",
|
||||
"@faker-js/faker": "^8.4.1",
|
||||
"@relative-ci/agent": "^4.3.1",
|
||||
"@testing-library/react": "^12.0.0",
|
||||
@@ -340,9 +342,6 @@
|
||||
"@types/utf8": "^3.0.3",
|
||||
"@types/validator": "^13.15.0",
|
||||
"@types/yauzl": "^2.10.3",
|
||||
"@typescript-eslint/eslint-plugin": "^8.33.0",
|
||||
"@typescript-eslint/parser": "^8.33.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-jest": "^29.7.0",
|
||||
"babel-plugin-transform-inline-environment-variables": "^0.4.4",
|
||||
"babel-plugin-transform-typescript-metadata": "^0.3.2",
|
||||
@@ -350,16 +349,6 @@
|
||||
"browserslist-to-esbuild": "^1.2.0",
|
||||
"concurrently": "^8.2.2",
|
||||
"discord-api-types": "^0.37.119",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^8.10.0",
|
||||
"eslint-import-resolver-typescript": "^3.10.1",
|
||||
"eslint-plugin-es": "^4.1.0",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||
"eslint-plugin-lodash": "^7.4.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^4.6.2",
|
||||
"husky": "^8.0.3",
|
||||
"i18next-parser": "^8.13.0",
|
||||
"jest-cli": "^29.7.0",
|
||||
@@ -367,6 +356,7 @@
|
||||
"jest-fetch-mock": "^3.0.3",
|
||||
"lint-staged": "^13.3.0",
|
||||
"nodemon": "^3.1.10",
|
||||
"oxlint": "^1.7.0",
|
||||
"postinstall-postinstall": "^2.1.0",
|
||||
"prettier": "^3.6.2",
|
||||
"react-refresh": "^0.17.0",
|
||||
|
||||
Reference in New Issue
Block a user