francoismassart/eslint-plugin-tailwindcss

Upgrading to 3.8.1 causes "Failed to load parser '@typescript-eslint/parser'"

lewishowles opened this issue ยท 28 comments

Firstly thanks for the great plugin.

Describe the bug
I'm working on a Vue project. It's hard to pinpoint exactly what's causing this or dig deeper as running the lint fails, but I'm hoping something here triggers a thought. When updating to 3.8.1 this morning, my eslint runs started failing with Failed to load parser '@typescript-eslint/parser'. If I manually install that to see what happens, it errors about an Angular parser, but this project doesn't use Angular.

Before starting a new feature, I updated:

eslint: 8.27.0 => 8.32.0
eslint-plugin-tailwindcss: 3.7.0 => 3.8.1
eslint-plugin-vue 9.7.0 => 9.9.0

The same versions of eslint and eslint-plugin-vue are used in another project without problems, but that project is only running eslint-plugin-tailwindcss 3.8.0.

Downgrading to 3.8.0 fixes the issue.

Environment (please complete the following information):

  • OS: macOS Ventura
  • Node: 16.13.1 (also tried 19.4.0)

eslint config file or live demo
Video: https://share.cleanshot.com/Xbzbym9V

eslintrc:

module.exports = {
	root: true,
	env: {
		'node': true,
		'cypress/globals': true,
		'vue/setup-compiler-macros': true,
	},
	plugins: [
		'@babel',
		'cypress',
		'tailwindcss',
	],
	extends: [
		'eslint:recommended',
		'plugin:cypress/recommended',
		'plugin:jest-dom/recommended',
		'plugin:vue/vue3-recommended',
		'plugin:tailwindcss/recommended',
	],
	parserOptions: {
		parser: '@babel/eslint-parser',
	},
	overrides: [
		{
			files: ['**/tests/unit/**/*.spec.{j,t}s?(x)'],
			env: {
				jest: true,
			},
		},
	],
	rules: {
		'arrow-parens': ['error', 'as-needed'],
		'comma-dangle': ['error', 'always-multiline'],
		'computed-property-spacing': 'error',
		'guard-for-in': 'error',
		'indent': ['error', 'tab', { SwitchCase: 1 }],
		'lines-between-class-members': 'error',
		'max-params': ['error', 5],
		'no-alert': 'error',
		'no-await-in-loop': 'error',
		'no-bitwise': 'error',
		'no-confusing-arrow': 'error',
		'no-console': process.env.NODE_ENV === 'development' ? 'off' : ['error', { allow: ['warn', 'error'] }],
		'no-const-assign': 'error',
		'no-constant-condition': 'error',
		'no-debugger': process.env.NODE_ENV === 'development' ? 'off' : 'warn',
		'no-dupe-args': 'error',
		'no-dupe-class-members': 'error',
		'no-dupe-keys': 'error',
		'no-duplicate-case': 'error',
		'no-duplicate-imports': 'error',
		'no-empty-character-class': 'error',
		'no-empty-function': 'error',
		'no-empty': 'error',
		'no-eval': 'error',
		'no-ex-assign': 'error',
		'no-extra-boolean-cast': 'error',
		'no-extra-semi': 'error',
		'no-invalid-regexp': 'error',
		'no-irregular-whitespace': 'error',
		'no-labels': 'error',
		'no-lone-blocks': 'error',
		'no-loop-func': 'error',
		'no-loss-of-precision': 'error',
		'no-multi-spaces': 'error',
		'no-nested-ternary': 'error',
		'no-obj-calls': 'error',
		'no-prototype-builtins': 'error',
		'no-regex-spaces': 'error',
		'no-return-assign': 'error',
		'no-self-assign': 'error',
		'no-self-compare': 'error',
		'no-sequences': 'error',
		'no-setter-return': 'error',
		'no-sparse-arrays': 'error',
		'no-tabs': 'off',
		'no-template-curly-in-string': 'error',
		'no-this-before-super': 'error',
		'no-throw-literal': 'error',
		'no-trailing-spaces': 'error',
		'no-undef': 'error',
		'no-unexpected-multiline': 'error',
		'no-unneeded-ternary': 'error',
		'no-unreachable-loop': 'error',
		'no-unreachable': 'error',
		'no-unsafe-finally': 'error',
		'no-unsafe-negation': 'error',
		'no-unused-expressions': 'error',
		'no-unused-vars': 'error',
		'no-useless-catch': 'error',
		'no-useless-concat': 'error',
		'no-useless-escape': 'error',
		'no-useless-return': 'error',
		'no-var': 'error',
		'no-with': 'error',
		'padding-line-between-statements': ['error', { blankLine: 'always', prev: ['const', 'let', 'var'], next: '*'}, { blankLine: 'always', prev: ['const'], next: ['let', 'var'] }, { blankLine: 'never', prev: ['singleline-const'], next: ['singleline-const'] }, { blankLine: 'never', prev: ['singleline-let'], next: ['singleline-let'] }, { blankLine: 'always', prev: '*', next: ['multiline-let', 'multiline-const'] }, { blankLine: 'always', prev: ['multiline-let', 'multiline-const'], next: '*' }, { blankLine: 'always', prev: '*', next: 'return' }],
		'prefer-arrow-callback': 'error',
		'prefer-const': 'error',
		'prefer-object-spread': 'error',
		'prefer-rest-params': 'error',
		'prefer-spread': 'error',
		'prefer-template': 'error',
		'quote-props': ['error', 'consistent-as-needed'],
		'require-await': 'error',
		'semi': ['error', 'always'],
		'space-before-function-paren': ['error', 'never'],
		'spaced-comment': ['error', 'always', { markers: ['/'] }],
		'tailwindcss/no-custom-classname': 'off',
		'use-isnan': 'error',
		'valid-typeof': 'error',
		'vars-on-top': 'error',
		'vue/attribute-hyphenation': ['error', 'always'],
		'vue/component-definition-name-casing': ['error', 'kebab-case'],
		'vue/custom-event-name-casing': 'off',
		'vue/html-end-tags': 'error',
		'vue/html-indent': ['error', 'tab'],
		'vue/max-attributes-per-line': ['error', { singleline: 20, multiline: 1 }],
		'vue/no-multi-spaces': 'error',
		'vue/no-v-html': 'off',
		'vue/require-prop-types': ['error'],
		'vue/require-valid-default-prop': ['error'],
		'vue/singleline-html-element-content-newline': ['error', {
			ignoreWhenNoAttributes: true,
			ignoreWhenEmpty: true,
		}],
		'yoda': 'error',
	},
};

