Vue-cli: CLI Beta-15: vue.config.js merge with global scss vars no longer working

Created on 7 Jun 2018  路  14Comments  路  Source: vuejs/vue-cli

Version

3.0.0-beta.15

Reproduction link

https://github.com/adam-t-b/CLI3-Sass-Loader-Repro/tree/master/sass-test

Steps to reproduce

1) pull down provided test repo
2) npm install
3) npm run serve

What is expected?

The variable used on line 23 of App.vue should be imported from the bootstrap vars.

What is actually happening?

error in ./src/App.vue?vue&type=style&index=0&lang=scss

Module build failed:
undefined
^
Undefined variable: "$gray-400".
in C:\Users\Adam\Documents\CLI3-Sass-Loader-Repro\sass-test\src\App.vue (line 23, column 12)


I've setup the vue.config.js to import the global vars from the bootstrap node_modules location ( using ~ per sass-loader docs) See the config. Also, I've pre-run the vue inspect > webpackConfigOutput.json. It correctly shows the sass-loader data option on lines 544-551.

In 3.0.0-beta.11 My vue.config.js worked correctly, but threw errors only on my Jenkins server. See: https://forum.vuejs.org/t/modulebuilderror-undefined-variable-when-attempting-to-build-app-on-jenkins-server/35562
I was never able to figure out why it only failed when I ran on a clean CI build.

One of my paths to test things was to upgrade to 3.0.0-beta.15. Now, I can no longer pull in global vars even when I run locally. Without this, i'm forced to put the import statement at the top of every single .vue file.. which is not great for maintenance, and also is contrary to vue documentation on how to setup global vars.

Most helpful comment

There is a top level option called css in vue.config.js - its not via chainWebpack. check the docs for more details.

All 14 comments

you do not need to do the sass loader import in vue.config, try reinstalling it just sass and remove this vue.config, it already comes standard in the core.

example: component import

<style lang="scss">
  @import "../../assets/sass/_bulma-connector";
  body.login,
  body.register {
    background-color: $primary;
    #app {
      padding: 0;
    }
  }
</style>

I did not even have to do a config

You are correct that sass-loader is included by default. I use vue.config.js to append the data option to the already existing config, per the vue cli 3 recommendations.

Your example forces me to add the @import statement in every single component or .vue file in order to get the vars. That is the maintenance issue I don't want to deal with. This is the reason for the data option in the sass-loader. Adding the @import statement on a few files is easy enough, but we're hoping to use Vue across our entire organization which could easily mean several dozen components.

Use vue.config.js -> css.loaderOptions.sass instead of manually tapping sass-loader.

I'm not positive I follow. Are you saying I should tap config.module.rule('css').oneOf('normal').use('css-loader') instead and add sass data options there? Sorry if that's a dumb question. I'm still figuring out webpack, so abstracting access to it in vue.config.js is difficult. If there's an example you could point me to that would extremely helpful.

There is a top level option called css in vue.config.js - its not via chainWebpack. check the docs for more details.

This is not working for me. Is this still working for others?

@jdkahn
this work fine for me

module.exports = {
  lintOnSave: true,
  css: {
    sourceMap: true,
    loaderOptions: {
      sass: {
        data: `
          @import "~bootstrap/scss/_variables";
        `
      }
    }
  },
  productionSourceMap: false
};

@yyx990803, as I understand from docs adding "data",` is a bad idea. I have a pretty big project and a lot of component use variables, so import variables.scss in tons of files is annoying. If I use loaderOptions-> sass -> data things get better, but variables.scss content adds in every vue component even if it's not used (no used variables in some component).
A want to ask: is there a better way(best practice) except using "loaderOptions-> sass -> data" (witch touch every file) or adding import in a lot of component?

[...] import variables.scss in tons of files is annoying.
If I use loaderOptions-> sass -> data things get better, but variables.scss content adds in every vue component even if it's not used (no used variables in some component).
[...] is there a better way(

Well, since webpack can't just magically "know" your thoughts about which files you want this data to be present in, those are your two options: import it manually where you want it or import it automatically everyhwere.

I usually go the manual route and make my life a little easier by using a webpack alias to shrink my import to something like @import(~@vars). That's few enough letters to not annoy me.

@LinusBorg, thanks for advise. I use alias for components and its nice feature so using special aliases for importing scss files must be a good experience :+1:

Thanks @andreydos. This one worked for me too :

   lintOnSave: true,
    css: {
        sourceMap: true,
        loaderOptions: {
            sass: {
                data: `
                  @import "src/scss/_variables";
                `
            }
        }
    },
  productionSourceMap: false

Sass can, but less is not

image

Variable @primary is undefined
@yyx990803

Yeah, less-loader simply doesnt have this option.

css: {
  loaderOptions: {
    less: {
      globalVars: {
        primary: '#fff'
      }
    }
  },
}

it's work
http://lesscss.org/usage/#less-options-strict-units
@weoil

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yyx990803 picture yyx990803  路  34Comments

yyx990803 picture yyx990803  路  80Comments

AegirLeet picture AegirLeet  路  38Comments

mayefeng picture mayefeng  路  44Comments

dimavolo picture dimavolo  路  75Comments