Code Monkey home page Code Monkey logo

htmlhint-loader's Introduction


Logo HTMLHint
HTMLHint

The static code analysis tool you need for your HTML.

Travis Build Status Codecov npm count MIT License

  How To UseContributingWebsite

Table of Contents

📟 Installation and Usage

There are two ways to install HTMLHint: globally and locally.

Local Installation and Usage

In case you want to include HTMLHint as part of your project, you can install it locally using npm:

$ npm install htmlhint --save-dev

After that, You can run HTMLHint on any file or directory like this:

$ ./node_modules/.bin/htmlhint www/index.html
$ ./node_modules/.bin/htmlhint www/**/*.html

Global Installation and Usage

If you want to make HTMLHint available to tools that run across all of your projects, you can install HTMLHint globally using npm:

$ npm install htmlhint -g

After that, you can run HTMLHint on any file like this:

$ htmlhint www/index.html
$ htmlhint www/**/*.html

You can even launch HTMLHint to analyze an URL:

$ htmlhint https://htmlhint.com/

📃 Example output

🔧 Configuration

Search .htmlhintrc file in current directory and all parent directories:

$ htmlhint
$ htmlhint test.html

Custom config file:

$ htmlhint --config htmlhint.conf test.html

Custom rules:

$ htmlhint --rules tag-pair,id-class-value=underline index.html

Inline rules in test.html:

<!--htmlhint tag-pair,id-class-value:underline -->
<html>
  <head>
    ...
  </head>
</html>

📙 Docs

  1. How to use
  2. All Rules
  3. How to Develop

© License

MIT License

💪🏻 Contributors

This project exists thanks to all these people. Contribute.

🏅 Backers

Thank you to all our backers! Become a backer.

🎖 Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. Become a sponsor.

htmlhint-loader's People

Contributors

benoit-vasseur avatar colinwkirk avatar greenkeeper[bot] avatar jaythomas avatar mattlewis92 avatar snyk-bot avatar thedaviddias avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

htmlhint-loader's Issues

Suggestion: improve handling of configFile paths

Before using htmllint-loader, I was able to execute my webpack build from various directories (cwd); now, I am forced to do so from one specific location, because otherwise the config file cannot be found. The reason is that every given configFile path is processed by this line:

const configFilePath = path.join(process.cwd(), options.configFile);

I would suggest two changes to further improve the code:

(1.) Allow absolute paths to be passed in. If a path is already absolute, do not join the cwd:

let configFilePath = options.configFile;
if (!path.isAbsolute(configFilePath)) {
  configFilePath = path.join(process.cwd(), configFilePath);
}

(2.) Throw an error if a configFile was specified and cannot be located. Currently, this would be silently ignored!

Error when report is generated

Hi, I got the next while webpack generates a report of a HTML which violated some htmlhint rules:

