wewowweb / laravel-mix-svelte

mix.svelte();
MIT License
68 stars 10 forks source link

Question : Postcss Support #9

Closed JoshuaCrewe closed 4 years ago

JoshuaCrewe commented 4 years ago

One of the Svelte components I am using in a project makes use of css custom properties. These are not supported in IE (🙄 ) but clients want this support.

Postcss can compile these way with the use of their plugin ecosystem.

This is supported in Laravel mix and works really well.

let mix = require("laravel-mix");

mix
  .js("src/app.js", "dist/")
  .sass("src/app.scss", "dist/")
  .options({
    postCss: [require("postcss-preset-env")]
  });

Which does the following :

:root {
  --color: pink;
}

body {
  background: var(--color);
}

// Becomes ...

:root {
  --color: pink;
}

body {
  background: pink;
  background: var(--color);
}

I have been trying to apply the same functionality to my svelte components. By default any styles written in a Svelte component will get injected onto the page as inline styles. With emitCss: true a virtual css file is created which can then be written out seperately (which is better for performance say the docs).

I cannot get Laravel mix to do anything with this virtual file however. I am interested in knowing how to plumb these styles into the Laravel Mix ecosystem so that we can perform the same processes on them.

The following is the furthest I have got :

let mix = require("laravel-mix");
require("laravel-mix-svelte");

mix
  .js("src/app.js", "dist/")
  .svelte({
    dev: true,
    emitCss: true
  })
  .sass("src/app.scss", "dist/")
  .options({
    postCss: [require("postcss-preset-env")]
  });

If I try to handle the css seperately using mix.webpackConfig() then I get an error saying that there can be only one loader per rule as Laravel Mix has its own .css rule already.

morpheus7CS commented 4 years ago

Hey @JoshuaCrewe,

I wanted to tackle CSS preprocessing a while back, but I never got really far into it.

From what I'm reading in your issue, seems like PostCSS plugins should do the trick, but since these are virtual files, they remain outside Mix's radar? Have you tried using svelte-preprocess as the PostCSS plugin, instead of postcss-preset-env?

Let me know. As always, PR's are welcome, if there is functionality we are currently not supporting, but should.

Kind regards,
g

JoshuaCrewe commented 4 years ago

On Friday I created a reduced scenario, which didn't appear to work. I have definitely tried svelte-preprocess before and it didn't want to work but that was in my actual project rather than in a slimmed down version.

The following works :

let mix = require("laravel-mix");
require("laravel-mix-svelte");

mix
  .js("src/app.js", "dist/")
  .svelte({
    dev: true,
    preprocess: require("svelte-preprocess")({
      postcss: {
        plugins: [require("postcss-preset-env")()]
      }
    })
  })
  .sass("src/app.scss", "dist/")
  .options({
    postCss: [require("postcss-preset-env")]
  });

But not quite how I would like it to. Ideally I would like to be able to pick up the output css (using emitCss) and integrate that with the other styles in the bundle. I think that would be a question on the Laravel Mix repo and might not even be possible.

I am going to take another look at the webpack.mix.js for my project and see if I can feed these changes back into that config.

Passing an options object will give the ability for postcss support out of the box so that is 👍 . I will keep digging to see if there is a way to handle the virtual css file it outputs and report back here if I find a solution like that.

morpheus7CS commented 4 years ago

Hey @JoshuaCrewe,

thanks again for spending so much time on it. Let me know if you come up with something.

Kind regards,
g

dvlpr91 commented 3 years ago

I'm in trouble like you

JoshuaCrewe commented 3 years ago

@dvlpr91 what sort of trouble?

I did get postcss to convert svelte styles using the config above which solved my compatibility issues (it would compile for IE11) but not any further than this. In all honesty, I forgot about it.