UNPKG

7.85 kBMarkdownView Raw
1eslint-plugin-html
2==================
3
4[![NPM version](https://img.shields.io/npm/v/eslint-plugin-html.svg)](https://www.npmjs.com/package/eslint-plugin-html)
5[![Build Status](https://travis-ci.org/BenoitZugmeyer/eslint-plugin-html.svg?branch=master)](https://travis-ci.org/BenoitZugmeyer/eslint-plugin-html)
6
7
8This [`ESLint`](http://eslint.org) plugin allows linting and fixing inline scripts contained in HTML
9files.
10
11Migration to v4
12---------------
13
14`eslint-plugin-html` v4 requires at least ESLint v4.7. This is because a lot of internal changes
15occured in ESLint v4.7, including a [new API to support autofixing in
16preprocessors](https://eslint.org/docs/developer-guide/working-with-plugins#processors-in-plugins).
17If you are still using an older version of ESLint, please consider upgrading, or keep using
18`eslint-plugin-html` v3.
19
20The big feature (and breaking change) in `eslint-plugin-html` v4 is the ability to chose how [scopes
21are shared between script tags in the same HTML file](#multiple-scripts-tags-in-a-html-file).
22
23
24Migration to v3
25---------------
26
27If you are considering upgrading to v3, please read [this guide](MIGRATION_TO_V3.md).
28
29Usage
30-----
31
32Simply install via `npm install --save-dev eslint-plugin-html` and add the plugin to your ESLint
33configuration. See
34[ESLint documentation](http://eslint.org/docs/user-guide/configuring#configuring-plugins).
35
36Example:
37
38```javascript
39{
40 "plugins": [
41 "html"
42 ]
43}
44```
45
46Note: by default, when executing the `eslint` command on a directory, only `.js` files will be
47linted. You will have to specify extra extensions with the `--ext` option. Example: `eslint --ext
48.html,.js src` will lint both `.html` and `.js` files in the `src` directory. See [ESLint
49documentation](http://eslint.org/docs/user-guide/command-line-interface#ext).
50
51Multiple scripts tags in a HTML file
52------------------------------------
53
54When linting a HTML with multiple script tags, this plugin tries to emulate the browser behavior by
55sharing the global scope between scripts by default. This behavior doesn't apply to "module"
56scripts (ie: `<script type="module">` and most transpiled code), where [each script tag gets its own
57top-level scope](http://exploringjs.com/es6/ch_modules.html#_modules).
58
59ESLint has already [an
60option](https://eslint.org/docs/user-guide/configuring#specifying-parser-options) to tell the parser
61if the script are modules. `eslint-plugin-html` will use this option as well to know if the scopes
62should be shared (the default) or not. To change this, just set it in your ESLint configuration:
63
64```
65{
66 "parserOptions": {
67 "sourceType": "module"
68 }
69}
70```
71
72To illustrate this behavior, consider this HTML extract:
73
74```html
75<script>
76var foo = 1;
77</script>
78
79<script>
80alert(foo);
81</script>
82```
83
84This is perfectly valid by default, and the ESLint rules `no-unused-vars` and `no-undef` shouldn't
85complain. But if those scripts are considerated as ES modules, `no-unused-vars` should report an
86error in the first script, and `no-undef` should report an error in the second script.
87
88### History
89
90In `eslint-plugin-html` v1 and v2, script code were concatenated and linted in a single pass, so
91the scope were always shared. This caused [some issues](MIGRATION_TO_V3.md), so in v3 all scripts
92were linted separately, and scopes were never shared. In v4, the plugin still lint scripts
93separately, but makes sure global variables are declared and used correctly in the non-module case.
94
95
96XML support
97-----------
98
99This plugin parses HTML and XML markup slightly differently, mainly when considering `CDATA`
100sections:
101* in XML, any data inside a `CDATA` section will be considered as raw text (not XML) and the `CDATA`
102 delimiter will be droped ;
103* in HTML, there is no such thing for `<script>` tags: the `CDATA` delimiter is considered as normal
104 text and thus, part of the script.
105
106
107Settings
108--------
109
110> Note: all settings can be written either as `"html/key": value` or in a nested object `"html": {
111> "key": value }`
112
113### `html/html-extensions`
114
115By default, this plugin will only consider files ending with those extensions as HTML: `.erb`,
116`.handlebars`, `.hbs`, `.htm`, `.html`, `.mustache`, `.nunjucks`, `.php`, `.tag`, `.twig`, `.we`.
117You can set your own list of HTML extensions by using this setting. Example:
118
119```javascript
120{
121 "plugins": [ "html" ],
122 "settings": {
123 "html/html-extensions": [".html", ".we"], // consider .html and .we files as HTML
124 }
125}
126```
127
128
129### `html/xml-extensions`
130
131By default, this plugin will only consider files ending with those extensions as XML: `.xhtml`,
132`.xml`. You can set your own list of XML extensions by using this setting. Example:
133
134```javascript
135{
136 "plugins": [ "html" ],
137 "settings": {
138 "html/xml-extensions": [".html"], // consider .html files as XML
139 }
140}
141```
142
143
144### `html/indent`
145
146By default, the code between `<script>` tags is dedented according to the first non-empty line. The
147setting `html/indent` allows to ensure that every script tags follow an uniform indentation. Like
148the `indent` rule, you can pass a number of spaces, or `"tab"` to indent with one tab. Prefix this
149value with a `+` to be relative to the `<script>` tag indentation. Example:
150
151```javascript
152{
153 "plugins": [ "html" ],
154 "settings": {
155 "html/indent": "0", // code should start at the beginning of the line (no initial indentation).
156 "html/indent": "+2", // indentation is the <script> indentation plus two spaces.
157 "html/indent": "tab", // indentation is one tab at the beginning of the line.
158 }
159}
160```
161
162
163### `html/report-bad-indent`
164
165By default, this plugin won't warn if it encounters a problematic indentation (ex: a line is under
166indented). If you want to make sure the indentation is correct, use the `html/report-bad-indent` in
167conjunction with the `indent` rule. Pass `"warn"` or `1` to display warnings, `"error"` or `2` to
168display errors. Example:
169
170```javascript
171{
172 "plugins": [ "html" ],
173 "settings": {
174 "html/report-bad-indent": "error",
175 }
176}
177```
178
179
180### `html/javascript-mime-types`
181
182By default, the code between `<script>` tags is considered as JavaScript code only if there is no
183`type` attribute or if its value matches the pattern
184`(application|text)/(x-)?(javascript|babel|ecmascript-6)` or `module` (case insensitive). You can
185customize the types that should be considered as JavaScript by providing one or multiple MIME types.
186If a MIME type starts with a `/`, it will be considered as a regular expression. Example:
187
188```javascript
189{
190 "plugins": [ "html" ],
191 "settings": {
192 "html/javascript-mime-types": ["text/javascript", "text/jsx"], // also use script tags with a "text/jsx" type attribute
193 "html/javascript-mime-types": "/^text\\/(javascript|jsx)$/", // same thing
194 }
195}
196```
197
198Troubleshooting
199---------------
200
201### Linting templates (or PHP)
202
203`eslint-plugin-html` won't evaluate or remove your template markup. If you have template markup in
204your script tags, the resulting script may not be valid JavaScript, so `ESLint` will fail to parse
205it.
206
207One possible hacky workaround to make sure the code is valid JavaScript is to put your template
208markup inside a comment. When the template is rendered, the generated JS code must start with a new
209line, so it will be written below the comment. PHP example:
210
211```html
212<script>
213var mydata;
214// <?= "\n mydata = " . json_encode($var) . ";" ?>
215console.log(mydata);
216</script>
217```
218
219
220### Linting VUE files
221
222Initially, [`eslint-plugin-vue`](https://github.com/vuejs/eslint-plugin-vue) was using
223`eslint-plugin-html` to lint code inside script tags. Since v3, `eslint-plugin-vue` is using its
224own parser, so it is *incompatible* with `eslint-plugin-html`. You should use `eslint-plugin-vue`
225exclusively and remove `eslint-plugin-html` from your dependencies if you still have it.