Closed juzi214032 closed 3 years ago
That is indeed a long time compared to your other files.
prettier
over those files instead of going through eslint? I'm wondering if this is an issue with prettier itself rather than the eslint plugin.--debug
flag? Are there any particular files that take longer than expected time to process? I wonder if there are any files that prettier finds tough to parse - I've saw that before if you accidentally try and run large files through prettier.I was reading a tweet regarding this today and thought I should give it a try, I was surprised to see the results (this is a React Native, Typescript codebase).
TIMING=1 npm run lint
:
Rule | Time (ms) | Relative
:---------------------------------|----------:|--------:
prettier/prettier | 1333.671 | 91.6%
react/no-string-refs | 46.890 | 3.2%
@typescript-eslint/no-unused-vars | 7.696 | 0.5%
semi | 4.267 | 0.3%
react-native/no-inline-styles | 4.207 | 0.3%
react-hooks/exhaustive-deps | 3.590 | 0.2%
react-hooks/rules-of-hooks | 3.248 | 0.2%
no-obj-calls | 2.784 | 0.2%
no-div-regex | 2.560 | 0.2%
no-undef-init | 2.220 | 0.2%
cat package.json | grep -E "eslint|prettier"
:
"@react-native-community/eslint-config": "^2.0.0",
"@typescript-eslint/eslint-plugin": "^3.2.0",
"@typescript-eslint/parser": "^3.2.0",
"eslint": "^7.1.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-react-hooks": "^4.0.4",
"prettier": "^2.0.5",
cat .prettierrc.js
:
module.exports = {
bracketSpacing: true,
jsxBracketSameLine: true,
singleQuote: true,
trailingComma: 'all',
semi: false,
};
cat .eslintrc.js
:
module.exports = {
root: true,
extends: [
'@react-native-community',
'prettier/@typescript-eslint',
'plugin:prettier/recommended',
'plugin:react-hooks/recommended',
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
rules: {
semi: [2, 'never'],
},
overrides: [
{
files: ['**/*.test.js', '**/*.test.jsx', '**/*.test.ts', '**/*.test.tsx'],
env: {
jest: true,
},
},
],
}
I'm not accustomed with prettier cli's API so I don't know how to trigger the Timing=1 to compare the results, neither could I capture the output of eslint --debug
's output in order to do anything meaningful with the results (they show up on the screen too fast and then are not piped to stdout npm run lint -- --debug > res.txt
).
neither could I capture the output of eslint --debug's output in order to do anything meaningful with the results
You'll want to redirect stderr in addition to stdout to capture the debugging information: https://stackoverflow.com/questions/637827/redirect-stderr-and-stdout-in-bash
Seeing the same thing:
Rule | Time (ms) | Relative
:---------------------------------|----------:|--------:
prettier/prettier | 11580.842 | 57.7%
import/namespace | 4941.682 | 24.6%
react/no-deprecated | 465.174 | 2.3%
import/no-extraneous-dependencies | 450.004 | 2.2%
react/no-direct-mutation-state | 312.252 | 1.6%
import/no-unresolved | 237.725 | 1.2%
simple-import-sort/sort | 185.009 | 0.9%
react/no-string-refs | 181.877 | 0.9%
react/require-render-return | 160.600 | 0.8%
no-unused-vars | 159.425 | 0.8%
package.json
{
"eslint": "6.8.0",
"eslint-config-prettier": "6.9.0",
"eslint-import-resolver-babel-module": "5.1.1",
"eslint-plugin-import": "2.19.1",
"eslint-plugin-jsx-a11y": "6.2.3",
"eslint-plugin-prettier": "3.1.2",
"eslint-plugin-react": "7.17.0",
"eslint-plugin-react-hooks": "2.3.0",
"eslint-plugin-simple-import-sort": "5.0.0",
"eslint-plugin-testcafe": "0.2.1",
"prettier": "1.19.1",
}
.eslintrc.js
Same issue here. It's fast when we run Prettier via the VSCode plugin esbenp.prettier-vscode
, but it's extremely slow when we run it with ESLint.
Rule | Time (ms) | Relative
:---------------------------------|----------:|--------:
prettier/prettier | 8142.741 | 45.4%
import/no-named-as-default | 2217.457 | 12.4%
import/no-extraneous-dependencies | 1190.158 | 6.6%
import/named | 712.467 | 4.0%
import/no-unresolved | 405.091 | 2.3%
react/sort-comp | 303.724 | 1.7%
react/no-deprecated | 278.299 | 1.6%
react/jsx-no-bind | 240.232 | 1.3%
import/no-duplicates | 240.053 | 1.3%
import/order | 227.723 | 1.3%
Dependencies:
"devDependencies": {
"@calm/eslint-plugin-react-intl": "^1.4.1",
"@umijs/fabric": "^2.1.1",
"babel-eslint": "^10.1.0",
"eslint": "^7.3.1",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-sort-keys-fix": "^1.1.1",
"fs-readdir-recursive": "^1.1.0",
"husky": "^4.2.5",
"jest": "^26.1.0",
"jest-expect-message": "^1.0.2",
"lerna": "^3.22.1",
"lint-staged": "^10.2.11",
"prettier": "^2.0.4",
"pretty-quick": "^2.0.1",
"stylelint": "^13.6.1",
"stylelint-prettier": "^1.1.2"
},
ESLint config:
const OFF = 0;
const WARNING = 1;
const ERROR = 2;
module.exports = {
extends: [require.resolve('@umijs/fabric/dist/eslint')],
plugins: ['prettier', 'import', 'jest'],
globals: {
REACT_APP_ENV: true,
},
env: {
node: true,
browser: true,
},
rules: {
'@typescript-eslint/no-unused-vars': [
'error',
{ varsIgnorePattern: '^_', argsIgnorePattern: '^_' },
],
'@typescript-eslint/naming-convention': OFF,
'import/no-extraneous-dependencies': WARNING,
'jsx-a11y/label-has-associated-control': OFF,
'jsx-a11y/label-has-for': OFF,
'jsx-a11y/media-has-caption': OFF,
'no-loop-func': OFF,
'no-nested-ternary': OFF,
'no-param-reassign': OFF,
'no-plusplus': OFF,
'no-return-assign': OFF,
'no-underscore-dangle': OFF,
'no-unused-expressions': OFF,
'no-unused-vars': ['error', { varsIgnorePattern: '^_', argsIgnorePattern: '^_' }],
'max-classes-per-file': OFF,
'global-require': OFF,
'prettier/prettier': ERROR,
'react/jsx-filename-extension': OFF,
'react/prop-types': OFF,
'react/require-default-props': OFF,
},
root: true,
};
Seeing the same thing here
Eslint config:
module.exports = {
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
env: {
browser: true,
jest: false,
},
parserOptions: {
ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows for the use of imports
ecmaFeatures: {
jsx: true, // Allows for the parsing of JSX
},
},
settings: {
react: {
version: 'detect', // Tells eslint-plugin-react to automatically detect the version of React to use
},
},
extends: [
'plugin:react-hooks/recommended',
'plugin:react/recommended', // Uses the recommended rules from @eslint-plugin-react
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from @typescript-eslint/eslint-plugin
'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
'plugin:prettier/recommended', // Enables eslint-plugin-prettier and eslin
],
rules: {
// Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
'react/prop-types': 0,
'react/display-name': 0,
'react/no-unescaped-entities': 0,
'arrow-parens': ['error', 'as-needed'],
'@typescript-eslint/ban-ts-comment': [0, 'allow-with-description'],
},
ignorePatterns: ['scripts', 'config', 'node_modules'],
}
@BPScott Can this problem be solved?
This looks related to the issue opened in prettier-eslint-cli repo
Seeing similar
Same here, prettier takes a lot of time, which results in really bad developer experience
Rule | Time (ms) | Relative |
---|---|---|
prettier/prettier | 4426.921 | 84.0% |
import/order | 412.818 | 7.8% |
react/no-direct-mutation-state | 91.420 | 1.7% |
@typescript-eslint/no-unused-vars | 71.658 | 1.4% |
react/no-typos | 39.917 | 0.8% |
react/require-render-return | 33.776 | 0.6% |
no-empty-character-class | 11.034 | 0.2% |
react-hooks/exhaustive-deps | 10.065 | 0.2% |
no-restricted-globals | 9.641 | 0.2% |
react-hooks/rules-of-hooks | 8.002 | 0.2% |
lint success
Same here
Rule | Time (ms) | Relative
:-------------------------------------|----------:|--------:
prettier/prettier | 29282.228 | 82.8%
compat/compat | 849.040 | 2.4%
import/no-unresolved | 704.407 | 2.0%
...
Same here
Rule | Time (ms) | Relative
:---------------------------------|----------:|--------:
prettier/prettier | 25445.485 | 44.7%
import/no-cycle | 12162.685 | 21.4%
import/extensions | 2531.717 | 4.4%
import/no-unresolved | 2133.016 | 3.7%
import/no-extraneous-dependencies | 1431.038 | 2.5%
...
same here Rule | Time (ms) | Relative |
---|---|---|
prettier/prettier | 91360.401 | 70.1% |
import/no-cycle | 10669.895 | 8.2% |
import/no-duplicates | 3134.220 | 2.4% |
import/default | 2746.444 | 2.1% |
import/named | 2690.323 | 2.1% |
import/no-unresolved | 1206.509 | 0.9% |
react/no-deprecated | 1000.266 | 0.8% |
react/jsx-no-bind | 890.601 | 0.7% |
no-unused-vars | 878.121 | 0.7% |
no-redeclare | 737.186 | 0.6% |
Rule | Time (ms) | Relative |
any updates on this?
@yekver no, I give up
Rule | Time (ms) | Relative |
---|---|---|
import/namespace | 20665.908 | 53.5% |
prettier/prettier | 10506.962 | 27.2% |
node/no-extraneous-import | 1789.480 | 4.6% |
@typescript-eslint/no-implied-eval | 1662.286 | 4.3% |
@typescript-eslint/no-misused-promises | 1268.487 | 3.3% |
@typescript-eslint/no-unused-vars | 280.963 | 0.7% |
@typescript-eslint/no-unnecessary-type-arguments | 209.879 | 0.5% |
import/no-unresolved | 194.264 | 0.5% |
@typescript-eslint/no-unnecessary-qualifier | 191.079 | 0.5% |
sonarjs/cognitive-complexity | 138.541 | 0.4% |
Bad to see import/namespace
rule is the slowest one :(
Same problem here. I'm removing this rule from my eslint config and running prettier as a separate step (it is drastically faster)
Could this be one cause? https://github.com/prettier/eslint-plugin-prettier/blob/885f48405e0fc9f312acdd3e3487c824bd59c102/eslint-plugin-prettier.js#L175-L188
This means it is stuck until reading/parsing the files finished and then it still has to run prettier.format
. import/namespace
also accesses files (e.g. fs.statSync
).
Correct me if I am wrong, but it doesn't look like eslint plugins can use any async code?
Maybe reading the prettier config files could be optimized? Instead of reading it for every file, just read it once and then watch it? I don't know. 🤷
This should be fixed as of v3.3.0.
I've known for a while that not clearing the prettier config cache is the fix for this but wanted to see if there was a way to get the performance speedup without impacting usage in editors - as with this change eslint plugins in editors keep using old cached prettier config instead of spotting when you make changes to prettier config.
The solution is easy but not ideal: "When you make a config change you may need to restart your editor for it to notice". I couldn't find fix that avoided that, but the size of the speedup is worth needing that extra step as 99% of the time you're not fiddling with settings.
@BPScott How much of a savings would you expect for v3.3.0?
In my trials running it from the CLI, comparing my old version v3.1.4
to v3.3.0
, it represents a savings of about 20%. The relative cost of prettier/prettier
in my configuration drops from about 78% to about 74%. Is that about consistent with your expectations?
Further to this, the version of prettier plays a role in execution time: prettier 2.2.1
takes about 15% longer than prettier 2.0.5
.
starting with 3.1.3
and prettier on 2.1.2
Rule | Time (ms) | Relative
:------------------------------------|-----------:|--------:
prettier/prettier | 150623.446 | 92.2%
react/no-deprecated | 3007.632 | 1.8%
react/no-direct-mutation-state | 1944.462 | 1.2%
@typescript-eslint/no-unused-vars | 1637.788 | 1.0%
react/no-string-refs | 1558.513 | 1.0%
react/require-render-return | 1457.691 | 0.9%
no-unused-vars | 313.724 | 0.2%
react/no-unknown-property | 275.788 | 0.2%
react/react-in-jsx-scope | 190.502 | 0.1%
@typescript-eslint/no-empty-function | 173.773 | 0.1%
✨ Done in 257.45s.
and now with 3.3.1
and prettier still on 2.1.2
Rule | Time (ms) | Relative
:------------------------------------|----------:|--------:
prettier/prettier | 43108.276 | 76.6%
react/no-deprecated | 3019.793 | 5.4%
react/no-direct-mutation-state | 2020.851 | 3.6%
@typescript-eslint/no-unused-vars | 1884.639 | 3.3%
react/no-string-refs | 1613.230 | 2.9%
react/require-render-return | 1471.966 | 2.6%
no-unused-vars | 315.334 | 0.6%
react/no-unknown-property | 291.186 | 0.5%
react/react-in-jsx-scope | 266.839 | 0.5%
@typescript-eslint/no-empty-function | 167.369 | 0.3%
✨ Done in 146.07s.
thx a lot @BPScott !
eslint: 8.11.0 prettier: 2.6.0 eslint-plugin-prettier: 4.0.0
Rule | Time (ms) | Relative |
---|---|---|
prettier/prettier | 153133.363 | 98.3% |
vue/attribute-hyphenation | 648.661 | 0.4% |
@typescript-eslint/no-unused-vars | 595.310 | 0.4% |
no-redeclare | 176.444 | 0.1% |
padding-line-between-statements | 144.199 | 0.1% |
max-len | 120.984 | 0.1% |
vue/valid-next-tick | 42.244 | 0.0% |
no-restricted-imports | 40.963 | 0.0% |
@typescript-eslint/no-empty-function | 39.269 | 0.0% |
@typescript-eslint/no-loss-of-precision | 39.268 | 0.0% |
This may help someone: I was able to reduce the time from 4 seconds to 370ms on my small project by creating a .prettierignore file:
build
coverage
.gitlab
.vscode
node_modules
Indeed upgrading to the latest version 4.2.1
helped a bit. Still feels slow to me, but I'm not that used the the JS-ecosystem so it might the at the fault of the project complexity. Adding a .prettierignore
mentioned above did not have any impact for me.
Before:
Rule | Time (ms) | Relative
:------------------------------------|----------:|--------:
prettier/prettier | 793.872 | 89.5%
react/display-name | 14.987 | 1.7%
react/no-deprecated | 8.424 | 0.9%
react/no-direct-mutation-state | 7.278 | 0.8%
react/no-string-refs | 5.602 | 0.6%
react/no-unknown-property | 5.157 | 0.6%
react/require-render-return | 5.021 | 0.6%
@typescript-eslint/no-empty-function | 4.726 | 0.5%
@typescript-eslint/naming-convention | 4.311 | 0.5%
react-hooks/exhaustive-deps | 3.885 | 0.4%
After:
Rule | Time (ms) | Relative
:------------------------------------|----------:|--------:
prettier/prettier | 549.801 | 89.4%
react/display-name | 11.733 | 1.9%
@typescript-eslint/naming-convention | 8.575 | 1.4%
react/no-deprecated | 4.636 | 0.8%
react/no-direct-mutation-state | 3.880 | 0.6%
react/require-render-return | 3.067 | 0.5%
react/no-string-refs | 2.937 | 0.5%
@typescript-eslint/no-empty-function | 2.641 | 0.4%
react/react-in-jsx-scope | 2.516 | 0.4%
react/no-unknown-property | 2.388 | 0.4%
Interesting :D
Rule | Time (ms) | Relative
:-----------------------------------------------|----------:|--------:
prettier/prettier | 28315.193 | 99.3%
lit/no-legacy-template-syntax | 67.812 | 0.2%
simple-import-sort/imports | 40.667 | 0.1%
@typescript-eslint/no-loss-of-precision | 24.350 | 0.1%
@typescript-eslint/no-empty-function | 13.465 | 0.0%
lit/attribute-value-entities | 7.950 | 0.0%
@typescript-eslint/no-extra-non-null-assertion | 5.667 | 0.0%
@typescript-eslint/adjacent-overload-signatures | 4.350 | 0.0%
@typescript-eslint/ban-types | 3.496 | 0.0%
@typescript-eslint/triple-slash-reference | 3.063 | 0.0%
This is with latest prettier
"@typescript-eslint/eslint-plugin": "^5.52.0",
"@typescript-eslint/parser": "^5.52.0",
"eslint": "^8.34.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-lit": "^1.8.2",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-simple-import-sort": "^10.0.0",
"prettier": "^2.8.4",
eslint.rc
module.exports = {
// Specifies the ESLint parser
parser: '@typescript-eslint/parser',
extends: [
// Uses the recommended rules from the @typescript-eslint/eslint-plugin
'plugin:@typescript-eslint/recommended',
// Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
'prettier',
'plugin:lit/recommended',
],
parserOptions: {
// Allows for the parsing of modern ECMAScript features
ecmaVersion: 2018,
// Allows for the use of imports
sourceType: 'module',
},
rules: {
'@typescript-eslint/explicit-function-return-type': 0,
'simple-import-sort/imports': 'error',
'sort-imports': 'off',
'import/order': 'off',
'prettier/prettier': [
'error',
{
trailingComma: 'es5',
semi: true,
singleQuote: true,
printWidth: 120,
endOfLine: 'auto',
},
],
indent: ['off', 2],
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/camelcase': 0,
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': ['off'],
'no-use-before-define': 'off',
'@typescript-eslint/no-use-before-define': 'off',
'lit/no-legacy-template-syntax': 'error',
'lit/no-template-arrow': 'off',
},
plugins: ['simple-import-sort', '@typescript-eslint', 'prettier', 'lit'],
};
I had a large js file with 30K line of code in my project's root directory. adding it to the .prettierignore file solved the issue for me. so, I think that the issue is not with the prettier plugin it's related to projects, just look for the large files and prettierignore it.
Don't forget to ignore .yarn
if you're using yarn berry
, it adds another few seconds on the linting step.
Example using the new flat eslint config
import eslint from "@eslint/js";
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
export default [
{
ignores: ["node_modules", ".yarn"],
},
eslint.configs.recommended,
eslintPluginPrettierRecommended
];
I have same issue with prettier:
package.json
"eslint": "^8.44.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"gatsby-plugin-linkedin-insight": "^1.0.1",
"gatsby-plugin-portal": "^1.0.7",
"gatsby-plugin-postcss": "^6.11.0",
"lint-staged": "^13.2.3",
"postcss": "^8.4.31",
"prettier": "^2.8.8",
"prettier-plugin-tailwindcss": "^0.3.0",
.eslintrc.json
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"plugin:react-hooks/recommended",
"plugin:react/recommended",
"plugin:prettier/recommended",
"plugin:@typescript-eslint/recommended"
],
"settings": {
"import/resolver": {
"node": {
"paths": ["src"],
"moduleDirectory": ["node_modules", "src/"],
"extensions": [".ts", ".tsx"]
}
},
"react": {
"version": "detect"
}
},
"ignorePatterns": [],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2021,
"sourceType": "module"
},
"plugins": ["react", "@typescript-eslint", "prettier", "import"],
"rules": {
"prettier/prettier": "error",
"no-console": "warn",
"react-hooks/exhaustive-deps": "warn",
"react/display-name": "off",
"react/react-in-jsx-scope": "off",
"import/no-default-export": "off",
"import/order": [
"error",
{
"groups": [
["external", "builtin"],
["parent", "internal"],
["index", "sibling"]
],
"newlines-between": "always"
}
],
"@typescript-eslint/no-unused-vars": [
"warn",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"caughtErrorsIgnorePattern": "^_"
}
],
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/explicit-module-boundary-types": "off"
}
}
@sjymon you're probably linting files you shouldn't be, like node_modules
, built assets or perhaps the .yarn
folder (or something similar if you're using another package manager). Try ignoring folders and files and see if that helps.
What version of
eslint
are you using? v7.2.0 What version ofprettier
are you using? v2.0.5 What version ofeslint-plugin-prettier
are you using? v3.1.3 Please paste any applicable config files that you're using (e.g..prettierrc
or.eslintrc
files)What source code are you linting? JavaScript、JSON、LESS What did you expect to happen? less time What actually happened? It takes a long time