How can I get ESLint to lint HTML files in VSCode?

25,222

Solution 1

I have this in <projectfolder>/.vscode/settings.json

{
  "eslint.validate": [ "javascript", "html" ]
}

I'm using an .eslintrc.js that looks like this

module.exports = {
  "env": {
    "browser": true,
    "es6": true
  },
  "plugins": [
    "eslint-plugin-html",
  ],
  "extends": "eslint:recommended",
  "rules": {
  }
};

I have lots of rules defined but didn't paste them above

Result:

enter image description here

Solution 2

Use eslint-plugin-html:

  1. Run npm install eslint-plugin-html --save-dev in your Terminal.
  2. Open .eslintrc.js and add there plugins: ["html"] right after module.exports. If you have .json or different format than the .js then just follow the pattern and add the same values on the same nesting level.
  3. Run ./node_modules/.bin/eslint --ext .html . in your terminal.

Solution 3

  • Open .html file
  • Open OUTPUT panel
  • Select ESLint channel
  • See errors and fix them

enter image description here

Share:
25,222
Alex McDermott
Author by

Alex McDermott

Updated on July 11, 2022

Comments

  • Alex McDermott
    Alex McDermott almost 2 years

    I have a Javascript browser project split over multiple files and can't get ESLint to lint the script tags of my HTML file under the same global scope so that declarations and calls of classes and functions in one file are recognised in another.

    Here is my project structure:

    project structure

    This is the contents of foo.js:

    sayHello();
    

    and bar.js:

    function sayHello() {
      console.log('Hello');
    }
    

    And I have linked them both in the HTML file:

    <html>
      <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="main.css">
        <script src="libraries/bar.js" type="text/javascript"></script>
        <script src="foo.js" type="text/javascript"></script>
      </head>
      <body>
      </body>
    </html>
    

    I thought that the solution to this was to use the eslint-plugin-html package but have tried to configure it with no luck. These are the packages I've installed locally to the project:

    Alexs-MacBook-Pro:Demo alexmcdermott$ npm list --depth=0
    [email protected] /Users/alexmcdermott/GitHub/Demo
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    └── [email protected]
    

    I'm using the VSCode editor but have also had the same problem in the terminal:

    Alexs-MacBook-Pro:Demo alexmcdermott$ npx eslint --ext .js,.html .
    
    /Users/alexmcdermott/GitHub/Demo/foo.js
      1:1  error  'sayHello' is not defined  no-undef
    
    /Users/alexmcdermott/GitHub/Demo/libraries/bar.js
      1:10  error    'sayHello' is defined but never used  no-unused-vars
      2:3   warning  Unexpected console statement          no-console
    
    ✖ 3 problems (2 errors, 1 warning)
    

    and the same in VSCode:

    vscode error

    This is my ESLint config:

    {
        "env": {
            "browser": true,
            "es6": true
        },
        "extends": "airbnb-base",
        "plugins": [ "html" ]
    }
    

    and I've also configured VSCode to run ESLint on HTML files with these options in my VSCode user settings:

    {
        "eslint.autoFixOnSave": true,
        "eslint.options": {
            "extensions": [ ".js", ".html" ]
        },
        "eslint.validate": [
            "javascript",
            {
                "language": "html",
                "autoFix": true
            }
        ]
    }
    

    Although I must be doing something wrong, or am missing the point of the eslint-plugin-html? If anyone has any input as to what I'm doing wrong or how to fix this I'd greatly appreciate it as I've been stuck on this for ages. Please let me know if I need to provide more info, I'm new to this.

  • gman
    gman over 5 years
    added my .eslintrc.js. I'm pretty sure the plugins section can be just "html". You installed it though right? npm install --save-dev eslint-plugin-html?
  • Alex McDermott
    Alex McDermott over 5 years
    Hi thanks for the response. I believe I have that as well if you look at the last two pictures. I just specified my validations in the user settings not the workplace settings for VSCode. Although I just tried your way as well but it didn't work. I know it is referencing my config file because it makes other syntactical changes on a per file basis such as replacing semicolons but it just doesn't work across Javascript files.
  • Alex McDermott
    Alex McDermott over 5 years
    Yea I have it installed. I've put a copy of my npm list output in the question so you can see the installed packages and their versions
  • Alex McDermott
    Alex McDermott over 5 years
    Hi, I just tried you're suggestion and don't have any errors in the ESLint out panel on my HTML document
  • Alex
    Alex over 5 years
    Then idk. Could be duplicate of this one stackoverflow.com/questions/32683223/…
  • Alex McDermott
    Alex McDermott over 5 years
    I don't believe it's a duplicate. I don't get an error like that. If I uninstall the eslint-plugin-html extension I get that error but it disappears once I reinstall it. So it seems like ESLint can see the plugin but it isn't working for some reason?
  • Alex McDermott
    Alex McDermott over 5 years
    This is all I get in the ESLint output tab when I restart: [Info - 10:51:04 AM] ESLint server stopped. [Info - 10:51:04 AM] ESLint server running in node v8.9.3 [Info - 10:51:04 AM] ESLint server is running. [Info - 10:51:06 AM] ESLint library loaded from: /Users/alexmcdermott/GitHub/Demo/node_modules/eslint/lib/api‌​.js
  • gman
    gman over 5 years
    added a screenshot of how I tested. Just made a test.html, a script tag, and typed some JS.
  • Alex McDermott
    Alex McDermott over 5 years
    Ah ok I see. I just tired making an inline script tag like in your image and it worked. So that shows that the plugin is working, but I would like to get it working with linked Javascript files so that I can keep my code in seperate files rather than all in one HTML file.
  • gman
    gman over 5 years
    it doesn't look at links. It looks at .js and .html files in your project
  • Alex McDermott
    Alex McDermott over 5 years
    @Alex I'm trying to lint my Javascript which is split into seperate files and linked into my HTML file (It's a web app). So I have a function in one file and that function is called in another file but ESLint cannot see that it's defined and then also used because its split over two files.
  • Alex McDermott
    Alex McDermott over 5 years
    I thought that was the whole point of the eslint-plugin-html? This is from their npm page: "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"
  • gman
    gman over 5 years
    AFAIK that's normal. Either you define it using import foo from 'foo.js'; or you define it with a comment /* global foo */. Eslint doesn't look across files and really can't
  • Alex McDermott
    Alex McDermott over 5 years
    So instead of linking all the js files in the HTML file I link one main javascript file and then use "import foo from 'foo.js';" inside of that to include all my modules? Is import a part of browser javascript or will I need to compile it first? Or just have a inline script in the HTML with the import foo from ... ?
  • gman
    gman over 5 years
    No, if bar.js uses stuff in foo.js called fooFunction then in bar.js you'd put /* global fooFunction */ to tell eslint that some global function called fooFunction is defined outside of bar.js. import is ES7 which is the newer way to import definitions from other modules. If you're using import then you generally don't need the global comments. If you're not using import you do need them in every file that uses something not defined in that file.
  • gman
    gman over 5 years
    Maybe you should ask on github for the plugin. I suspect it won't do what you want. It might not require a global comment in an inline script for a script included on that page. It seems unlikely it would not require globals to be defined when used inside .js file since the plugin is only for html.
  • Alex McDermott
    Alex McDermott over 5 years
    Ah ok I see. Yea it think I'll give the ES7 imports a try because it seems like a bit of a hassle having to define globals for every file. And yea I might check with the plugins Github but I feel like the problem was just me misunderstanding its purpose. Thanks very much for the help and info :)
  • Todd.Werelius
    Todd.Werelius almost 2 years
    Trying to fix this stupid problem all day, yours worked, thanks!