Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add pug support for vue templates #29

Open
maksnester opened this issue Jul 15, 2018 · 31 comments
Open

Add pug support for vue templates #29

maksnester opened this issue Jul 15, 2018 · 31 comments

Comments

@maksnester
Copy link

Hello, it is very desired feature to have in eslint-plugin-vue, but they relay on this lib to parse things. So I just wanted to ask if there are any plans to add pug support?

Original issue: vuejs/eslint-plugin-vue#310

@mysticatea
Copy link
Member

Thank you for this issue.

Yes, it will be good if this parser can parse pug.

But I don't have knowledge about pug syntax and semantics, so I don't have enough time to implement it for now.

PR is welcome.
It should parse pug and generate this AST.

@lehni
Copy link

lehni commented Oct 10, 2018

@mysticatea I've started looking into this, and have found https://github.com/pugjs/pug-lint which could be a good starting point:

Internally it uses pug-lexer, which does all the parsing, and already outputs a type of AST. Maybe it won't be all that hard to translate this AST into the form that vue-eslint-parser requires?

@mysticatea
Copy link
Member

@lehni Thank you!

You are right. That pug-lexer looks good starting point.
I image the steps are below:

  1. Parse the inside of <template lang="pug"> with pug-lexer.
  2. Convert the result of the parse to our AST. Note some parts such as expression containers, directives, etc, should be re-parsed as JavaScript.
  3. Extract tokens from the result of the parse. For example, div(data-foo="bar") may be the sequence of div ( data-foo = "bar" ). (Tokens are separated at the places we can add spaces freely without semantic changes.) Store the tokens to ast.templateBody.tokens.
  4. Extract comments from the result of the parse. Store the comments to ast.templateBody.comments.

@lehni
Copy link

lehni commented Oct 12, 2018

@mysticatea thank you for the detailed description! Could you point me to the part in the parser code that does this for HTML?

@ppsirius
Copy link

Anyone working on it maybe?

@lehni
Copy link

lehni commented Dec 13, 2018

Unfortunately I don't have the time to do so at the moment

@armano2
Copy link
Contributor

armano2 commented Dec 13, 2018

@ppsirius @lehni some time ago there was some work on it by @leo-buneev
leo-buneev/vue-eslint-parser@de3fe7f...master

@leo-buneev
Copy link

leo-buneev commented Dec 14, 2018

I have abandoned this project.

If anyone will continue, beware, pug-lexer returns a little bit different format of tokens, and doesn't provide all necessary data - some hacking done by me here is useful to return consistent data from pug-lexer.

My idea was to return HTML syntax tree that is equivalent to PUG source code (so existing vue-eslint-plugin rules do not need reimplementation), but with different character indexes (corresponding to pug code). It was coming along nicely, but still far from finishing.

We've moved our projects to html since (https://github.com/leo-buneev/pug-to-html). Curiously, it increased character count only by 3.8% - much less than I expected. Pug has more drawbacks than benefits, imho -

Benefits:

  • 3.8% less characters
  • Less syntax noise

