node -v): 14.15.0npm -v): 6.14.8Laravel 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:

What is the possible solution to above?
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.
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