I've just encountered the same issue after upgrading to 3.8.1

The error I get is:

Error: Failed to load parser '@angular-eslint/template-parser' declared in '.eslintrc ยป plugin:tailwindcss/recommended#overrides[0]': Cannot find module '@angular-eslint/template-parser'

Installing @angular-eslint/template-pareser manually still doesn't solve it though.

@lewishowles & @CosAnca please try this beta version:

npm i eslint-plugin-tailwindcss@3.8.2-beta.0

For me, that stops it erroring with regards to parsers, but it still gives an error I saw originally that I struggled to pin down, which is actually coming back to an eslint-plugin-vue function in one of my Vue components. But I think that's a red herring as turning that rule off shows the same error in another rule, removing that component shows it in another, and so on.

In case it's useful I see this:

TypeError: programNode.body is not iterable
Occurred while linting /src/components/admin-header/get-help.vue:1
Rule: "vue/no-async-in-computed-properties"
    at ReferenceTracker.iterateEsmReferences (/node_modules/eslint-utils/index.js:1577:40)
    at iterateEsmReferences.next (<anonymous>)
    at Program (/node_modules/eslint-plugin-vue/lib/rules/no-async-in-computed-properties.js:267:29)
    at ruleErrorHandler (/node_modules/eslint/lib/linter/linter.js:1118:28)
    at /node_modules/eslint/lib/linter/safe-emitter.js:45:58
    at Array.forEach (<anonymous>)
    at Object.emit (/node_modules/eslint/lib/linter/safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (/node_modules/eslint/lib/linter/node-event-generator.js:297:26)
    at NodeEventGenerator.applySelectors (/node_modules/eslint/lib/linter/node-event-generator.js:326:22)
    at NodeEventGenerator.enterNode (/node_modules/eslint/lib/linter/node-event-generator.js:340:14)

Again going back to 3.8.0 stops the error occurring.

@lewishowles, how did you configure the linting of *.vue files before upgrading ?
I believe you should overwrite the "default" config introduced in 3.8.1 which is the following:

      overrides: [
        {
          files: ['*.html', '*.blade.php', '*.vue'],
          parser: '@angular-eslint/template-parser',
        },
        {
          files: ['*.ts', '*.tsx', '*.js'],
          parser: '@typescript-eslint/parser',
        },
      ],

What parser are you using, maybe I should switch to yours by default for vue files.

I haven't changed anything in my eslintrc - it could be that I need to.

I believe it's just using @babel/eslint-parser:

parserOptions: {
	parser: '@babel/eslint-parser',
},

and then I'm using eslint-plugin-vue via

extends: [
	'plugin:vue/vue3-recommended',
	...
],

Though I do need to rebuild these projects using Vite, which is on the list... That might change exactly how the linting is set up.

@francoismassart Upgraded to the recommended beta version but still getting errors.

TypeError: programNode.body is not iterable
Occurred while linting /app.vue:1
Rule: "vue/no-async-in-computed-properties"
    at ReferenceTracker.iterateEsmReferences (/node_modules/eslint-utils/index.js:1577:40)
    at iterateEsmReferences.next (<anonymous>)
    at Program (/node_modules/eslint-plugin-vue/lib/rules/no-async-in-computed-properties.js:267:29)
    at ruleErrorHandler (/node_modules/eslint/lib/linter/linter.js:1118:28)
    at /node_modules/eslint/lib/linter/safe-emitter.js:45:58
    at Array.forEach (<anonymous>)
    at Object.emit (/node_modules/eslint/lib/linter/safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (/node_modules/eslint/lib/linter/node-event-generator.js:297:26)
    at NodeEventGenerator.applySelectors (/node_modules/eslint/lib/linter/node-event-generator.js:326:22)
    at NodeEventGenerator.enterNode (/node_modules/eslint/lib/linter/node-event-generator.js:340:14)

I'm on the latest estlint version 8.32.0 and this is my eslint config

{
  "root": true,
  "env": {
    "browser": true,
    "node": true
  },
  "extends": [
    "@nuxtjs/eslint-config-typescript",
    "plugin:nuxt/recommended",
    "plugin:prettier/recommended",
    "plugin:tailwindcss/recommended"
  ],
  "plugins": ["tailwindcss"],
  "rules": {
    "vue/multi-word-component-names": "off",
    "vue/no-multiple-template-root": "off"
  }
}

Downgraded eslint-plugin-tailwindcss to 3.7.1 for now where there are no errors thrown.

If you install @typescript-eslint/parser as a dev dependency, does it fix the issue?

@charkour Not for me, no. It moved the complaint to @angular-eslint/template-parser that @CosAnca is seeing - though I'm not running an Angular project.

The beta version from @francoismassart seems to remove that but allows the other issue to surface, but it looks like there's progress there.

Still getting the same error as above after installing @typescript-eslint/parser.
I've also removed the node_modules and the lock file and re-installed all dependencies but no luck.

@lewishowles, @charkour, @CosAnca

๐Ÿ‘‰ Are you also getting these errors using v3.8.0?

It seems like setting a default parser based on the file extension in the recommended preset was not such a good idea.

  • it can create new dependencies even if you don't use some of the file extensions
  • which also has an negative impact on the bundle size (even if this plugin lives in the devDepencies)
  • it's obviously causes you runtime error

If I read through the recommended preset of mainstream eslint plugins such as typescript-eslint or eslint-plugin-react, they don't do it.

I only saw it in eslint-plugin-vue so I guess, I'll revert this and update the install documentation with recommended parsers section.

๐Ÿ‘‰ What parser are you using for eslint-plugin-tailwindcss for each linted file extension?

Thank you for your feedback

If someone have a project A that use an eslint plugin B
Plugin B dependencies has no impact on project A build size

I don't understand why html parser could not be a dependency of this eslint plugin that want to cover lint in various files and contexts

@francoismassart No errors at all on v3.8.0.

For parsers I am only specifying the one above, @babel/eslint-parser, and as you mention it looks like eslint-plugin-vue is using vue-eslint-parser

@Shuunen , the bundle size I'm talking about is the total bundle size of eslint-plugin-tailwindcss and its dependencies.
By adding the default parsers in the preset, the code require them to be present as a dependency even if not used in the project...

I don't think it is a best practice to define the parser in the preset, I might be wrong, I'm no eslint expert ๐Ÿ˜…

Apart from the bundle size aspect, the issue is that it will overwrite the optional existing parser setting:

eslintrc file parser => eslint-plugin-tailwindcss recommended preset

Let's say you need 2 different parsers for the same file extension, I don't know if this can be done...

@Shuunen, @lewishowles, @CosAnca & @charkour

I just published eslint-plugin-tailwindcss@3.8.2-beta.1
๐Ÿ‘‰ npm i -D eslint-plugin-tailwindcss@3.8.2-beta.1

which uses vue-eslint-parser for *.vue files.

This might fix it, please test it out ๐Ÿ™

I'm personally not getting any more errors using 3.8.2-beta.1! ๐ŸŽ‰

Thanks for your help.

Faced the same issue when tried to use with react without typescript

node:internal/event_target:1006
  process.nextTick(() => { throw err; });
                           ^
Error: Failed to load parser '@typescript-eslint/parser' declared in '.eslintrc.cjs ยป plugin:tailwindcss/recommended#overrides[1]': Cannot find module 'typescript'

@retromack, are you using v3.8.2 ?

๐Ÿ‘‰ npm i -D eslint-plugin-tailwindcss@3.8.2

In the demo repo, I'm not using typescript and npm run lint works fine.

See the recommended branch:
https://github.com/francoismassart/demo-eslint-plugin-tailwindcss/tree/recommended

@francoismassart yes i'm using v3.8.2. I have just initialized a new project with vite then installed tailwindcss and eslint. I then installed the plugin, when i started the dev server i got that error

@retromack would you mind publishing a simplified / minimalist copy of the project on a repo, so that I can try to debug this ?

Thanks

Just to circle back, my team hasn't had any issues, but we were using @typescript-eslint/parser in our ESLint config prior to the plugin changes.

Hope this helps. Thank you for your continued support!

@francoismassart i tried deleting node_modules folder and reinstalling the dependencies. Everything works as expected!

3.8.0 works stable

3.8.2 error

Error: Failed to load parser '@typescript-eslint/parser' declared in '.eslintrc.json ยป plugin:tailwindcss/recommended#overrides[1]': Cannot find module 'typescript'

Project without typescript

@gldkru, did you try to rm -rf your node_modules folder ?
I have a demo which is not using typescript as well in the dependencies and it works fine, see https://github.com/francoismassart/demo-eslint-plugin-tailwindcss/tree/recommended

@gldkru, did you try to rm -rf your node_modules folder ? I have a demo which is not using typescript as well in the dependencies and it works fine, see https://github.com/francoismassart/demo-eslint-plugin-tailwindcss/tree/recommended

Yes, I did. I removed folder node_modules and yarn.lock file.
After use yarn install and yarn lint I see this error
image

@gldkru can you share your eslintrc ?

@gldkru can you share your eslintrc ?

{
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:jsx-a11y/recommended",
    "plugin:prettier/recommended",
    "plugin:tailwindcss/recommended",
    "prettier"
  ],
  "rules": {
    "react/prop-types": 0,
    "no-console": 1,
    "react-hooks/rules-of-hooks": 2,
    "react/react-in-jsx-scope": "off",
    "react/jsx-filename-extension": [
      1,
      {
        "extensions": [".ts", ".tsx", ".js", ".jsx"]
      }
    ],
    "no-nested-ternary": "off",
    "import/prefer-default-export": "off"
  },
  "plugins": [
    "react",
    "jsx-a11y",
    "react-hooks",
    "tailwindcss"
  ],
  "parserOptions": {
    "ecmaVersion": 2018,
    "sourceType": "module",
    "ecmaFeatures": {
        "jsx": true
    }
  },
  "env": {
    "es6": true,
    "browser": true,
    "node": true,
    "commonjs": true
  },
  "settings": {
    "react": {
        "version": "detect"
    }
  }
}