vue.js: always load a settings.scss file in every vue style section
Asked Answered
Z

9

21

I find myself repeating this same pattern in every .vue file, in order to use variables, etc.:

<style lang="scss">
  @import "../styles/settings.scss";

  .someclass { color: $some-variable; }
</style>

or if it's nested in a folder I have to remember to be careful with the path:

<style lang="scss">
  @import "../../styles/settings.scss";

</style>

Is there a way to globally import that settings.scss file in every .vue file I create? I looked in the docs and didn't see it, but maybe I missed it, or maybe this is something I need to leverage webpack to do?

Zoan answered 13/8, 2016 at 1:35 Comment(1)
cli.vuejs.org/guide/…Rattletrap
Z
9

The official docs have been updated since I asked this question: https://vue-loader.vuejs.org/en/configurations/pre-processors.html

For anyone else viewing this in 2017 and beyond, check out the instructions under 'loading a global settings file'.

Zoan answered 16/10, 2017 at 20:39 Comment(3)
Does this also allow use of global mixins?Bohr
That link no longer talks about "loading a global settings file" -- still looking for a simple way to load global css in vue 2.x.Antitank
@Antitank it's in the official docs, there's a huge thread on github about it too with many examplesZoan
S
14

I have struggled with the same question for a while. But there's a really simple fix. This feature comes through node-sass itself.

so you can declare your scss globals in a file, say globals.scss whose path is:

/src/scss/globals.scss

Now you can simply edit the vue-loader config:

loaders: {
  sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1&data=@import "./src/scss/globals"',
  scss: 'vue-style-loader!css-loader!sass-loader?data=@import "./src/scss/globals";'
}

and voila! You have the scss globals available across all your vue components. Hope it helps!

Update:

A lot of settings have been updated in new releases of vue. So the above changes may not seem trvial in latest vue projects. So I'll brief how everything is tied together-

Short version:

Find build/utils.js which would contain a method (most probably named cssLoaders() ). This method would return an object like this :

return {
   ...
    sass: generateLoaders('sass', { indentedSyntax: true }),
    scss: generateLoaders('sass'),
   ...
  }

You simply need to change the scss/sass specific line to something like this:

 return {
   ...
    sass: generateLoaders('sass', { indentedSyntax: true }),
    scss: generateLoaders(['css', 'sass?data=@import "~assets/styles/app";']),
   ...
  }

Long Version:

webpack.base.conf.js contains vue-loader in it, it would look something like this :

    ...    
    {
            test: /\.vue$/,
            loader: 'vue-loader',
            options: vueLoaderConfig
        },
    ...

The vueLoaderConfig variable is imported from the vue-loader.conf.js file, which is equal to this object:

    {
      loaders: utils.cssLoaders( Obj ),  // actual settings coming from cssLoader method of build/utils.js
      transformToRequire: {
       //some key value pairs would be here
      }
    }

in build/utils.js file we find the cssLoaders() method which returns: ....

     return {
        css: generateLoaders(),
        postcss: generateLoaders(),
        less: generateLoaders('less'),
        sass: generateLoaders('sass', { indentedSyntax: true }),
        scss: generateLoaders('sass'),
        stylus: generateLoaders('stylus'),
        styl: generateLoaders('stylus')
      }

You simply need to update the above code with updated scss configuration like this:

       ...
        {
           ...
            scss: generateLoaders(['css', 'sass?data=@import"~assets/scss/main";']),
           ...
         }
        ...

Thus, the variables/mixins written in src/assets/scss/main.scss file will be available across all your components.

Shenashenan answered 2/9, 2017 at 16:33 Comment(0)
F
10

I reckon you're using webpack? You can require the settings.scss file in your app.js file something like this

require("!style!css!sass!./file.scss");

hence when it's compiled. All your components will get it. You won't have to require it on each of them.