Drawbacks:

  • Pug creates problems for junior team members (they have hard time understanding why it's not html, and even harder time putting correct amount of spaces to nest elements)
  • You need to switch mentally between coding (Pug) and inspecting in devtools (HTML)
  • Worse IDE support
  • vue-eslint-plugin doesn't work yet

@tats-u
Copy link

tats-u commented Aug 18, 2019

Why don't you use https://github.com/myfreeweb/eslint-plugin-pug ?

@prgueza
Copy link

prgueza commented Jan 28, 2020

Any news on this one?

@SkyaTura
Copy link

Is there any perspective of solving this issue?

@matthieusieben
Copy link

@tats-u because eslint-plugin-pug is to validate javascript inside pug. Not pug inside vue.

@sgarcia-dev
Copy link

Honestly, why I'm slightly saddened at the reduced flexibility, I think @leo-buneev made the right call here. Open Source is maintained out of the good-will of kind developers. And Leo made a good analysis showing why adding the extra work load of supporting Pug just doesn't have enough objective benefits to warrant it.

@TokugawaTakeshi
Copy link

To everyone who want this feature be implemented by have not time to implement it yourself:
How about chip in and hire someone who can do it for fee?
I am ready to invest 300$ for implementing of this feature.

P. S.
When this feature will be implemented, it will be a new page of quality management automation history.

@lehni
Copy link

lehni commented Oct 3, 2020

FYI: There's a prettier-pug plugin now that works quite well for my use-case:

https://github.com/prettier/plugin-pug

@TokugawaTakeshi
Copy link

@lehni
That’s very kind of you. I'll try.

@juliovedovatto
Copy link

juliovedovatto commented Jul 19, 2021

Oh Boy, I wish I had seen this issue before starting a big Vue project using PUG 🙄

@Shinigami92
Copy link

Author of https://github.com/prettier/plugin-pug here.

Please watch/star https://github.com/Shinigami92/eslint-plugin-vue-pug-sfc
I will try to tackle eslint vue pug support in next time

@Shinigami92
Copy link

Shinigami92 commented Aug 23, 2021

I have currently a hard time trying to find out what could be the best/correct way of processing the files.
I may need to implement the pug parser as @leo-buneev pointed out in https://github.com/leo-buneev/vue-eslint-parser/blob/master/src/pug/tokenizer.ts
But I would just use the default tokens instead of the HTML variant of tokens and then just process these. Cause the HTML variant of tokens are really hard to use, if not to impossible.

It seems I cannot implement just a e.g. pug-eslint-parser cause this way I could not access vue files, cause these need the vue-eslint-parser and this is needed for vue files. And we cannot declare two parsers for vue at the same time 😖

... So could take a while ... mainly because I also have a real life 🤣
Any help is very welcome

@Shinigami92
Copy link

I'm not progressing as fast as I wanted 🙁
I have currently so much other stuff around me, and this PR/Issue has a low-mid priority for me 😕
So this could take a while and I didn't expect that it is that hard to understand all of this stuff and bring everything together. Until now I'm even not sure what would be the best and most efficient solution.

I'm still interested in solving this (for my pug-vue community), but this could take weeks to month due to the other stuff around me 🤷

loriswit added a commit to frilan/frilan that referenced this issue Sep 6, 2021
ESLint is yielding false negatives because of Pug templates
see vuejs/vue-eslint-parser#29
@Shinigami92
Copy link

https://www.npmjs.com/package/eslint-plugin-vue-pug-sfc/v/1.0.0-alpha.2 👀

This is a first alpha and "supports" vue-pug-sfc/this-in-template for the never option. always is currently NOT supported due to it is much harder to implement.

Please give it a try and please also start to create issues in the repo for every rule you want to get support for!
Please do NOT use the --fix option right know (or at least with a backup), cause it can damage your code!
The ranges are not accurate yet so the ~~~~ lines are positioned to broad right now.

Please also feel free to jump into the code and help me 😃
If you use VSCode jump into the Debug Launcher and run the tests with debug-breakpoints.


@TokugawaTakeshi You don't need to but I would really love to get at least a bit of your offered investment.
I'm working hard on the project and it took me a while to get to this point

  • reading how to create eslint plugins
  • finding a way to parse the pug content
    thanks to @ota-meshi for the initial help, maybe you should get also a bit of the payout if there is one
  • etc...

I will not spam here anymore, so please lets move all discussions to the project's repo.

@TokugawaTakeshi
Copy link

TokugawaTakeshi commented Sep 17, 2021

@Shinigami92,

I am responsible for my words.
I'll send the email on the address mentioned in your profile soon.

@doutatsu
Copy link

It seems that there is no desire to add support for it - but I'll still leave my comment, as I am one of many who love and want to continue using Pug, but not having the ability to use https://github.com/vuejs/eslint-plugin-vue is a big issue

@Shinigami92
Copy link

@doutatsu Whats wrong with my plugin? https://github.com/Shinigami92/eslint-plugin-vue-pug-sfc
Do you need anything special?
Maybe you could even help contribute to it? Then we all have something from it 🙂
You can see the project board here: https://github.com/Shinigami92/eslint-plugin-vue-pug-sfc/projects/1

@doutatsu
Copy link

@Shinigami92 Nothing particularly wrong with yours, but this is an official VueJS ESLint parser, so I think it's still appropriate to ask for the official support for pug here.
Moreover, this specific plugin is the one being used by this repository, which is what I need specifically - https://github.com/vuejs/eslint-plugin-vue. If they decide to use your plugin, then that'll be fine as well

@Shinigami92
Copy link

Shinigami92 commented Nov 13, 2021

Ah yeah, sry now I understand: yeah I would love if the parser would parse the pug content. But sadly the structure is not really compatible.
In my plugin I extract the pug content out of it and the use the real pug-lexer to generate the tokens.
I'm not sure if it's really possible to support this like it is currently designed out of the box.

@sgarcia-dev
Copy link

sgarcia-dev commented Nov 14, 2021

Totally understand @doutatsu here with no disrespect to the incredible, selfless work @Shinigami92 is doing here for the pug community. As much a third-party solution is appreciated, let's keep hoping that's at some point pug support is added to vue-eslint-parser. Since it's unlikely any larger than small-scale production app will want to go for anything but "officially" recommended community plugins. Having more than one templating option will never be a bad thing.

Having said that, I feel for @juliovedovatto ... Our last greenfield project's head foolishly decided to go for pug templates out of personal coding preference despite the team's overwhelming amount of evidence against it and it also left us with a ton of pug-related issues...

  • IDE support was poor and plenty of easy to catch linter errors got in frequently.
  • There was a large initial learning curve
  • We had a mess of PR quality control with people mixing Pug / Vue templating logic instead of being consistent and sticking to only one (due to the Pug/Vue PR overlap).

Hope at the very least this PR conversation helps folks considering pug in their vue project think twice before using it (at least until official support is added to vue-eslint-parser)

@Shinigami92
Copy link

@sgarcia-dev Thanks for the kind words regarding me, but I would say that it is okay to use pug (maybe without all the pug-js stuff, but using framework stuff like v-if)
If they know how html works, they can also use pug, it's just shorter syntax.

@rashfael
Copy link
Contributor

I gave implementing this also a shot and got most of the attribute-hyphenation rule to work as a proof of concept. You can find the code here https://github.com/rashfael/vue-eslint-parser/tree/pug-parser .
I also used the approach of generating HTML* tokens, but I now think this will lead to some issues down the line.
Since HTML* tokens are used in actual rules to check syntax, we would need to always generate the correct structure (including whitespace) to satisfy these rules. Since these rules are configurable, that's not a rabbithole I want to go down.
I now think it would be better to generate higher level tokens from ast.md to support rules not looking at syntax, indentation, etc. Especially since rules like html-end-tags don't make sense for pug.
To lint pug-specific syntax adding rules just for pug might be best (these could totally live in a different project apart from eslint-plugin-vue) and vue-eslint-parser could emit pug-specific tokens.

Since supporting pug like that might involve bigger changes, what's the opinion of the maintainers (@mysticatea , @ota-meshi?) on pug specific tokens?

In the meantime I'll contribute to @Shinigami92's project.

@rashfael
Copy link
Contributor

Pug support has been added via eslint-plugin-vue-pug, which adds a template tokenizer to vue-eslint-parser, making a lot of rules of eslint-plugin-vue just work.
For full rule compat see this table.
Please try it out on your real world projects and see if you can find some bugs!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests