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