BenoitZugmeyer / eslint-plugin-html

An ESLint plugin to extract and lint scripts from HTML files.
ISC License
435 stars 51 forks source link
eslint eslint-plugin html javascript

eslint-plugin-html

NPM version Tests Status

A ESLint plugin to lint and fix inline scripts contained in HTML files.

Usage

Simply install via npm install --save-dev eslint-plugin-html and add the plugin to your ESLint configuration. See ESLint documentation.

Example with ESLint 9 and above (flat config) ```javascript import html from "eslint-plugin-html" export default [ { files: ["**/*.html"], plugins: { html }, }, ] ```
Example with ESLint 8 and below ```json { "plugins": ["html"] } ```

Disabling ESLint

To temporarily disable ESLint, use the <!-- eslint-disable --> HTML comment. Re-enable it with <!-- eslint enable -->. Example:

<!-- eslint-disable -->
<script>
  var foo = 1
</script>
<!-- eslint-enable -->

To disable ESLint for the next script tag only, use the <!-- eslint-disable-next-script --> HTML comment. Example:

<!-- eslint-disable-next-script -->
<script>
  var foo = 1
</script>

Disabled script tags are completely ignored: their content will not be parsed as JavaScript. You can use this to disable script tags containing template syntax.

Linting HTML

This plugin focuses on applying ESLint rules on inline scripts contained in HTML. It does not provide any rule related to HTML. For that, you can use other plugins like @eslint-html or @angular-eslint. eslint-plugin-html is compatible with those plugins and can be used along them.

Multiple scripts tags in a HTML file

When linting a HTML with multiple script tags, this plugin tries to emulate the browser behavior by sharing the global scope between scripts by default. This behavior doesn't apply to "module" scripts (ie: <script type="module"> and most transpiled code), where each script tag gets its own top-level scope.

ESLint has already an option to tell the parser if the script are modules. eslint-plugin-html will use this option as well to know if the scopes should be shared (the default) or not. To change this, just set it in your ESLint configuration:

ESLint 9 and above (flat config) ```javascript export default [ { // ... languageOptions: { sourceType: "module", }, }, ] ```
ESLint 8 and below ```json { "parserOptions": { "sourceType": "module" } } ```

To illustrate this behavior, consider this HTML extract:

<script>
  var foo = 1
</script>

<script>
  alert(foo)
</script>

This is perfectly valid by default, and the ESLint rules no-unused-vars and no-undef shouldn't complain. But if those scripts are considerated as ES modules, no-unused-vars should report an error in the first script, and no-undef should report an error in the second script.

History

In eslint-plugin-html v1 and v2, script code were concatenated and linted in a single pass, so the scope were always shared. This caused some issues, so in v3 all scripts were linted separately, and scopes were never shared. In v4, the plugin still lint scripts separately, but makes sure global variables are declared and used correctly in the non-module case.

XML support

This plugin parses HTML and XML markup slightly differently, mainly when considering CDATA sections:

Settings

Note: all settings can be written either as "html/key": value or in a nested object "html": { "key": value }

html/html-extensions

By default, this plugin will only consider files ending with those extensions as HTML: .erb, .handlebars, .hbs, .htm, .html, .mustache, .nunjucks, .php, .tag, .twig, .we. You can set your own list of HTML extensions by using this setting. Example:

ESLint 9 and above (flat config) ```javascript export default [ { files: ["**/*.html", "**/*.we"], plugins: { html }, settings: { "html/html-extensions": [".html", ".we"], // consider .html and .we files as HTML }, }, ] ``` Note: you need to specify extensions twice, which is not ideal. This should be imporved in the future.
ESLint 8 and below ```json { "plugins": ["html"], "settings": { "html/html-extensions": [".html", ".we"] // consider .html and .we files as HTML } } ```

html/xml-extensions

By default, this plugin will only consider files ending with those extensions as XML: .xhtml, .xml. You can set your own list of XML extensions by using this setting. Example:

ESLint 9 and above (flat config) ```javascript export default [ { files: ["**/*.html"], plugins: { html }, settings: { "html/xtml-extensions": [".html"], // consider .html files as XML }, }, ] ``` Note: you need to specify extensions twice, which is not ideal. This should be imporved in the future.
ESLint 8 and below ```json { "plugins": ["html"], "settings": { "html/xml-extensions": [".html"] // consider .html files as XML } } ```

html/indent

By default, the code between <script> tags is dedented according to the first non-empty line. The setting html/indent allows to ensure that every script tags follow an uniform indentation. Like the indent rule, you can pass a number of spaces, or "tab" to indent with one tab. Prefix this value with a + to be relative to the <script> tag indentation. Example:

ESLint 9 and above (flat config) ```javascript export default [ { files: ["**/*.html"], plugins: { html }, settings: { "html/indent": "0", // code should start at the beginning of the line (no initial indentation). "html/indent": "+2", // indentation is the Githubissues.
  • Githubissues is a development platform for aggregating issues.