vuejs / vue-eslint-parser

The ESLint custom parser for `.vue` files.
MIT License
450 stars 74 forks source link

Add pug support for vue templates #29

Open maksnester opened 6 years ago

maksnester commented 6 years ago

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: https://github.com/vuejs/eslint-plugin-vue/issues/310

mysticatea commented 6 years ago

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 commented 6 years ago

@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 commented 6 years ago

@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 commented 6 years ago

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

mysticatea commented 6 years ago
ppsirius commented 5 years ago

Anyone working on it maybe?

lehni commented 5 years ago

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

armano2 commented 5 years ago

@ppsirius @lehni some time ago there was some work on it by @leo-buneev https://github.com/leo-buneev/vue-eslint-parser/compare/de3fe7f18feaebdf61dc1c9661d8446b074c41c2...master

leo-buneev commented 5 years ago

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:

Drawbacks:

tats-u commented 5 years ago

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

prgueza commented 4 years ago

Any news on this one?

SkyaTura commented 4 years ago

Is there any perspective of solving this issue?

matthieusieben commented 4 years ago

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

sgarcia-dev commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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

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

TokugawaTakeshi commented 4 years ago

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

juliovedovatto commented 3 years ago

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

Shinigami92 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

I'm not progressing as fast as I wanted :slightly_frowning_face:
I have currently so much other stuff around me, and this PR/Issue has a low-mid priority for me :confused:
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 :shrug:

Shinigami92 commented 3 years ago

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

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 :smiley: 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


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

TokugawaTakeshi commented 3 years ago

@Shinigami92,

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

doutatsu commented 3 years ago

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 commented 3 years ago

@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 :slightly_smiling_face: You can see the project board here: https://github.com/Shinigami92/eslint-plugin-vue-pug-sfc/projects/1

doutatsu commented 3 years ago

@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 commented 3 years ago

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 commented 3 years ago

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...

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 commented 3 years ago

@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 commented 2 years ago

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 commented 2 years ago

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!