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.

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!