1 | # vue-eslint-parser
|
2 |
|
3 | [![npm version](https://img.shields.io/npm/v/vue-eslint-parser.svg)](https://www.npmjs.com/package/vue-eslint-parser)
|
4 | [![Downloads/month](https://img.shields.io/npm/dm/vue-eslint-parser.svg)](http://www.npmtrends.com/vue-eslint-parser)
|
5 | [![Build Status](https://github.com/vuejs/vue-eslint-parser/workflows/CI/badge.svg)](https://github.com/vuejs/vue-eslint-parser/actions)
|
6 | [![Coverage Status](https://codecov.io/gh/vuejs/vue-eslint-parser/branch/master/graph/badge.svg)](https://codecov.io/gh/vuejs/vue-eslint-parser)
|
7 |
|
8 | The ESLint custom parser for `.vue` files.
|
9 |
|
10 | ## โคด๏ธ Motivation
|
11 |
|
12 | This parser allows us to lint the `<template>` of `.vue` files. We can make mistakes easily on `<template>` if we use complex directives and expressions in the template. This parser and the rules of [eslint-plugin-vue](https://github.com/vuejs/eslint-plugin-vue) would catch some of the mistakes.
|
13 |
|
14 | ## ๐ฟ Installation
|
15 |
|
16 | ```bash
|
17 | npm install --save-dev eslint vue-eslint-parser
|
18 | ```
|
19 |
|
20 | - Requires Node.js ^14.17.0, 16.0.0 or later.
|
21 | - Requires ESLint 6.0.0 or later.
|
22 |
|
23 | ## ๐ Usage
|
24 |
|
25 | 1. Write `parser` option into your `.eslintrc.*` file.
|
26 | 2. Use glob patterns or `--ext .vue` CLI option.
|
27 |
|
28 | ```json
|
29 | {
|
30 | "extends": "eslint:recommended",
|
31 | "parser": "vue-eslint-parser"
|
32 | }
|
33 | ```
|
34 |
|
35 | ```console
|
36 | $ eslint "src/**/*.{js,vue}"
|
37 | # or
|
38 | $ eslint src --ext .vue
|
39 | ```
|
40 |
|
41 | ## ๐ง Options
|
42 |
|
43 | `parserOptions` has the same properties as what [espree](https://github.com/eslint/espree#usage), the default parser of ESLint, is supporting.
|
44 | For example:
|
45 |
|
46 | ```json
|
47 | {
|
48 | "parser": "vue-eslint-parser",
|
49 | "parserOptions": {
|
50 | "sourceType": "module",
|
51 | "ecmaVersion": 2018,
|
52 | "ecmaFeatures": {
|
53 | "globalReturn": false,
|
54 | "impliedStrict": false,
|
55 | "jsx": false
|
56 | }
|
57 | }
|
58 | }
|
59 | ```
|
60 |
|
61 | ### parserOptions.parser
|
62 |
|
63 | You can use `parserOptions.parser` property to specify a custom parser to parse `<script>` tags.
|
64 | Other properties than parser would be given to the specified parser.
|
65 | For example:
|
66 |
|
67 | ```json
|
68 | {
|
69 | "parser": "vue-eslint-parser",
|
70 | "parserOptions": {
|
71 | "parser": "@babel/eslint-parser",
|
72 | "sourceType": "module"
|
73 | }
|
74 | }
|
75 | ```
|
76 |
|
77 | ```json
|
78 | {
|
79 | "parser": "vue-eslint-parser",
|
80 | "parserOptions": {
|
81 | "parser": "@typescript-eslint/parser",
|
82 | "sourceType": "module"
|
83 | }
|
84 | }
|
85 | ```
|
86 |
|
87 | You can also specify an object and change the parser separately for `<script lang="...">`.
|
88 |
|
89 | ```jsonc
|
90 | {
|
91 | "parser": "vue-eslint-parser",
|
92 | "parserOptions": {
|
93 | "parser": {
|
94 | // Script parser for `<script>`
|
95 | "js": "espree",
|
96 |
|
97 | // Script parser for `<script lang="ts">`
|
98 | "ts": "@typescript-eslint/parser",
|
99 |
|
100 | // Script parser for vue directives (e.g. `v-if=` or `:attribute=`)
|
101 | // and vue interpolations (e.g. `{{variable}}`).
|
102 | // If not specified, the parser determined by `<script lang ="...">` is used.
|
103 | "<template>": "espree",
|
104 | }
|
105 | }
|
106 | }
|
107 | ```
|
108 |
|
109 | When using JavaScript configuration (`.eslintrc.js`), you can also give the parser object directly.
|
110 |
|
111 | ```js
|
112 | const tsParser = require("@typescript-eslint/parser")
|
113 | const espree = require("espree")
|
114 |
|
115 | module.exports = {
|
116 | parser: "vue-eslint-parser",
|
117 | parserOptions: {
|
118 | // Single parser
|
119 | parser: tsParser,
|
120 | // Multiple parser
|
121 | parser: {
|
122 | js: espree,
|
123 | ts: tsParser,
|
124 | }
|
125 | },
|
126 | }
|
127 | ```
|
128 |
|
129 | If the `parserOptions.parser` is `false`, the `vue-eslint-parser` skips parsing `<script>` tags completely.
|
130 | This is useful for people who use the language ESLint community doesn't provide custom parser implementation.
|
131 |
|
132 | ### parserOptions.vueFeatures
|
133 |
|
134 | You can use `parserOptions.vueFeatures` property to specify how to parse related to Vue features.
|
135 | For example:
|
136 |
|
137 | ```json
|
138 | {
|
139 | "parser": "vue-eslint-parser",
|
140 | "parserOptions": {
|
141 | "vueFeatures": {
|
142 | "filter": true,
|
143 | "interpolationAsNonHTML": true,
|
144 | "styleCSSVariableInjection": true,
|
145 | "customMacros": []
|
146 | }
|
147 | }
|
148 | }
|
149 | ```
|
150 |
|
151 | ### parserOptions.vueFeatures.filter
|
152 |
|
153 | You can use `parserOptions.vueFeatures.filter` property to specify whether to parse the Vue2 filter. If you specify `false`, the parser does not parse `|` as a filter.
|
154 | For example:
|
155 |
|
156 | ```json
|
157 | {
|
158 | "parser": "vue-eslint-parser",
|
159 | "parserOptions": {
|
160 | "vueFeatures": {
|
161 | "filter": false
|
162 | }
|
163 | }
|
164 | }
|
165 | ```
|
166 |
|
167 | If you specify `false`, it can be parsed in the same way as Vue 3.
|
168 | The following template parses as a bitwise operation.
|
169 |
|
170 | ```vue
|
171 | <template>
|
172 | <div>{{ a | b }}</div>
|
173 | </template>
|
174 | ```
|
175 |
|
176 | However, the following template that are valid in Vue 2 cannot be parsed.
|
177 |
|
178 | ```vue
|
179 | <template>
|
180 | <div>{{ a | valid:filter }}</div>
|
181 | </template>
|
182 | ```
|
183 |
|
184 | ### parserOptions.vueFeatures.interpolationAsNonHTML
|
185 |
|
186 | You can use `parserOptions.vueFeatures.interpolationAsNonHTML` property to specify whether to parse the interpolation as HTML. If you specify `true`, the parser handles the interpolation as non-HTML (However, you can use HTML escaping in the interpolation). Default is `true`.
|
187 | For example:
|
188 |
|
189 | ```json
|
190 | {
|
191 | "parser": "vue-eslint-parser",
|
192 | "parserOptions": {
|
193 | "vueFeatures": {
|
194 | "interpolationAsNonHTML": true
|
195 | }
|
196 | }
|
197 | }
|
198 | ```
|
199 |
|
200 | If you specify `true`, it can be parsed in the same way as Vue 3.
|
201 | The following template can be parsed well.
|
202 |
|
203 | ```vue
|
204 | <template>
|
205 | <div>{{a<b}}</div>
|
206 | </template>
|
207 | ```
|
208 |
|
209 | But, it cannot be parsed with Vue 2.
|
210 |
|
211 | ### parserOptions.vueFeatures.styleCSSVariableInjection
|
212 |
|
213 | If set to `true`, to parse expressions in `v-bind` CSS functions inside `<style>` tags. `v-bind()` is parsed into the `VExpressionContainer` AST node and held in the `VElement` of `<style>`. Default is `true`.
|
214 |
|
215 | See also to [here](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0043-sfc-style-variables.md).
|
216 |
|
217 | ### parserOptions.vueFeatures.customMacros
|
218 |
|
219 | Specifies an array of names of custom macros other than Vue standard macros.
|
220 | For example, if you have a custom macro `defineFoo()` and you want it processed by the parser, specify `["defineFoo"]`.
|
221 |
|
222 | Note that this option only works in `<script setup>`.
|
223 |
|
224 | ### parserOptions.templateTokenizer
|
225 |
|
226 | **This is an experimental feature. It may be changed or deleted without notice in the minor version.**
|
227 |
|
228 | You can use `parserOptions.templateTokenizer` property to specify custom tokenizers to parse `<template lang="...">` tags.
|
229 |
|
230 | For example to enable parsing of pug templates:
|
231 |
|
232 | ```jsonc
|
233 | {
|
234 | "parser": "vue-eslint-parser",
|
235 | "parserOptions": {
|
236 | "templateTokenizer": {
|
237 | // template tokenizer for `<template lang="pug">`
|
238 | "pug": "vue-eslint-parser-template-tokenizer-pug",
|
239 | }
|
240 | }
|
241 | }
|
242 | ```
|
243 |
|
244 | This option is only intended for plugin developers. **Be careful** when using this option directly, as it may change behaviour of rules you might have enabled.
|
245 | If you just want **pug** support, use [eslint-plugin-vue-pug](https://github.com/rashfael/eslint-plugin-vue-pug) instead, which uses this option internally.
|
246 |
|
247 | See [implementing-custom-template-tokenizers.md](./docs/implementing-custom-template-tokenizers.md) for information on creating your own template tokenizer.
|
248 |
|
249 | ## ๐ Usage for custom rules / plugins
|
250 |
|
251 | - This parser provides `parserServices` to traverse `<template>`.
|
252 | - `defineTemplateBodyVisitor(templateVisitor, scriptVisitor, options)` ... returns ESLint visitor to traverse `<template>`.
|
253 | - `getTemplateBodyTokenStore()` ... returns ESLint `TokenStore` to get the tokens of `<template>`.
|
254 | - `getDocumentFragment()` ... returns the root `VDocumentFragment`.
|
255 | - `defineCustomBlocksVisitor(context, customParser, rule, scriptVisitor)` ... returns ESLint visitor that parses and traverses the contents of the custom block.
|
256 | - `defineDocumentVisitor(documentVisitor, options)` ... returns ESLint visitor to traverses the document.
|
257 | - [ast.md](./docs/ast.md) is `<template>` AST specification.
|
258 | - [mustache-interpolation-spacing.js](https://github.com/vuejs/eslint-plugin-vue/blob/b434ff99d37f35570fa351681e43ba2cf5746db3/lib/rules/mustache-interpolation-spacing.js) is an example.
|
259 |
|
260 | ### `defineTemplateBodyVisitor(templateBodyVisitor, scriptVisitor, options)`
|
261 |
|
262 | *Arguments*
|
263 |
|
264 | - `templateBodyVisitor` ... Event handlers for `<template>`.
|
265 | - `scriptVisitor` ... Event handlers for `<script>` or scripts. (optional)
|
266 | - `options` ... Options. (optional)
|
267 | - `templateBodyTriggerSelector` ... Script AST node selector that triggers the templateBodyVisitor. Default is `"Program:exit"`. (optional)
|
268 |
|
269 | ```ts
|
270 | import { AST } from "vue-eslint-parser"
|
271 |
|
272 | export function create(context) {
|
273 | return context.parserServices.defineTemplateBodyVisitor(
|
274 | // Event handlers for <template>.
|
275 | {
|
276 | VElement(node: AST.VElement): void {
|
277 | //...
|
278 | }
|
279 | },
|
280 | // Event handlers for <script> or scripts. (optional)
|
281 | {
|
282 | Program(node: AST.ESLintProgram): void {
|
283 | //...
|
284 | }
|
285 | },
|
286 | // Options. (optional)
|
287 | {
|
288 | templateBodyTriggerSelector: "Program:exit"
|
289 | }
|
290 | )
|
291 | }
|
292 | ```
|
293 |
|
294 | ## โ ๏ธ Known Limitations
|
295 |
|
296 | Some rules make warnings due to the outside of `<script>` tags.
|
297 | Please disable those rules for `.vue` files as necessary.
|
298 |
|
299 | - [eol-last](http://eslint.org/docs/rules/eol-last)
|
300 | - [linebreak-style](http://eslint.org/docs/rules/linebreak-style)
|
301 | - [max-len](http://eslint.org/docs/rules/max-len)
|
302 | - [max-lines](http://eslint.org/docs/rules/max-lines)
|
303 | - [no-trailing-spaces](http://eslint.org/docs/rules/no-trailing-spaces)
|
304 | - [unicode-bom](http://eslint.org/docs/rules/unicode-bom)
|
305 | - Other rules which are using the source code text instead of AST might be confused as well.
|
306 |
|
307 | ## ๐ฐ Changelog
|
308 |
|
309 | - [GitHub Releases](https://github.com/vuejs/vue-eslint-parser/releases)
|
310 |
|
311 | ## ๐ป Contributing
|
312 |
|
313 | Welcome contributing!
|
314 |
|
315 | Please use GitHub's Issues/PRs.
|
316 |
|
317 | If you want to write code, please execute `npm install && npm run setup` after you cloned this repository.
|
318 | The `npm install` command installs dependencies.
|
319 | The `npm run setup` command initializes ESLint as git submodules for tests.
|
320 |
|
321 | ### Development Tools
|
322 |
|
323 | - `npm test` runs tests and measures coverage.
|
324 | - `npm run build` compiles TypeScript source code to `index.js`, `index.js.map`, and `index.d.ts`.
|
325 | - `npm run coverage` shows the coverage result of `npm test` command with the default browser.
|
326 | - `npm run clean` removes the temporary files which are created by `npm test` and `npm run build`.
|
327 | - `npm run lint` runs ESLint.
|
328 | - `npm run setup` setups submodules to develop.
|
329 | - `npm run update-fixtures` updates files in `test/fixtures/ast` directory based on `test/fixtures/ast/*/source.vue` files.
|
330 | - `npm run watch` runs `build`, `update-fixtures`, and tests with `--watch` option.
|