sveltejs / eslint-plugin-svelte3

An ESLint plugin for Svelte v3 components.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Preprocessor support?

tivac opened this issue · comments

Given the changes that came out of #3 where it's possible to use real JS objects, it'd be nice to add support for running svelte.preprocess before linting the component.

I want this because we use @modular-css/svelte which is itself a preprocessor that does this:

-<div class="{css.name}"></div>
+<div class="abc123_dep cba321_name"></div>

I don't want to run the full @modular-css/svelte preprocessor while linting, but I have a simplified version that would prevent a bunch of erroneous missing-declaration warnings from svelte by making those values static.

-<div class="{css.name}"></div>
+<div class="name"></div>

I'd really prefer to not have to disable all compiler warnings, and while I could provide a function that filters out just the specific issue we're seeing around the css.foo stuff being able to run a full preprocessor seems more generically useful.

There are a few hurdles between here and preprocessor support.

One is that preprocessors are allowed to be async and ESLint plugins have to be synchronous. Relying on something like deasync is not acceptable, because of node-gyp requirements it brings along with it. My current idea for this is to Have a separate process do the preprocessing, and to call that with child_process.execSync. It's hideous but it might work.

The next hurdle is that of sourcemaps. The Svelte compiler doesn't yet support actually doing anything useful with the sourcemaps from preprocessors, so there's not a lot of incentive for them to implement them yet. Of the preprocessors in the wild, I don't really know how many of them provide proper sourcemaps. If there are no sourcemaps, I can't map ESLint warnings and errors back to their original locations. If there are sourcemaps, I still don't expect it to be smooth sailing. I've never worked directly with sourcemaps in tooling before, and I've heard only negative things about the experience from other people who have.

Thirdly, even with sourcemaps mapping the errors back to the original code, there will probably be a lot of times when the autofix for the problem that ESLint will provide won't be applicable. Without an 'unpreprocessor', all I'll know is what replacement will fix the problem in the preprocessed source. I could either disable all autofix suggestions when preprocessors are in use, or just go with the best (quite possibly wrong) guess that the corresponding segment of the original code should be replace with the same string as the preprocessed code would. I don't know which is less likely to irritate people.

Anyway, it would be an uphill battle to implement this, but I do realize that not having it is quite a limitation. Sometime in the near future I intend to dig into sourcemap tools and libraries to see what I can make of that. How well that goes will also affect whether I decide to tackle the first issue about async vs sync.

I'd be fine with a limited version that only support sync preprocessors as a first pass, or even something less structured than svelte.preprocess that allowed for a sync transform of the component before ESLint runs.

Right now I have a custom error handler that just throws away all missing-declaration warnings, and that's not great. I can make do w/o actual preprocessing support if #11 is something you're amenable to, I'd be happy to send a PR for that if it'd help.

I'm currently using @pyoner/svelte-ts-preprocess to use typescript with svelte3 - is there currently any workaround until this plugin supports a preprocessor? If so how would that be done! Thanks!

Linting when using a preprocessor that doesn't return a sourcemap (or something equivalent to a sourcemap) is never going to be possible. It looks like that preprocessor doesn't return one. Even with a sourcemap, there are going to be a number of caveats, outlined in my comment above. I'm working on preprocessor support in this fork but nothing is stable yet.

I just stumbled upon this as I was trying to find out why the preprocessed Typescript in my Svelte files is always yielding errors ("unexpected token") on the types 😆

So if I get you right, @Conduitry, this is currently not supported because Typescript itself is at this time only available in Svelte with preprocessing.

Since Typescript is nevertheless a frequent request / addition, would you mind adding a dedicated or more general hint to the README? There is already some info on preprocessors, but somewhere deep in the styles section where people might miss it.

Thanks

Hey, good news (I guess)
I just created a PR allowing to use preprocessor, but pay attention to the comment in the PR to use it properly!
#62

Any update? This feature is a deal braker for us :-)

@NicoCevallos Thank you so much, but if I understand it properly, it solves TS support, but not a preprocessing in general. We also need LESS & SASS support. Hope it will be supported soon :)

@Conduitry You can try synckit which transforms async functions into sync API with worker_threads, so async preprocessor can be supported too.

eslint-plugin-mdx is using this approach to support async remark-lint rules.

Here is the benchmark.

Could we at the very least get a generalized way to ignore all of the inside of template tags for instance where we might be using a yet-unsupported syntax like pug?

Something like svelte3/ignore-styles but for template blocks where alternate html can be used?

Any update on this? No ESlint with scss is a real bummer.

@flosker Thanks a lot, because this issue is really blocking when working with Svelte in a team and file validation is clearly needed.

Actually, I came with my own Node.js solution so the implementation stay simple, customizable and can be integrated with the same toolset in your Svelte project : https://gist.github.com/pyrsmk/464f366de8dab22ac27d2d3ff860b668

Just call it with a list of path globs, like :

node svelte-lint.js 'src/**/*.svelte' 'src/**/*.js' 'src/**/*.ts'

I found a workaround for pug 🎆

I replaced :

+each('links as link')
   a(href='/{link.to}') {link.name}

by :

//- {#each tags as tag}
+each('links as link')
   a(href='/{link.to}') {link.name}
//- {/each}

If there's no support on <style lang="scss">, can it just be silent to it? The svelte-lint.js above did provide this idea that just remove the <style ...</style> block before giving it to eslint.

In fact, I don't think a general "preprocessing" is really needed to happen here because the generated code may or may not be strict enough to be linted. Instead we implement a few common language parsers. Here is an eslint plugin for vue: https://github.com/future-architect/eslint-plugin-vue-scoped-css


Update: found it svelte3/ignore-styles

/** @type {import("eslint").Linter.Config} */
module.exports = {
  settings: {
    "svelte3/typescript": true,
    "svelte3/ignore-styles": ({ lang }) => {
      return lang === "scss";
    },
  }
}