Fillister answered 28/8, 2016 at 7:20 Comment(4)
Not sure about this one, since Vueify automatically scopes all styles to apply only to the particular componentTrilingual
If it's included in your main, it will be applied to all.Fillister
Has anyone tried doing this with Vue2? Using the basic vue-cli webpack starter and I've added this require line to both the App.vue and main.js file and haven't had any success.Sclerous
Using vue2/webpack2, while the scss file can be included this way, the variables inside do not seem to be included in any component's <style> section.Cuttie
Z
9

The official docs have been updated since I asked this question: https://vue-loader.vuejs.org/en/configurations/pre-processors.html

For anyone else viewing this in 2017 and beyond, check out the instructions under 'loading a global settings file'.

Zoan answered 16/10, 2017 at 20:39 Comment(3)
Does this also allow use of global mixins?Bohr
That link no longer talks about "loading a global settings file" -- still looking for a simple way to load global css in vue 2.x.Antitank
@Antitank it's in the official docs, there's a huge thread on github about it too with many examplesZoan
E
7

If you use the Vue webpack template, you can fix it with one line of code in build/utils.js: scss: generateLoaders(['css', 'sass?data=@import "~assets/styles/app";'])

Then, in src/assets/styles/app, you add all the @imports and voilà!

Euphrosyne answered 15/1, 2017 at 11:46 Comment(0)
D
6

For users using Vue CLI, read https://cli.vuejs.org/guide/css.html#css-modules. Example:

// vue.config.js
const fs = require('fs')

module.exports = {
  css: {
    loaderOptions: {
      // pass options to sass-loader
      sass: {
        // @/ is an alias to src/
        // so this assumes you have a file named `src/variables.scss`
        data: `@import "@/variables.scss";`
      }
    }
  }
}

This fixed it for me perfectly.

Digitalin answered 9/6, 2018 at 8:6 Comment(0)
M
4

I don't believe you can globally import a file. I probably wouldn't do this anyway, it's not explicit enough. If someone wants to move that component into another project they would have no idea it relies on that file.

You can, however, make the path management a lot easier. You can add this to your webpack config file...

sassLoader: {
  includePaths: [
    path.resolve(__dirname, './sass')
  ]
},

Then you can include files from your projects root /sass directory freely without worrying about the paths.

Myrna answered 27/8, 2016 at 13:48 Comment(0)
T
3

If you store all your components in the same directory, your path to your settings.scss will always stay the same.

This is the desired functionality of webpack. The principle is to have as little globals as possible and only include what you need, keeping your project lean, efficient, and easy to reason about.

Perhaps you should restructure your components/styling such that you don't have so many custom styles within each Vue component (build your own bootstrap?), therefore you won't have to include a certain stylesheet inside every Vue component.

This doesn't really answer your question but it might guide you towards aligning with the principles behind the tools you've chosen to work with.

Best of luck!

Typology answered 14/8, 2016 at 12:7 Comment(0)
T
1

Been there - unfortunately there is not a way to do this without importing the file in each component. To get around this, you could try creating helper classes with color: $some-variable and background-color: $some-variable which may cover some of your use cases.

If you do import a file in each one, make sure it only contains variables. You don't want to include style rules multiple times.

Otherwise, I would create separate .scss files for each component. You can still use .vue templates for html and js, but keep your styles separate. This is probably the most efficient way to do it.

Trilingual answered 27/8, 2016 at 1:17 Comment(0)
W
0

My solution is set the settings.scss file's folder a alias in webpack,

maybe settings.scss is not global need, maybe you are also need a like setting2.scss file, but settings.scss is conflict with setting2.scss, you can only choose to introduce a file in this case.

webpack config like this:

resolve: {
  alias: {
    '~src': path.resolve(__dirname, '../src'),
    '~styles': path.resolve(__dirname, '../src/styles'),
}

so, you can import settings.scss in your component

<style lang="scss">
   @import "~styles/settings.scss";
</style>
Widener answered 18/2, 2017 at 17:30 Comment(1)
This is basically what I use, but I take it a step further. I'll have one global component that every component sits inside and that takes global site styles, and then every other component will import any SCSS that doesn't output styles directly, such as mixins. This avoids webpack spitting the same styles out multiple times.Jeanejeanelle

© 2022 - 2024 — McMap. All rights reserved.