ERROR in Error: Child compilation failed:
Module build failed: TypeError: formatter.on is not a function

  • checkstyle.js:8 Object.checkstyleFormatter [as formatter]
    [angular-hello-world]/[htmlhint]/bin/formatters/checkstyle.js:8:15

  • index.js:98 lint
    [angular-hello-world]/[htmlhint-loader]/index.js:98:47

  • index.js:164 fs.readFile
    [angular-hello-world]/[htmlhint-loader]/index.js:164:13

  • TypeError: formatter.on is not a function

  • compiler.js:76
    [angular-hello-world]/[html-webpack-plugin]/lib/compiler.js:76:16

  • Compiler.js:291 Compiler.
    [angular-hello-world]/[webpack]/lib/Compiler.js:291:10

  • Compiler.js:494
    [angular-hello-world]/[webpack]/lib/Compiler.js:494:13

  • Tapable.js:138 next
    [angular-hello-world]/[tapable]/lib/Tapable.js:138:11

  • CachePlugin.js:62 Compiler.
    [angular-hello-world]/[webpack]/lib/CachePlugin.js:62:5

  • Tapable.js:142 Compiler.applyPluginsAsyncSeries
    [angular-hello-world]/[tapable]/lib/Tapable.js:142:13

  • Compiler.js:491
    [angular-hello-world]/[webpack]/lib/Compiler.js:491:10

  • Tapable.js:131 Compilation.applyPluginsAsyncSeries
    [angular-hello-world]/[tapable]/lib/Tapable.js:131:46

  • Compilation.js:645 self.applyPluginsAsync.err
    [angular-hello-world]/[webpack]/lib/Compilation.js:645:19

  • Tapable.js:131 Compilation.applyPluginsAsyncSeries
    [angular-hello-world]/[tapable]/lib/Tapable.js:131:46

  • Compilation.js:636 self.applyPluginsAsync.err
    [angular-hello-world]/[webpack]/lib/Compilation.js:636:11

  • Tapable.js:131 Compilation.applyPluginsAsyncSeries
    [angular-hello-world]/[tapable]/lib/Tapable.js:131:46

  • Compilation.js:631 self.applyPluginsAsync.err
    [angular-hello-world]/[webpack]/lib/Compilation.js:631:10

  • Tapable.js:131 Compilation.applyPluginsAsyncSeries
    [angular-hello-world]/[tapable]/lib/Tapable.js:131:46

  • Compilation.js:627 sealPart2
    [angular-hello-world]/[webpack]/lib/Compilation.js:627:9

  • Tapable.js:131 Compilation.applyPluginsAsyncSeries
    [angular-hello-world]/[tapable]/lib/Tapable.js:131:46

  • Compilation.js:575 Compilation.seal
    [angular-hello-world]/[webpack]/lib/Compilation.js:575:8

  • Compiler.js:488
    [angular-hello-world]/[webpack]/lib/Compiler.js:488:16

  • Tapable.js:225
    [angular-hello-world]/[tapable]/lib/Tapable.js:225:11

  • Compilation.js:477 _addModuleChain
    [angular-hello-world]/[webpack]/lib/Compilation.js:477:11

  • Compilation.js:448 processModuleDependencies.err
    [angular-hello-world]/[webpack]/lib/Compilation.js:448:13

  • next_tick.js:73 _combinedTickCallback
    internal/process/next_tick.js:73:7

  • next_tick.js:104 process._tickCallback
    internal/process/next_tick.js:104:9

Child html-webpack-plugin for "index.html":
[./node_modules/html-webpack-plugin/lib/loader.js!./src/index.html] ./~/html-webpack-plugin/lib/loader.js!./src/index.html 616 bytes {0} [built] [failed] [1 error]

ERROR in ./~/html-webpack-plugin/lib/loader.js!./src/index.html
Module build failed: TypeError: formatter.on is not a function
    at Object.checkstyleFormatter [as formatter] (/media/DATA/Programming/AngularJS/AngularJS 4/angular-hello-world/node_modules/htmlhint/bin/formatters/checkstyle.js:8:15)
    at lint (/media/DATA/Programming/AngularJS/AngularJS 4/angular-hello-world/node_modules/htmlhint-loader/index.js:98:47)
    at fs.readFile (/media/DATA/Programming/AngularJS/AngularJS 4/angular-hello-world/node_modules/htmlhint-loader/index.js:164:13)
    at tryToString (fs.js:449:3)
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:436:12)

The following is a extract of my webpack.config.js

