yeonjuan / html-eslint

ESLint plugin for linting HTML
https://html-eslint.org
MIT License
161 stars 28 forks source link

How to create custom rule #194

Closed l3ender closed 3 months ago

l3ender commented 4 months ago

Is it possible to extend the existing rules with custom ones? We have a use case where we want to detect the presence of Angular expressions inside HTML elements and enforce required attributes and CSS classes.

Is it possible with this library, or could you please advise on how to accomplish? Thank you!

yeonjuan commented 4 months ago

Hi @l3ender, I can't think of a way to extend the rule. Can you share any example code you'd like to lint?

l3ender commented 4 months ago

The general question is how we can create custom HTML eslint rules to extend this library for scenarios that it doesn't currently cover. We wouldn't expect the library to cover all scenarios (or specific use cases like our own) and would be fine to build it ourselves, but we don't see how to add custom HTML rules to extend this library in the same way that custom rules can extend the core eslint library.

Having said that, here are some examples of what we're looking to validate using eslint (not specific to just paragraph elements):

Correct usage

<p data-verified="true">{{ model.property }}</p><!-- dynamic expression contains required attribute -->

<p>Static text</p><!-- static content; needs no attribute -->

Incorrect usage

<p>{{ model.property }}</p><!-- dynamic expression does not contain required attribute -->

Let us know your thoughts--thanks!

yeonjuan commented 4 months ago

@l3ender Thank you for sharing. Perhaps there is a way to create your own ESLint plugin using @html-eslint/parser and @html-eslint/eslint-plugin.

And perhaps it's possible to import @html-eslint's rule and extends with your purpose.

const { indent: indentBase } = require('@html-eslint/eslint-plugin/lib/rules');

module.exports = {
   meta: {

   },
  create(context) {
      const baseRule = indentBase.create(context);
       return {
          Tag(node) {
               baseRule.Tag(node);
         }
      }
   }
}
l3ender commented 3 months ago

Thank you for the reply and apologies for my slow response!

Thank you for the help. I am new to writing a custom eslint rule, but believe the key thing I need/want to do is use html-eslint/parser for my plugin, as that will allow for using HTML-type nodes from this library. Is that correct?

I would likely not be extending a current rule but building one from scratch. So it's still a little fuzzy, but hopefully am going in the correct direction.

Thanks again!

yeonjuan commented 3 months ago

@l3ender

Thank you for the help. I am new to writing a custom eslint rule, but believe the key thing I need/want to do is use html-eslint/parser for my plugin, as that will allow for using HTML-type nodes from this library. Is that correct?

Yes, that's right, @html-eslint/parser parses HTML and generates ASTs in a form compatible with ESlint. You can use it to create new plugins.

l3ender commented 3 months ago

Thank you! I was able to create a custom rule. Most of the headache was finding how to integrate the rule into an eslint plugin, and integrate the plugin into our shared eslint config...but all good now and the rule is working great.

For anyone else looking to do the same, it was very helpful to reference rules in this repo as well as the readme for https://github.com/yeonjuan/es-html-parser.