Search code examples
vue.jswebpacksassbulma

Importing SASS variables into Vue component


I'm working on building a webpage using Vue, Typescript, Webpack, and Bulma. I got everything working and building correctly but I noticed that some of my bundles were massive (over 2mb in some cases). After a lot of confusion I figured out it was because I was importing my main SCCS file that included Bulma, Bulma Fluent, and Material Design Icons into my components so that I could use the variables, mixins, and extend some of the classes. From what I understand @import simply copies everything from the import, which would explain my massive bundles.

A close approximation of my working code:

main.scss

/*Color customizations*/

@import "bulma-fluent/bulma.sass";
@import "buefy/src/scss/buefy";
@import "@mdi/font/scss/materialdesignicons";

/*Some custom classes*/

MyComponent.vue

/*Template and Script here*/
<style scoped lang="scss">
    @import "./main.scss";

    .floating {
        @extend .m-1;
        position: fixed;
        bottom: 0;
        right: 0;
    }

    @include mobile {
        .floating {
            max-width: unset;
            left: 0;
        }
    }
</style>

I want to be able to reference classes/variables/mixins from my main.scss without it ballooning the size of my modules. I thought about creating a separate variables.sass file but I couldn't get that to work plus it doesn't fix the issue of extending styles. I saw this question but I'm not using Nuxt.

How can I get this working?

P.S. I'm a bit of a noob when it comes to Webpack/Vue/SASS/SCSS so I apologize if I'm just being dumb here.

Edit

In the end I split out the variables to their own file and imported those globally. It doesn't solve the use case of extending styles but I think that's a lost cause. My code is below:

Variables.scss

/*Customization here*/
@import "bulma/sass/utilities/functions.sass";

@import "bulma-fluent/src/sass/color/_all.sass";

@import "bulma/sass/utilities/initial-variables.sass";
@import "bulma/sass/utilities/derived-variables.sass";
@import "bulma/sass/utilities/mixins.sass";

Main.scss

@import "./Variables.scss";

@import "bulma-fluent/bulma.sass";
@import "buefy/src/scss/buefy";
@import "@mdi/font/scss/materialdesignicons";

/*Some custom classes*/

webpack.js

/*Other irrelevant configurations*/
{
    test: /\.s[ac]ss$/,
    use: [
        "vue-style-loader",
        "css-loader",
        {
            loader: "sass-loader",
            options: {
                additionalData: `
                @import "./Variables.scss";
                `
            }
        }
    ]
},

MyComponent.vue

/*Template and Script here*/
<style scoped lang="scss">
    .floating {
        margin: $size-1;
        position: fixed;
        bottom: 0;
        right: 0;
    }

    @include mobile {
        .floating {
            max-width: unset;
            left: 0;
        }
    }
</style>

Solution

  • I use the same stack. I have variables.scss file with variables and bulma mixins and that variables.scss file is imported only in main.scss . To make all variables and mixins available in all components without using @import in style section you should add loaderOptions section to vue.config.js file. Here is my vue.config.js file:

    module.exports = {
      css: {
        loaderOptions: {
          scss: {
            prependData: '@import "~@/assets/scss/_variables.scss";'
          }
        }
      }
    }