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

Strange behavior with postcss and custom languages #309

Closed
non25 opened this issue Feb 8, 2021 · 9 comments
Closed

Strange behavior with postcss and custom languages #309

non25 opened this issue Feb 8, 2021 · 9 comments
Labels
bug Something isn't working

Comments

@non25
Copy link

non25 commented Feb 8, 2021

I've been messing around with svelte-preprocess, trying to squeeze more performance for tailwindcss and got some interesting results instead...

For example I can make custom langs, to make purpose-fit performant configs for certain tasks.

preprocess: sveltePreprocess({
  custom({ content, filename }) {
    return postcss(customPlugins)
      .process(content, { from: filename })
      .then(({ css: code, map }) => ({ code, map }))
      .then(({ code, map }) => {
        console.log('custom launched');
        return { code, map };
      });
  }
})

And every time component with lang="custom" is being built, I get two console logs, indicating that postcss has run twice instead of once. 🤔

Also I can configure postcss for lang="postcss" how I see fit just for svelte-preprocess, and make some default configuration for regular style tags while I'm at it:

preprocess: sveltePreprocess({

  defaults: { style: 'style' },
  style({ content, filename }) {
    return postcss([postcssImport])
      .process(content, { from: filename })
      .then(({ css: code, map }) => ({ code, map }))
      .then(({ code, map }) => {
        console.log('style launched');
        return { code, map };
      });
  },

  postcss({ content, filename }) {
    return postcss(otherPlugins)
      .process(content, { from: filename })
      .then(({ css: code, map }) => ({ code, map }))
      .then(({ code, map }) => {
        console.log('postcss launched');
        return { code, map };
      });
  },
  // or
  postcss: {
    plugins: postcssConfig.plugins
  }

})

And I will get both of them run for regular style tags.
So if I use postcss: true or postcss() {...} function - it will launch it for regular style tags along with what I have defined as default.
The only way to prevent this from happening is to avoid using truthy postcss key in config.

I don't think svelte-preprocess should work like this. It is unintuitive at best. 🤔

@kaisermann
Copy link
Member

kaisermann commented Feb 8, 2021

Hey @non25 👋 this happens because we purposefully run postcss after a possible style preprocessor, so it's possible to have postcss being executed after a scss style was preprocessed. It's the same for the babel preprocessor. It always runs after a script tag was preprocessed.

This assumption may not be 100% right, but changing this behavior would be a big breaking change

@non25
Copy link
Author

non25 commented Feb 8, 2021

Hi @kaisermann 🙂 Thanks for a fast response.

What do you think about having an option which controls such behavior ?

And more important, what about double run for custom languages ? Is that intentional too ? 🤔

@kaisermann
Copy link
Member

@non25 Can you provide a minimal repro with that happening?

And, in theory, the mechanism to disable such postcss behavior would be postcss: not-truthy. I'm not sure what we could do to change the current behavior apart from that, but I'm open to listening to ideas.

@non25
Copy link
Author

non25 commented Feb 9, 2021

@kaisermann Sure, take a look.

/~https://github.com/non25/svelte-template-webpack/commits/svelte-preprocess-repro

I suppose it should launch postcss for that too, instead of the second run of same custom language preprocessor ? 🤔
Feels like a bug.

Now I understand why postcss launches after other langs. I think it is completely reasonable.

I'm kinda spoiled with webpack's pipelines, which allows me to do crazy stuff like this:
/~https://github.com/non25/svelte-tailwind-template/blob/4b2bfb515fe838918300c8cb528877fd7c21ea63/webpack.config.js#L64-L104

Not like it is sane, but I can. 😀

The only configuration I can think of which can't be done properly is the follwing one:

scss => postcss(postcss-import, autoprefixer, cssnano) => emitCss
custom-precss?(sugarss, postcss-nested, etc.) => postcss(postcss-import, autoprefixer, cssnano) => emitCss

Ideally, I would want one plugin list for postcss post stuff, and second plugin list for postcss pre stuff.
And for custom lang with postcss pre stuff I would want to only run postcss once with pre and post plugin lists joined.
That would be cool.

Maybe we could turn off successive postcss run if previous style preprocessor returned something like:

{ code, map, disablePostcss: true } or { ..., skipPostcss: true }

That way we could control postcss behavior to fit any purpose without introducing breaking changes ? 🤔
What do you think ?

@kaisermann
Copy link
Member

kaisermann commented Feb 10, 2021

Oh, interesting! There's indeed an issue here. We're getting double custom logs because the custom transformer is taking precedence over the postcss one. Will try to fix that soon!

@non25
Copy link
Author

non25 commented Feb 10, 2021

Cool. 🙂
What about conditionally skipping subsequent postcss run depending on something like skipPostcss: true present in previous processor's returned object ? 🤔
I think that would be nice addition.

@kaisermann kaisermann added the bug Something isn't working label Feb 10, 2021
@kaisermann
Copy link
Member

kaisermann commented Feb 10, 2021

IMO, having something like skipPostcss seems too specific and edge-casey. If you don't want two postcss implementations overlapping, you could can create two custom transformers custom1 and custom2 and call whatever you want in them. You would just need to write lang="custom1" and lang="custom2" where needed. That would also "fix" (for your case) the double log issue.

@non25
Copy link
Author

non25 commented Feb 10, 2021

Is there a good-looking way to wrap default scss/sass processor to be able to extend it's functionality? 🤔
I saw exports in index.js.
Reimplementing scss/sass processor in the config is kinda messy.
I'll try to experiment later...
Thanks. 🙂

Edit: /~https://github.com/sveltejs/svelte-preprocess/blob/main/docs/preprocessing.md#overriding-preprocessors uh oh 🙂

That's what I end up with:

scss(data) {
  return scss().style(data).then(({ code: content, map }) => {
    postcss().style({ ...data, content, map })
  });
}
// or
scss: async (data) => {
  const { code: content, map } = await scss().style(data);
  return await postcss().style({ ...data, content, map });
}

Can't think of something less ugly than this. 🙂

@kaisermann
Copy link
Member

@non25 That option exists as a way to override the lib's native transformers, not extend them. I wouldn't say your way is ugly considering what you want to do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants