DEV Community

Cover image for My SCSS setup within a Vue CLI 3 project
Lynne Finnigan
Lynne Finnigan

Posted on • Updated on

My SCSS setup within a Vue CLI 3 project

I never realised that I had lost some of my passion for development until Vue.js came along. I'm still learning, but it has made coding fun again for me. I've played with it on and off for a little while, and now I'm working on building my own website from scratch again using Vue.

One of the hardest things to get my head around was the project structure. It's something not very many tutorials cover. Eventually I pieced it together, and came across my next problem. SCSS.

I couldn't find a lot of information on how people usually handle their use of global styles, and also styles within each component. I had an idea of how I wanted to do it, but no idea how to actually achieve it. If you're in a similar situation, I hope this article helps in some way.

So here's how I create a Vue CLI 3 app from scratch...

Creating the app

Assuming you have Vue CLI 3 installed, run the following command in the terminal to launch the Vue Project Manager in your browser.

vue ui
Enter fullscreen mode Exit fullscreen mode

If you don't have it installed yet, here is the documentation you need.

To create an app, simply click the create button at the top of the screen in the Vue Project Manager. This will then take you through various steps which you would normally have to do in the terminal, and allow you to save your settings as a preset. Handy!

For my projects I tend to choose the following options:

  • Package manager: Yarn
  • Preset: Manual (for the first project)
  • Features: Babel, Router, CSS Pre-processors, Linter/Formatter
  • History mode: on
  • Pre-processor: SCSS/SASS
  • Linter/Formatter: ESLint + Prettier (Lint on save)

Then click Create Project and it will create your app. You should now have a basic Vue.js project. You can run this by going to the tasks tab in the Vue Project Manager and clicking on serve to launch your site locally.

Setting up our styles

First of all, create a folder within the src folder named styles. This is where we will store all of our SCSS for the app. In this folder, create a file that will be used for your global styles e.g. global.scss

In the Vue Project Manager, go to the Plugins tab and click on the Add plugin button. We want to install a plugin called vue-cli-plugin-style-resources-loader.

Once this has installed, it will add a file to the root of your project called vue.config.js

Go to vue.config.js and add the following code, replacing the stylesheet name/path with whatever you have named your scss file for your global styles.

const path = require("path");

module.exports = {
  pluginOptions: {
    "style-resources-loader": {
      preProcessor: "scss",
      patterns: [path.resolve(__dirname, "./src/styles/global.scss")]
    }
  }
};
Enter fullscreen mode Exit fullscreen mode

Now, all of the styles from global.scss will be available across the project and within components. Normally my SCSS file structure looks something like this to begin with:

Image of scss file structure

I have basic rich text styles within _base.scss, and variables, typography, etc are all stored in their respective folders as partials. These are then imported into the global stylesheet like this:

@import "setup/normalize.scss";
@import "setup/typography.scss";
@import "setup/variables.scss";
@import "setup/mixins.scss";

@import "basics/base.scss";
@import "basics/layout.scss";
@import "basics/links.scss";
@import "basics/buttons.scss";
Enter fullscreen mode Exit fullscreen mode

I also have a folder within the styles directory for components. Each component I create in Vue will have it's own scss partial. A useful feature of Vue.js is that you can add styles within the Vue component file, and these can be scoped so that they will only render if that specific component is rendered on the page.

Now that we're all set up, adding styles to a component is easy. Here is how it would look in my component Example.vue

<template>
  <div>
    <h1>I am a component!</h1>
  </div>
</template>

<script>
export default {
  name: Example
}
</script>

<style lang="scss" scoped>
@import "../styles/components/example.scss";
</style>

Enter fullscreen mode Exit fullscreen mode

Inside the _example.scss file you would have access to all the variables/typography/mixins and anything else you have added in your global styles. You could also write it out inside the style tag like this, with $c-title being our global variable name for the title colour:

<style lang="scss" scoped>
h1 {
  color: $c-title;
}
</style>

Enter fullscreen mode Exit fullscreen mode

However, I prefer to keep all of the styles in one place overall (the styles folder & sub folders), with the file names named the same as the component itself. This makes it easier to find and for other people to work with.

This has been a long(ish) article, so if you've made it this far, thanks for reading! I hope this helps in some way. Have fun with your Vue projects and create something awesome!

Latest comments (55)

Collapse
 
eligarlo profile image
Eliahu Garcia Lozano

Great article. I followed step by step and I really enjoyed this setup.
The only thing I could not make working are the scoped styles, every time I import a .scss to a component if I declare it as scoped it won't work...

Collapse
 
