From 7bac8a19621abdeef57c75573a914590aab26506 Mon Sep 17 00:00:00 2001 From: Alireza Safaierad Date: Sun, 29 Oct 2023 17:49:23 +0400 Subject: [PATCH] feat: add disable expensive rule --- README.md | 28 ++++++++++++++++++++++++++++ expensive-rules.js | 13 +++++++++++++ init.d.ts | 2 ++ init.js | 3 ++- naming-convention.js | 22 +++++----------------- package.json | 1 + registerOpts.js | 2 ++ typescript.js | 2 +- 8 files changed, 54 insertions(+), 19 deletions(-) create mode 100644 expensive-rules.js diff --git a/README.md b/README.md index c10f3ba..305a3c6 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,8 @@ interface Modules { storybook?: boolean; // controls storybook plugin tailwind?: boolean; // controls tailwindcss plugin next?: boolean; // controls next plugin + prettier?: boolean; // controls prettier plugin + disableExpensiveRules?: boolean; // controls expensive rules } ``` @@ -88,6 +90,32 @@ module.exports = init({ }); ``` +## Speed Optimization! + +It's crucial to balance the benefits of linting rules against their performance impact. Below is a table highlighting the most resource-intensive linting rules encountered in a real-world React project: + +| Rule | Time (ms) | Relative | +| --------------------------------------- | --------- | -------- | +| @cspell/spellchecker | 4298.302 | 25.0% | +| prettier/prettier | 3299.631 | 19.2% | +| @typescript-eslint/no-misused-promises | 2473.767 | 14.4% | +| import/no-cycle | 1177.111 | 6.8% | +| import/namespace | 1148.731 | 6.7% | + +As illustrated, certain rules significantly increase linting time, potentially hindering the developer experience by slowing down the feedback loop. To mitigate this, you may consider disabling these resource-intensive rules in the development environment. However, they can remain active in environments where performance is less critical, such as Continuous Integration (CI) systems or during pre-commit checks (git hooks). + +To conditionally disable expensive linting rules, you can modify your configuration as follows: + +```js +module.exports = init({ + modules: { + disableExpensiveRules: !process.env.CI || !process.env.HUSKY // Or anywhere you want + }, +}); +``` + +This approach ensures a smoother development experience while still enforcing rigorous code quality checks in environments where performance is less of a concern. + ## React/NextJS configuration React/NextJS configuration should automatically work with Auto Module Detection, but if you need to have more control over the rules you can configure it through `modules.react`. diff --git a/expensive-rules.js b/expensive-rules.js new file mode 100644 index 0000000..ba3d003 --- /dev/null +++ b/expensive-rules.js @@ -0,0 +1,13 @@ +/** @type { import('eslint').Linter.Config } */ +module.exports = { + rules: { + '@typescript-eslint/no-misused-promises': 'off', + 'prettier/prettier': 'off', + 'import/no-cycle': 'off', + 'import/namespace': 'off', + 'import/no-deprecated': 'off', + 'import/named': 'off', + 'import/export': 'off', + '@typescript-eslint/no-floating-promises': 'off', + }, +}; diff --git a/init.d.ts b/init.d.ts index 893eb85..6ebb3d5 100644 --- a/init.d.ts +++ b/init.d.ts @@ -15,6 +15,8 @@ export interface Options extends Config { test?: boolean; cypress?: boolean; storybook?: boolean; + prettier?: boolean; + disableExpensiveRules?: boolean; }; } diff --git a/init.js b/init.js index 8971ada..3606854 100644 --- a/init.js +++ b/init.js @@ -32,7 +32,8 @@ function init(opts = {}) { opts.test && require.resolve('./jest'), opts.esm && require.resolve('./esm'), opts.strict && require.resolve('./strict'), - require.resolve('./prettier'), + opts.prettier && require.resolve('./prettier'), + opts.disableExpensiveRules && require.resolve('./expensive-rules'), ] .concat(extraExtends) .filter(Boolean), diff --git a/naming-convention.js b/naming-convention.js index 23fb865..0386a69 100644 --- a/naming-convention.js +++ b/naming-convention.js @@ -2,11 +2,9 @@ module.exports = [ { selector: 'default', format: ['camelCase'], - filter: { - regex: '^_+$', - match: false, - }, + filter: { regex: '^_+$', match: false }, }, + { selector: 'import', format: null }, { selector: 'function', format: ['camelCase', 'PascalCase'], @@ -15,24 +13,15 @@ module.exports = [ { selector: 'variable', format: ['camelCase', 'UPPER_CASE', 'PascalCase'], - filter: { - regex: '^_+$', - match: false, - }, + filter: { regex: '^_+$', match: false }, }, { selector: 'parameter', format: ['camelCase', 'PascalCase'], leadingUnderscore: 'allow', - filter: { - regex: '^_+$', - match: false, - }, - }, - { - selector: 'memberLike', - format: null, + filter: { regex: '^_+$', match: false }, }, + { selector: 'memberLike', format: null }, { selector: 'memberLike', modifiers: ['static'], @@ -53,7 +42,6 @@ module.exports = [ selector: 'enumMember', format: ['PascalCase'], }, - // disallow I prefix for interfaces { selector: 'interface', format: ['PascalCase'], diff --git a/package.json b/package.json index e69a238..718a530 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "node.js", "packages.js", "prettier.js", + "expensive-rules.js", "promise.js", "react.js", "registerOpts.js", diff --git a/registerOpts.js b/registerOpts.js index 698b7b7..4d4e70b 100644 --- a/registerOpts.js +++ b/registerOpts.js @@ -12,6 +12,8 @@ const defaultOptions = { typescript: hasDep('typescript'), tailwind: hasDep('tailwindcss'), cspell: hasDep('cspell'), + prettier: hasDep('prettier'), + disableExpensiveRules: false, import: true, node: true, }; diff --git a/typescript.js b/typescript.js index 3cd0e4c..eb8bd20 100644 --- a/typescript.js +++ b/typescript.js @@ -46,7 +46,7 @@ module.exports = { '@typescript-eslint/explicit-member-accessibility': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/generic-type-naming': 'off', - '@typescript-eslint/init-declarations': ['off'], + '@typescript-eslint/init-declarations': 'off', '@typescript-eslint/lines-between-class-members': ['warn', 'always', { exceptAfterSingleLine: true }], '@typescript-eslint/member-naming': 'off', '@typescript-eslint/member-ordering': 'off',