BenoitZugmeyer / eslint-plugin-html

An ESLint plugin to extract and lint scripts from HTML files.
ISC License
430 stars 51 forks source link

Is it possbile to eslint-disable a script(type=module)? #188

Closed wxiaoguang closed 2 years ago

wxiaoguang commented 2 years ago

When working with backend MVC projects, sometimes the code could be:

<!-- I want to disable eslint-plugin-html for this script block -->
<script type="module">
    window.myGlobal.var = {{.MyData}};  // here is invalid JS syntax, but it's rendered by backend template engine correctly.
</script>

<!--  eslint-plugin-html works well for this block, and it should be enabled -->
<script type="module">
    console.log(window.myGlobal.var);
</script>

What we need here is to make eslint-plugin-html skip a whole <script> block because code inside it is not valid JS syntax.

When using eslint-plugin-html, I can not find a proper way to disable the eslint for the script(type=module) block (I do not want ignore the whole file).

I know a trick that: <script><!-- /* eslint-disable */ --></script>, but it doesn't work for script(type=module)

For traditional <script> we can use <script><!-- /* eslint-disable */ --></script>.

But for <script type=module>, this trick doesn't work anymore because the module script doesn't accept <!-- HTML comment.

Standard8 commented 2 years ago

I think you should be able to do something like:

<script type="application/javascript" type="module">
/* eslint-disable */

// Your code

/* eslint-enable */
</script>
wxiaoguang commented 2 years ago

It doesn't work because the syntax inside the tag is invalid JavaScript code window.myGlobal.var = {{.MyData}}

Before the comment /* eslint-disable */ takes effect, the parser reports syntax error first.

BenoitZugmeyer commented 2 years ago

Please refer to Linting templates

wxiaoguang commented 2 years ago

I have read it. But there are a lot of template engines, not only PHP.

And // <?= "\n mydata = " . json_encode($var) . ";" ?> is quite ugly, and sometimes it's not feasible in other template engines.

If the whole <script> tag could be disabled from linting, then the code can be simple and clear. Maybe something like:

<!-- eslint-disable -->
<script type="module">
    window.myGlobal.var = {{.MyData}};  // here is invalid JS syntax, but it's rendered by backend template engine correctly.
</script>

Is it feasible?

silverwind commented 2 years ago

I think the bug here is that invalid JS between eslint-disable and eslint-enable trips this module's parser when it should ideally not try to parse anything between such tags:

<script>
  /* eslint-disable */
  ]
  /* eslint-enable */
</script>

The bug is reproducible with a regular .js file too, so I think espree is not correctly ignoring code between disable/enable sections as it expects the whole file/block to be valid JS, which generally is true for .js files but it's certainly a problem with templated HTML.

What could work (if eslint-plugin-html decides to support it) would be support the disable/enable comment as HTML, outside the script block, so the invalid block is not passed to eslint in first place, e.g.

<!-- eslint-disable -->
<script>
]
</script>
<!-- eslint-enable -->
BenoitZugmeyer commented 2 years ago

Thank you for the suggestion, it has been implemented and released as part of v7.0.0.