Linting a Vue SFC containing JSX throws a parsing error
See original GitHub issueThe following Vue SFC causes a lint error:
<script setup lang="jsx">
const JsxElement = (
<div>
Rendered from JSX!
</div>
)
</script>
<template>
<JsxElement />
</template>
Repro: https://github.com/leonzalion/vue-eslint-plugin-jsx-bug
I did some debugging, and I think the problem has to do with the .vue file extension when the file is passed to @typescript-eslint/parser
.
This is the parserOptions
configuration passed to @typescript-eslint/parser
at this line: https://github.com/vuejs/vue-eslint-parser/blob/c476e7c25ab161b336339448765085e6219d0e04/src/script/index.ts#L555
{
comment: true,
loc: true,
range: true,
tokens: true,
ecmaVersion: undefined,
sourceType: 'module',
parser: '@typescript-eslint/parser',
project: '/Users/leonzalion/projects/jsx-test/tsconfig.json',
extraFileExtensions: [ '.vue' ],
ecmaFeatures: { jsx: true, globalReturn: false },
raw: true,
eslintVisitorKeys: true,
eslintScopeManager: true,
filePath: '/Users/leonzalion/projects/jsx-test/src/app.vue'
}
When I modified the JavaScript code and only changed the above parserOptions.filePath parameter from app.vue
to app.jsx
, the linter didn’t throw any error.
I then traced down the bug through the @typescript-eslint/parser
code and I think it has to do with the following line: https://github.com/typescript-eslint/typescript-eslint/blob/5e794512bf124c39de76d4e2cf8a3d6cfb08f1a8/packages/typescript-estree/src/create-program/createWatchProgram.ts#L351
I think this line causes TypeScript to try and infer the type of the file based on the file extension, and because the file extension in .vue
(which TypeScript doesn’t recognize), TypeScript treats the file as a .ts
file by default, causing the parsing to fail since the file is actually a JSX file.
(Sidenote: when I tried changing that line to ts.ScriptKind.TSX
, it gave me the following error:)
When I modified the TypeScript compiler code and added a case ".vue":
under this line, the lint then started working again (you can test this by running npx patch-package && npm lint
in the repro).
As somebody who isn’t really experienced with the internals of ESLint, I’m not exactly sure what the best way to fix this is, so please let me know what you think!
Issue Analytics
- State:
- Created a year ago
- Reactions:1
- Comments:8 (5 by maintainers)
Top GitHub Comments
You may be able to patch it personally by putting the following script in
.eslintrc.js
.Thank you for posting this issue.
I think it’s a
typescript-eslint/parser
spec. It is documented in the following link. https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/parser#parseroptionsecmafeaturesjsxI think you need to stop using JSX in
.vue
file, emptyparserOptions.project
, or use another parser.