Skip to content

Add pug support for vue templates #123

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Conversation

Shinigami92
Copy link

references #29

Comment on lines +10 to +12
.yarn
.yarnrc.yml
yarn.lock
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use yarn locally.
To prevent accidental commit of 80+ files, I ignored these for now.
Can revert it when out of draft

@Shinigami92
Copy link
Author

const scripts = rootAST.children.filter(isScriptElement)
https://github.com/Shinigami92/vue-eslint-parser/blob/03afed418fc06a1e79430622b21d1c6e723f2018/src/index.ts#L91

Why is a scripts element used here? Do I need to use partially the HTMLParser for that?
I thought this whole part is just for the template block?
Am I wrong? And do I also need to parse the script part?

@Shinigami92
Copy link
Author

@mysticatea Please guide me in the right direction from here

Am I on the correct track?


@leo-buneev Are you totally not interested anymore? Do you have any hints for me what issues you had in the past?


@lehni @SkyaTura Hey my pug team ^^
Would you also like to help me?

@ota-meshi
Copy link
Member

This parser also parses <script> blocks.
Try checking AST by selecting Vue as the syntax and vue-eslint-parser as the parser in https://astexplorer.net/.

@ota-meshi
Copy link
Member

Also, this parser treats the content of custom blocks without lang="html" as RAWTEXT.

<custom-block-no-html>
<div><h1>Is Not HTML</h1></div>
</custom-block-no-html>

"children": [
{
"type": "VText",
"range": [
132,
167
],
"loc": {
"start": {
"line": 5,
"column": 22
},
"end": {
"line": 7,
"column": 0
}
},
"value": "\n <div><h1>Is Not HTML</h1></div>\n"
}

@Shinigami92
Copy link
Author

@ota-meshi Oh this is really helpful! Thx 🚀

But the problem is, that templateBody for the following example is undefined

https://astexplorer.net/#/gist/c65cb983b69598b7b2f5cda88627144b/2f61d497ca7582da9041165a869712a728e32c59

The goal of this PR should be to solve explicitly this.

@ota-meshi
Copy link
Member

templateBody is undefined because the current parser only parses HTML.

template != null && templateLang === "html"

I think it's a good to change the conditions as you change the parser to make it understand pug.

@Shinigami92 Shinigami92 force-pushed the 29-add-pug-support-for-vue-templates branch from 79d0226 to 9a2d5b1 Compare September 7, 2021 11:34
@Shinigami92 Shinigami92 marked this pull request as ready for review September 7, 2021 11:45
@Shinigami92
Copy link
Author

Could you trigger the tests?
I have hard problems with executing any of the scripts like coverage, lint or test. I just get errors locally before these could even start.

I took the easy route for now: just dump the parsed tokens into doc's pugTokens property, and that only if it exists and no errors are thrown.
I then can use this on my side in my plugin and just read and process them. But I don't need to parse them everytime a lint rule triggers but they get only parsed once in the vue-eslint-parser.

So at least I can try to start working on my plugin 🤔

@Shinigami92
Copy link
Author

@ota-meshi please retrigger 🙂
I used nvm use 14 locally and I can now run tests and some other stuff.
But the formatting of my VSCode is mobbing me 😆

@ota-meshi
Copy link
Member

ota-meshi commented Sep 13, 2021

In your change, you can't use traverse with esquery when creating rules for eslint. Is this what you intended?
If it is as intended, I think you can do the same without making any changes to this parser by doing the following:

  /** @param {RuleContext} context */
  create(context) {
    const df =
      context.parserServices.getDocumentFragment &&
      context.parserServices.getDocumentFragment()
    if (!df) {
      return {}
    }
    /** @type {VElement} */
    const pugTemplateElement = df.children.find(
      (node) =>
        node.type === 'VElement' &&
        node.name === 'template' &&
        node.startTag.attributes.some(
          (attr) =>
            !attr.directive &&
            attr.key.name === 'lang' &&
            attr.value &&
            attr.value.value === 'pug'
        )
    )
    if (!pugTemplateElement) {
      return {}
    }
    const pugText = context
      .getSourceCode()
      .text.slice(
        pugTemplateElement.startTag.range[1],
        pugTemplateElement.endTag.range[0]
      )
    const pugTokens = require('pug-lexer')(pugText)
    // ...
  }

(Actually, I think that a cache mechanism is necessary, but I omit it.)

I think the value of making changes to this parser is that the children of <template lang="pug"> will be replaced with pug nodes.

https://github.com/vuejs/vue-eslint-parser/pull/123/files#diff-d6116d0257c9cbb51683fc3313fe94fdb66af52eda8bd4e9f593050c2676b065R119

@Shinigami92
Copy link
Author

Interesting, I will try this out and test if this fulfills my needs. Will report back, but could take a while due to other prios.

And yeah, I need to find a way to cache this so not every single rule reparses the pug code.

@Shinigami92
Copy link
Author

Shinigami92 commented Sep 15, 2021

@ota-meshi IT WORKS!!! 🎉 🚀 ❤️

https://github.com/Shinigami92/eslint-plugin-vue-pug-sfc/blob/a8b3dc504e28b64891803d563509d6c25abd65fa/src/rules/this-in-template.ts#L25-L48

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants