Reputation: 307
Question
How can I globally import variables.scss
1. without importing them in every file and 2. by referencing instead of duplicating them in my build?
Setup
I use Vue2 and laravel-mix and I have index.scss
imported in my main.js
variables.scss
$--test: #ff0000;
index.scss
@import 'variables';
.dashboard-title {
color: $--test;
}
This colors the title red. But when I try to do the same thing inside of the component, it doesnt work:
<style scoped lang="scss">
.dashboard-title {
color: $--test;
}
</style>
This doesn't work, but I proved that index.scss
is global in my first example. How is
variables.scss
not global, when I import it in my global index.scss
?
I can fix the error by importing the variables file in the component, but by doing this, I essentially duplicate the whole variables.scss
file every time I import it in a vue component.
I found this out by analyzing my bundle with a webpack bundle analyzer, this is the output:
webpack bundle analysis image
(all blue crossed parts are increased in size because the variables file is imported, this isn't a big problem now, but this will exponentially increase my bundle size with time)
It would reduce my bundle size by atleast 20% right now...
How can I reference the variables.scss
file instead of duplicating its content?
What I've tried:
https://css-tricks.com/how-to-import-a-sass-file-into-every-vue-component-in-an-app/ (I wasn't able to "migrate" this to a laravel-mix config)
I've also tried using purgeCss
to remove duplicate css, this just completely messed up my styles but reduced the bundle size by 50% lol
Adding this to the webpack.mix.js
mix.webpackConfig({
module: {
rules: [
{
test: /\.scss$/,
use: [
{
loader: 'sass-loader',
options: {
//this might be "data" or "prependData" depening on your version
additionalData: `@import "./resources/js/styles/variables.scss";`
}
}
]
}
]
}
})
This does make the variables global, but imports(duplicates) them for every vue component, even if they aren't being used.
Edit: This only is an issue, when the imported file is relatively big. In my project, the imported file itsself imported a theme scss (to get access to the themes variables), which ultimately copied this whole thing everywhere I needed the variables.
I fixed this by defining my custom variables in a seperate file and using those variables in the "overwriting-variables" file, something like this:
custom-variables.scss
$red: #ff0000;
overwriting-variables.scss
import 'theme.scss'; //this bloated my project
import 'custom-variables';
$--theme-red: $red
And when I needed this theme color in my vue components I just imported the custom-variables.scss
instead of overwriting-variables.scss
.
This does fix my bloating issue, but doesn't fully solve the problem, I still have multiple instances of the custom-variables.scss
in my project, it just doesn't matter (yet) because its really small. So I'd be still happy to hear about other solutions!
Upvotes: 4
Views: 2387
Reputation: 307
So I got it working with laravel-mix like this:
mix.webpackConfig({
module: {
rules: [
{
test: /\.scss$/,
use: [
{
loader: 'sass-loader',
options: {
//this might be "data" or "prependData" depening on your version
additionalData: `@import "./resources/js/styles/variables.scss";`
}
}
]
}
]
}
})
Not sure yet if this prevents the duplication though
Edit: It does not prevent duplication, it does increase the bundle size in every vue component. So I now have a 150% bigger bundle, because the variables file is imported in every single vue component. Even if the variable isn't even used.
Upvotes: 0
Reputation: 480
If you import every .scss in your index.scss, then every variable should work. Try this in your vue.config
css: {
loaderOptions: {
// by default the `sass` option will apply to both syntaxes
// because `scss` syntax is also processed by sass-loader underlyingly
// but when configuring the `data` option
// `scss` syntax requires an semicolon at the end of a statement, while `sass` syntax requires none
// in that case, we can target the `scss` syntax separately using the `scss` option
scss: {
prependData: `@import "@/style/index.scss"`
}
}
},
Upvotes: 1