Laravel-mix: extractStyles not working as intended with css in vue components

Created on 31 Oct 2020  路  9Comments  路  Source: JeffreyWay/laravel-mix

  • Laravel Mix Version: 6
  • Node Version (node -v): 14.15.0
  • NPM Version (npm -v): 6.14.8
  • OS: Ubuntu 18

Description:

Laravel mix is unable to extract css from vue component and throwing error.

webpack.mix.js

let mix = require('laravel-mix');
const del = require('del');
const tailwindcss = require('tailwindcss');

del('./public');
mix
    .setPublicPath('public')
    .webpackConfig({
        optimization: {
            providedExports: false,
            sideEffects: false,
            usedExports: false
        }
    })
    .js('resources/src/js/app.js', 'public/js/')
    .sass('resources/src/sass/vendor.scss', 'css')
    .sass('resources/src/sass/landing.scss', 'css')
    .sass('resources/src/sass/app.scss', 'css')
    .copyDirectory('resources/src/img', './public/img')
    .copyDirectory('resources/src/font', './public/font')
    .copy('resources/src/favicon.ico', './public/favicon.ico')
    .vue({
        extractStyles: true
    })
    .options({
        processCssUrls: false,
        postCss: [tailwindcss('./tailwind.config.js')]
    }).extract();

Vue component:

<template>
  <div class="relative w-12 my-1 cursor-pointer" @click="toggle">
    <div v-if="isEnabled" class="w-12 h-8 rounded-full" :class="color">
      <div
        class="absolute top-0 flex items-center justify-center w-6 h-6 mt-1 -ml-6 bg-white border-gray-300 rounded-full transition-all transform ease-linear duration-100 shadow-toggle left-96"
      ></div>
    </div>

    <div v-if="!isEnabled" class="w-12 h-8 bg-gray-300 rounded-full">
      <div
        class="absolute top-0 flex items-center justify-center w-6 h-6 mt-1 bg-white border-gray-300 rounded-full transition-all transform ease-linear duration-100 shadow-toggle left-4"
      ></div>
    </div>
  </div>
</template>

<script>
export default {
  name: "ToggleSwitch",
  model: {
    prop: "isEnabled",
    event: "toggle",
  },
  props: {
    isEnabled: Boolean,
    color: {
      type: String,
      required: false,
      default: "bg-green-600",
    },
  },
  methods: {
    toggle() {
      this.$emit("toggle", !this.isEnabled);
    },
  },
};
</script>

<style scoped>
.shadow-toggle {
  box-shadow: 1px 0px 2px 1px rgba(0, 0, 0, 0.1),
    -1px 1px 4px 1px rgba(0, 0, 0, 0.06);
}

.left-4 {
  left: 4%;
}

.left-96 {
  left: 96%;
}
</style>

When running the mix command for watch and visiting the page gave following error:
image

What is the possible solution to above?

bug

Most helpful comment

I've a similar problem in laravel mix 4.2.0. In my case, if I use:
extractVueStyles: '[name].css',

it works perfectly but it created on the wrong folder, so at public/js/app.css and public/js/vendor.css

My first code attemplt was:
extractVueStyles: 'public/js/vue.css',

But that would create a vue.css with only the content of vendor.css, the app.css seems to be overwritten by the vendor one

So for now, I'm using extractVueStyles: '[name].css', since it works with the only inconvenient of having the css on a js folder.

best regards

All 9 comments

It appears that this has to do w/ style extraction + use of async components. I'll take a look today.

@thecrypticace Did you get chance to look into it?

I've a similar problem in laravel mix 4.2.0. In my case, if I use:
extractVueStyles: '[name].css',

it works perfectly but it created on the wrong folder, so at public/js/app.css and public/js/vendor.css

My first code attemplt was:
extractVueStyles: 'public/js/vue.css',

But that would create a vue.css with only the content of vendor.css, the app.css seems to be overwritten by the vendor one

So for now, I'm using extractVueStyles: '[name].css', since it works with the only inconvenient of having the css on a js folder.

best regards

@Daniel4Digital This pointed me in the direction as to why something isn't working. When using extractVueStyles: 'path/to/filename.css' the vendor css is just straight up ignored. When setting to extractVueStyles: '[name.css]' it outputs the vendor styles, but in the JS directory. Which is _fine, I guess 馃し _. Frustrating though. I'd like for a vendor css file to be generated regardless.

Any fixes to this?

If i apply

.vue({
    extractStyles: 'app.css',
})

in laravel mix vue options, the webpack tries to load chunk called "app.js" when trying to load dynamically imported components.

So I've confirmed that async components + style extraction doesn't work properly. If I tell webpack to only extract styles for non-async components things work fine but that's definitely not ideal.

Today I updated to laravel mix 6 (Saw today too that this issue regards version 6) and try to use vue({
extractStyles: 'css/app.css'
})

And the app.css is now on the correct folder, but the vendor.css still goes to js folder no matter what.

Even if I use extractStyles: true, the vendor.css still goes to js folder. And using '[name].css' no longer works, since it seems not to be needed anymore.

Dunno if related to this issue no more. But well.

In v6, this builds a vendor.css file in public/styles but also a main.css file in public/scripts (?? 馃槃):

mix.js('resources/scripts/main.js', 'public/scripts/main.js').vue({extractStyles: 'public/styles/vendor.css'})

Also when using

.vue({
    extractStyles: '[name].css',
})

In laravel mix vue options, the build output is a plain "[name].css" file. In laravel-mix 5, the css file was created using the input scripts name.

For example if i have .js('resources/application.js', 'app.js').js('resources/admin.js', 'admin.js');in webpack.mix.js. _(Two different vue bootstrapping scripts.)_ In laravel-mix 5 the extractVueStyles '[name].css' would create two css files; app.css and admin.css. If i use laravel-mix 6, the output file is just [name].css which includes styles from both scripts.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rderimay picture rderimay  路  3Comments

mstralka picture mstralka  路  3Comments

rlewkowicz picture rlewkowicz  路  3Comments

mementoneli picture mementoneli  路  3Comments

nezaboravi picture nezaboravi  路  3Comments