"rules": [
      {
        "enforce": 'pre',
        "test": /\.html$/,
        "loader": 'htmlhint-loader',
        "exclude": /node_modules/,
        "options": {
          "configFile": '.htmlhintrc.json',
          "failOnError": true,
          "failOnWarning": false,
          "outputReport": {
            "filePath": 'checkstyle-[name].xml',
            "formatter": require('htmlhint/bin/formatters/checkstyle')
          }
        }
     },
  // . . . 

I am using

  • htmlhint-loader 1.3.0
  • htmlhint 0.9.13
  • webpack 2.6.1

How to get it working?

I have this setup.

webpack.config.js

var path = require("path");

// console.log(path.join(__dirname, 'src'));
// console.log(path.resolve(__dirname, "src"));

module.exports = {
    entry: {
        app : "./entry.js", 
        src : "./src/a.js"
    } ,
    output: {
        path: path.join(__dirname, "out"),
        filename: "[name].js"
    },
    module: {
        preLoaders: [
            {
               test: /\.jsx?$/,
               exclude: /node_modules/,
               loader: 'jshint-loader',
            },
            {test: /\.html/, loader: 'htmlhint?{tagname-lowercase: true}', exclude: /node_modules/}
        ]
    },
    htmlhint: {
            configFile: './.htmlhintrc'
    }
};

test.html

<!DOCTYPE html>
<html>
<head>
    <title>Title is here</title>
</head>
<body>
<DIV ></DIV>

<img src="http://kevinpelgrims.com/blog/files/images/2015/05/gradle_icon.png" />
</body>
</html>

.htmlhintrc

{
  "tagname-lowercase": true,
  "attr-lowercase": true,
  "attr-value-double-quotes": true
}

It should have shown error for capitalized div elements, but it's not doing so.

Could you please tell me some points or hints?

got error in a vue project.

I'm using htmlhint-loader in a vue project.and I just follow the docs like:

      {
        test: /\.html/,
        enforce: 'pre',
        loader: 'htmlhint-loader',
        exclude: /node_modules/
      },

error as following:

ERROR in   Error: Child compilation failed:
  Module parse failed: /Users/zsd/repo/vue-webpack/test/node_modules/html-webpack-plugin/lib/loader.js!/Users/zsd/repo/vue-webpack/test/node_modul
  es/htmlhint-loader/index.js!/Users/zsd/repo/vue-webpack/test/index.html Unexpected token (1:0)
  You may need an appropriate loader to handle this file type.
  | <!DOCTYPE html>
  | <html>
  |   <head>:
  SyntaxError: Unexpected token (1:0)

am I missing something?

supporting info:
"node": "7.9.0",
"webpack": "^2.6.1",
"htmlhint-loader": "1.3.0",
"vue-loader": "^12.1.0",

wepback 4.0.0 compatiblity

hello,
this loader throws an exception when used with webpack 4.0.0
it throws:

ERROR in ./app/test.html
Module build failed: TypeError: Cannot read property 'htmlhint' of undefined
    at Object.module.exports

Better tests

Current tests mock too much out, it's much better to have integration tests instead

Latest version stills installs htmlhint 0.9.13 which installs also minimatch 0.3.0 with vulnerabilities

Describe the bug
When I install the latest version of the module I got a warning of security vulnerability

npm WARN deprecated [email protected]: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated [email protected]: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue

To Reproduce
Steps to reproduce the behavior:

  1. Run `npm install htmlhint-loader --save-dev
  2. Error appears

Expected behavior
Install the latest version of htmlhint which already uses the correr minimatch package

Screenshots

image

Use `strip-json-comments` before parsing the config file.

Is your feature request related to a problem? Please describe.

htmlhint use strip-json-comments for config file so you can use comments inside the .htmlhintrc file.

Code here: https://github.com/htmlhint/HTMLHint/blob/85a1c78984a8ec09ab17595efba2e6ac479e6f31/bin/htmlhint#L319

But htmlhint-loader doesn't support it.

Describe the solution you'd like

Use strip-json-comments

Describe alternatives you've considered

I advice to use http://json5.org/

Additional context

None

Angular inline templates

Hi there,

I am using Angular inline templates in my project and I would like to lint them with HTMLHint via htmlhint-loader.

It works with this configuration:

            {
                enforce: "pre",
                test: /\.ts$/,
                loader: "htmlhint-loader",
                include: [...],
                options: {
                    configFile: [...],
                    failOnError: false,
                    failOnWarning: false,
                }
            },

The actual HTML part within inline templates is situated inside a template variable in those *.ts files. I guess htmlhint-loader is currently linting the whole file including the TypeScript code. This probably causes the following loader plugin error when the linter finds something what it thinks is an error:

Error:
at lint ([...]\node_modules\htmlhint-loader\index.js:115:15)
at fs.readFile ([...]\node_modules\htmlhint-loader\index.js:163:11)
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:528:3)
@ ./assets/scripts/ts/modules/shared/shared.module.ts 81:39-113
@ ./assets/scripts/ts/modules/app/app.module.ts
@ ./assets/scripts/ts/modules/app/standalone-app.module.ts
@ ./assets/scripts/ts/main.jit.ts

I would like to know if it is somehow possible to tell htmlhint-loader that it should only lint the template part within those files. (Maybe something like the regExp option of file-loader to only target a part of the loaded file.)

Incorrect config, or something else?

Should it run on built when the loader is configured? Or would it just work on calling npx htmlhint script.

The output of my npx webpack command (from build script) does not mention htmlhint,

I am not sure if this is an issue with how I configured, or if its not compatible with webpack 5 (or should just call in script)?

Node: v17.0.1
Npm: 8.1.0
webpack: 5.60.0
webpack-cli: 4.9.1
webpack-dev-server 4.4.0
mac-os: 12.0.1

Package.json:

  "scripts": {
    "lint:html": "npx htmlhint src/*.html",
    "build": "npx webpack --config webpack.config.dev.js"
    "dev": "npx webpack serve --live-reload --config webpack.config.dev.js",
  },
"devDependencies": {
    "@babel/cli": "^7.15.7",
    "@babel/core": "^7.15.8",
    "@babel/node": "^7.15.8",
    "@babel/preset-env": "^7.15.8",
    "@babel/register": "^7.15.3",
    "babel-loader": "^8.2.3",
    "css-loader": "^6.5.0",
    "htmlhint": "^0.15.2",
    "htmlhint-loader": "^1.3.1",
    "numeral": "^2.0.6",
    "style-loader": "^3.3.1",
    "stylelint": "^13.13.1",
    "stylelint-webpack-plugin": "^3.0.1",
    "webpack": "^5.60.0",
    "webpack-cli": "^4.9.1",
    "webpack-dev-server": "^4.4.0"
  }

.htmlhintrc:

{
  "tagname-lowercase": true,
  "attr-lowercase": true,
  "attr-no-duplication": true,
  "attr-value-double-quotes": true,
  "attr-unsafe-chars": true,
  "attr-no-unnecessary-whitespace": true,
  "attr-value-not-empty": false,
  "doctype-first": true,
  "tag-pair": true,
  "spec-char-escape": true,
  "src-not-empty": true,
  "title-require": true,
  "tag-self-close": false,
  "head-script-disabled": true,
  "alt-require": true,
  "doctype-html5": true,
  "inline-script-disabled": true,
  "inline-style-disabled":true,
  "id-unique": true,
  "id-class-ad-disabled": true,
  "id-class-value": "aaa-bbb",
  "style-disabled": true,
  "input-requires-label": true,
  "tags-check": true,
  "space-tab-mixed-disabled": true
}

webpack config:

const path = require('path');
var StyleLintPlugin = require('stylelint-webpack-plugin');

module.exports = {
    mode: "development",
    devtool: "eval-source-map",
    entry: './src/index.js',
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: ["babel-loader"]
            },
            {
                test: /\.css$/,
                use: ["style-loader", "css-loader"]
            },
            {
                enforce: 'pre',
                test: /\.html/,
                loader: 'htmlhint-loader',
                exclude: /node_modules/,
                options: {
                    configFile: '.htmlhintrc'
                }
            }
        ]
    },
    output: {
        path: path.resolve(__dirname, 'src'),
        filename: "bundle.js",

        //enable clean on dist only. otherwise, it will delete all files and cannot recover.
        // clean: true, 
    },
    devServer: {
        static: {
            directory: path.join(__dirname, 'src'),
        },
        compress: true,
        port: 9000,
    },
    plugins: [
        new StyleLintPlugin({
            configFile: '.stylelintrc',
            failOnError: true,
            emitErrors: true,
            emitWarning: true
        }),
    ],
}

npm run build:

asset bundle.js 136 KiB [compared for emit] (name: main)
runtime modules 997 bytes 4 modules
modules by path ./node_modules/ 41.5 KiB
  modules by path ./node_modules/style-loader/dist/runtime/*.js 5.75 KiB 6 modules
  modules by path ./node_modules/css-loader/dist/runtime/*.js 2.94 KiB
    ./node_modules/css-loader/dist/runtime/sourceMaps.js 688 bytes [built] [code generated]
    ./node_modules/css-loader/dist/runtime/api.js 2.26 KiB [built] [code generated]
  ./node_modules/numeral/numeral.js 32.8 KiB [built] [code generated]
modules by path ./src/ 2.86 KiB
  ./src/index.js 125 bytes [built] [code generated]
  ./src/style.css 1.11 KiB [built] [code generated]
  ./node_modules/css-loader/dist/cjs.js!./src/style.css 1.63 KiB [built] [code generated]
webpack 5.60.0 compiled successfully in 1260 ms

npm run lint:html

Config loaded: /Users/jenn/GitHub/dev-starter-kit/.htmlhintrc

   /Users/jenn/GitHub/dev-starter-kit/src/index.html
      L11 |    <P></P>
               ^ The html element name of [ P ] must be in lowercase. (tagname-lowercase)
      L11 |    <P></P>
                  ^ The html element name of [ P ] must be in lowercase. (tagname-lowercase)

Scanned 1 files, found 2 errors in 1 files (17 ms)

configFile option ignored

Hi,

It doesn't seem that the configFile option described in the documentation actually does anything.

Skimming through the source code, it appears that this parameter gets handed directly to htmlhint, which doesn't actually do anything with it.

simpler custom rules import

is it possible to make creating multiple custom rules simpler.
I want to make about 50-100 rules to my project, and creating those files and adding reference going to be hard task

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.