lynnewritescode profile image
Lynne Finnigan • Edited

Thanks for reading the article! Hmm strange, what happens? Do the styles just not show up? Do you have an example of your code for the scoped styles?

Collapse
 
eligarlo profile image
Eliahu Garcia Lozano

Finally I could make it work.
Yes what happened was that when I declared it as a scoped styles did not show up, but then I realized that I was importing styles twice (also from global.scss). I changed that and it worked.

Thanks again for your great post, I've read it many times as yesterday I was starting a new project and I wanted this setup for it.

Thread Thread
 
lynnewritescode profile image
Lynne Finnigan

Ah great, glad you got it working!
I'm happy the article has helped :) good luck with your project!

Collapse
 
vinous22 profile image
Mannar

Hi Lynne my styles are working without need to @import "../styles/components/example.scss" in the component, how come?

Collapse
 
vishalpatra profile image
Vishal Patra

ka bakwass likho be .

Collapse
 
vishalpatra profile image
Vishal Patra

OMG AWESOME POST LOVE IT!

Collapse
 
peoray profile image
Emmanuel Raymond

Dammit, this is what I have been searching for. Thank you so much for writing this.

Question: Can you give a brief description of each of the folders in the style directory?
Also, you mentioned that the example.scss file would have access to other files like typography, etc but you didn't show how? I want to assume it happens by default?

Collapse
 
lynnewritescode profile image
Lynne Finnigan

Thanks :)

The folders in the style directory are just the way I normally organise things and they are fairly self-explanatory from the names. The Views folder contains partials for styles relating to views. Basics contains things like basic rich text styles, links, buttons, etc. Setup is things like variables mixins, and functions. And components would be the styles for each component.

The point of the article is that you need to use the plugin in order to make things like the variables available in other scss files. So if you had a global.scss file setup in the config using the plugin, inside global.scss you would import any scss partials you need to be available across the whole site/app.

Then in the example component I created, example.scss would just have your styles for that component, but the point is that you can use variables within it because they are served globally.

Collapse
 
peoray profile image
Emmanuel Raymond

Okay, what about access to other styles like the button or typography. Sorry, but I'm a little bit confused. since the way you are explaining it, you are only making reference to the variable styles.

Collapse
 
camielm profile image
camielm

nice article, but i have a question.
I'm new with Vue.js. When I leave styles blank in the app.vue, and I only want to use my global.scss, my global.scss is not being compiled. Is this normal behavior?

Collapse
 
lynnewritescode profile image
Lynne Finnigan

Is there anywhere I could see your code? it's hard to tell what the issue could be without being able to see it

Collapse
 
camielm profile image
camielm

unfortunately thats not possible.
The problem is when my style tags in my app.vue are emtpy:

, the scss files are not compiling...

When I put anything between them, for instance:

body{line-height: 20px;}

my SCSS files are compiling...

Collapse
 
burkeholland profile image
Burke Holland

Hey Lynne!

This article is so good. I love how you've organized these files. It's super clean and easy to see what styles are where. A novel approach to the problem. Thanks for writing it!

Collapse
 
lynnewritescode profile image
Lynne Finnigan

Thank you so much! :)

Collapse
 
jerrymerchand profile image
Jerry-Merchand • Edited

Nice article :)!

I'm new to vue 3 and vue UI. I personally think that Vue 3 should add the required SCSS Loader plugin when you select it and create a standard style folder and some default files. I really appreciate your article! It filled in some gaps. I'm not a web developer, until the last year and then only really looking at all the new frameworks like; AngularJS, Angular, React, Preact, etc. I think Vue 3 has a lot going for it over vuejs. However, Seems like the Documentation for vue 3 needs to improve some. What a lot of articles lack are fine details that beginner would need. A lot of students and others moving over to web programming need every detail possible. I think it would be great if this article has some of your sample files contents to show what a basic scss file looks like and the structure inside your files global.scss. Thanks again! Great Job!!

Collapse
 
lynnewritescode profile image
Lynne Finnigan

Thanks! I never really thought about the official docs before but I guess it is lacking in terms of how to structure/set up styles. I might look into contributing to the docs :) I'm glad it helped you!

Collapse
 
jerrymerchand profile image
Jerry-Merchand • Edited

Hey Lynne, really nice job and quick response! I was tasked with creating a vue app for mobile like two weeks ago. So learning at a high rate of speed. :)

I'm really lacking in knowledge of css and scss. I have added bootstrap to my vue app. And now thanks to your article, I know i need to add my bootstrap scss files to the global.scss file as imports. However, it's blank right now.

One thing I'm trying to wrap my head around is css is cascading the css rules down but we are thing to sandbox them into each component (vue). And in the end we will combine them all into one file for deployment.

Does my assumption seem right about importing the scss file into the global.scss file? The bootstrap scss files are located under the node_modules folder in subfolders.

Thread Thread
 
lynnewritescode profile image
Lynne Finnigan • Edited

The way I use it, and think about it, is that anything in the global scss file applies across the whole site and this is generally things like variables, grid, layout, and basic styles. It should be styles that aren't very specific, sort of like your baseline.

For each component, when you write a scss file for it and the styles are nested inside the component class name, it shouldn't affect anything else other than that one component. This is what makes it modular.

In your component scss file, you might want to overwrite something that has been set in the global stylesheet, and that's completely fine. As long as it is nested inside your component class name then it should only affect that one component.

Does that make sense?

Collapse
 
napalmdev profile image
DΓͺnis Nunes

wowww, amazing, I was precisely looking for this, to use variables and mixins inside my scoped style, I'm testing using atomic design with VueJS, and this import of variables is a must have part of the solution, thank you very much \o/

Collapse
 
lynnewritescode profile image
Lynne Finnigan

No problem, I'm so glad it helps!! :)

Collapse
 
a_omaf profile image
Aomaf

Life saver,
actually this article it is better than every tutorial i watched in the same topic,
I have always been confused about setting up a style architecture for my vue projects.
good job

Collapse
 
lynnewritescode profile image
Lynne Finnigan

Thank you so much! I'm glad it has helped :)

Collapse
 
secular12 profile image
Mark Dekin

Like the article, but quick question. I am trying to create a Vue Component Library, where all of the components have a default scss variable in them, for example:

$color: #000 !default

The intention is that the component will have default styling that could easily be configured/overridden when I later install my component library but override the styles in a configurable variables scss file. I can't seem to figure out on how to have the vue library's config file to accept that scss file.

Any insights?

Collapse
 
lynnewritescode profile image
Lynne Finnigan

Hi Mark, do you have a code example of the config file and where you're trying to add the scss?

I'd imagine that you could probably override based on the order you're importing the scss files into the component, but I'm not sure I understand what you're looking to do.

Collapse
 
hjelperne profile image
hjelperne • Edited

Hi - a newbie question here - if anyone can please fill me in:

Following your guide I have successfully added vue-cli-plugin-scss-base (0.1.10) to my vue project.
And when using the "vue ui" (Vue Project Manager in your browser) approach - the scss folder with all the scss files get generated (as well as changes to vue.config.js and App.vue).

I suppose this happens just about the time the terminal which I engage "vue ui" from reports:
"πŸš€ Invoking generator for vue-cli-plugin-scss-base...
βœ” Successfully invoked generator for plugin: vue-cli-plugin-scss-base
The following files have been updated / added:" (and the list of files: src/scss/animations/_animations.scss etc.......)

Now the question is: How would I go about doing this from the terminal??

I mean: "npm i vue-cli-plugin-scss-base" adds the statements to package.json and package.lock.json (in dependencies)

And "npm i vue-cli-plugin-scss-base --save-dev" adds to devDependencies (same as vue ui - from browser) when I add the plugin there..

but after that npm install / npm build / (rebuilding entire project in IntelliJ) or whatever I tried - it doesn't seem to have any effect. The scss file creation and file changes (mentioned above) never appear/happens.

Surely there is some essential command (knowledge) I am completely missing.

NEVER mind - the solution was as simple as: "vue add vue-cli-plugin-scss-base"

best regards,
H

Collapse
 
lynnewritescode profile image
Lynne Finnigan

Hi, I was just about to look into this, did you get it all sorted then?

Collapse
 
lynnewritescode profile image
Lynne Finnigan

Thanks, I'm really glad this helped you! 😊

Collapse
 
vertcitron profile image
Vert Citron

I have in a project a huge components base. Some have their style tag in scss, and others in sass.

When I put scss in 'preProcessor', it works for scss styles but not sass ones. If I put sass, the same, it does not works foe scss components.

Is there a way to import my variables file in both componetns ?

Collapse
 
lynnewritescode profile image
Lynne Finnigan

Off the top of my head, it could be the import syntax. I think in scss it looks like this:

<style scoped lang="scss">
    @import 'styles.scss'
</style>

and in sass like this (without the quotes):

<style scoped lang="sass">
    @import styles.scss
</style>
Collapse
 
shakilzaman87 profile image
Shakil Zaman

I make a CRM with Vue.js & Firebase. Checkout the demo here.
codecanyon.net/item/puku-crm/22205914?