Globally Load SASS into your Vue.js Applications

Written by Alex Jover Morales

In the CSS world, we can see plenty of great preprocessors that improve the language, being SASS/SCSS, LESS and PostCSS the most common among them. SASS seems to be still the most popular and used solution by the date of writing, and that's no surprise since it's fully featured and extends the CSS language with an easy to understand syntax.

Thanks to vue-loader, Vue allows to use any of these solutions just by adding the lang="scss" property with the desired language to the style tag in single file components:

<!-- Classroom.vue -->
<style lang="scss">
$bg-classroom: #232323;

.classroom {
  background: $bg-classroom;
}
</style>

As a project grows up, you start separating your SASS variables, mixins and functions in separate files. You can import them by using the @import instruction:

/* scss/_variables.scss */
$bg-classroom: #232323;

<!-- Classroom.vue -->
<style lang="scss">
@import "./scss/_variables.scss";

.classroom {
  background: $bg-classroom;
}
</style>

So far so good, but the thing is that in every component that we want to use a variable, mixin or function we have to import those files, becoming a very repetitive task and ending up with the following lines repeated all across your components:

<style lang="scss">
@import "./scss/_variables.scss";
@import "./scss/_mixins.scss";
@import "./scss/_functions.scss";
/* ... */
</style>

Let's see how can we solve this issue and globally loading all your SASS framework files in the new vue-cli 3.x.

Loading global SASS in the vue-cli

For the purpose of this section, we're assuming you have a project created with vue-cli v3.x using the default configuration. If you don't have it, you can create it by installing the cli and running the create command:

npm install -g vue-cli
vue create awesome-project-name

From here, let's start by installing the required SASS dependencies:

npm install --save-dev node-sass sass-loader

Vue-cli allows to modify its configuration by creating a vue.config.js file at the root of the project that exports an object with several configuration options.

Among them, we have the css option, which includes a loaderOptions that we can use to change the internal configuration of vue-loader.

Master Vue.js with Vue School

Top notch Vue.js courses and over 200 lessons for just $12 per month!

Probably you didn't know this trick, but we can execute some global CSS preprocessor code using the data option, so we can use that to import our CSS tooling:

module.exports = {
  css: {
    loaderOptions: {
      sass: {
        data: `
          @import "@/scss/_variables.scss";
          @import "@/scss/_mixins.scss";
        `
      }
    }
  }
};

Note: the "@" in vue-cli is an alias that points to /src

Notice that we've specified the sass loader under the loaderOptions option. Just like that, all the code in those files will be available in the global scope. So from any component we can use it out of the box:

<style lang="scss">
.classroom {
  /* No need to import, it just works \o/ */
  background: $bg-classroom;
}
</style>

Setup on projects not using vue-cli 3.x

If you're not using vue-cli 3.x, you'll need to tweak the vue-loader options in your Webpack configuration files. Here you can see an example:

// webpack.config.js
{
  test: /\.scss$/,
  use: [
    'vue-style-loader',
    'css-loader',
    {
      loader: 'sass-loader',
      options: {
        data: `
          @import "@/scss/_variables.scss";
          @import "@/scss/_mixins.scss";
        `
      }
    }
  ]
}

We're not going to dive deeper on Webpack configuration, since it's out of the scope of this article and it can take several articles of their own, but instead I'm showing you what you need to change to in yours in order to achieve global SASS loading.

Caveats

You have to make sure that the files that you import in the data configuration contain only SASS code that doesn't get rendered, such as variables, mixins and functions. Otherwise, that code will end up repeated for each component in the final post-processed css file.

That’s just the way it works: vue-loader will prepend all those files you’ve defined in each component CSS’s.

For instance, let’s say you have 10 components and you preload the file _*variables.scss* as we’ve seen above, and that _*variables.scss* files contain any CSS rule such as:

.box {
  color: $red-color;
}

That will actually be included in the CSS part of each component, ending up with 10 repeated .box rules.

Wrapping up

I hope this article has been as useful for you as it was for me. Go and don't repeat your SASS imports!

Master Vue.js with Vue School

Top notch Vue.js courses and over 200 lessons for just $12 per month!

  1. there is another way to create a global rule style as a class by example?
    that makes me possible to reach from any component, and of course, avoiding the duplicate

  2. I did followed the same steps an I am getting an error

    @ ./node_modules/vue-style-loader??ref--9-oneOf-1-0!./node_modules/css-loader??ref--9-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--9-oneOf-1-2!./node_modules/sass-loader/lib/loader.js??ref--9-oneOf-1-3!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/pages/index.vue?vue&type=style&index=0&lang=sass& 4:14-453 14:3-18:5 15:22-461

  3. I managed to get my styles globally using the plugin vue-cli-plugin-style-resources-loader (installed from the vue ui) that generate a vue.config.js file in the root folder, then I just filled with the following snippet:

    const path = require(‘path’)
    module.exports = {
    pluginOptions: {
    ‘style-resources-loader’: {
    preProcessor: ‘scss’,
    patterns: [
    path.resolve(__dirname, ‘src/styles/variables.scss’),
    path.resolve(__dirname, ‘src/styles/globals.scss’),
    path.resolve(__dirname, ‘src/styles/icons.scss’)
    ]
    }
    }
    }

    But my question right now is about the caveats you just mentioned, because those file will also get classic css rules : theses are repeated for each components, I can see it when inspecting the elements. Do you have a simple workaround for this ? I read some stuffs involving webpack manipulations but want to avoid that as I setup my project with vue CLI and don’t have webpack conf folders in the root.

    Nice article anyway!

  4. For some reason I am not able to get this working. Using the variables in the components results in ‘undefined variable’ erros. When I import the the variables scss file in the components itself, it works. It’s almost like vue.config.js is completely ignored. Running Vue cli 3.5.0 and installed sass-loader and node-sass as instructed in the article.

Leave a Reply

Your email address will not be published. Required fields are marked *

Up Next:

5. Testing a Vue Component

5. Testing a Vue Component