vue.jssassvuetify.jsvue-clivue-cli-5

Vue CLI 5 with Vuetify SCSS variables and CSS imports


I work for an organization that try to migrate a project from Vue CLI 4 to Vue CLI 5. The project uses Vuetify and we have SCSS files that are used in the styles/variables.scss file (required by Vuetify to customize style) and also used in Vue components files via @import (SCSS variables sometimes need to be in the <script> section).
Here some example that show how SCSS variables are used through the app:

// styles/variables.scss

@import "colors.scss";
$some-vuetify-sass-variable: $color // from (colors.scss)
// plugins/vuetify.js

import { primaryColor } from "@/style/colors.scss";

Vue.use(Vuetify);

const options = {
  theme: {
    dark: false,
    themes: {
      light: {
        primary: primaryColor,
        // ...
      },
    },
  },
};

export default new Vuetify(options);
// Component.vue

<template>
  <v-chip
    :color="clearPrimaryColor"
    text-color="primary"
  />
</template>

<script>
import { clearPrimaryColor } from "@/style/colors.scss";
export default {
  name: "Component",
  created() {
    this.clearPrimaryColor = clearPrimaryColor;
  }
}
</script>

<style lang="scss">
.some-class {
  background-color: $clearPrimaryColor 
}
</style>

During the Vue CLI migration, we also tried to upgrade some Vuetify dependencies (sass and vuetify-loader). Upgrading sass from 8 to 10 version triggers a compile sass error.

With this reproduction branch: https://github.com/KevinFabre/vue-cli-5-vuetify-scss-variables-in-js (sass 8.0.0), the project does compile. And for this one: https://github.com/KevinFabre/vue-cli-5-vuetify-scss-variables-in -js/tree/error/sass-error (sass 10.0.0), it does not compile:

ERROR  Failed to compile with 2 errors                                                                                                                                                                

 error  in ./src/styles/app.module.scss

Syntax Error: SassError: This file is already being loaded.

  ╷
2 │ @import "app.module.scss";
  │         ^^^^^^^^^^^^^^^^^
  ╵
  src/styles/variables.scss 2:9   @import
  src/styles/app.module.scss 1:9  root stylesheet

Is there extra Vue CLI 5 configuration to allow CSS import in JS while using Vuetify sass override ?

We've submitted issues to vuetify-loader and Vue CLI but didn't receive any reply for now:

{
    "devDependencies": {
    "@babel/preset-env": "^7.11.0",
    "@cypress/webpack-preprocessor": "^5.4.1",
    "@mdi/font": "^6.5.95",
    "@vue/cli-plugin-babel": "^4.4.5",
    "@vue/cli-plugin-e2e-cypress": "^4.4.5",
    "@vue/cli-plugin-eslint": "^4.4.5",
    "@vue/cli-service": "^4.4.5",
    "@vue/eslint-config-prettier": "^6.0.0",
    "babel-eslint": "^10.0.1",
    "core-js": "^3.6.5",
    "eslint": "^7.3.1",
    "eslint-plugin-mocha": "^9.0.0",
    "eslint-plugin-prettier": "^3.1.0",
    "eslint-plugin-unused-imports": "^1.1.5",
    "eslint-plugin-vue": "^7.0.0",
    "eslint-plugin-vuetify": "^1.1.0",
    "lint-staged": "^10.2.11",
    "sass": "~1.32.0",
    "sass-loader": "^10.0.0",
    "style-resources-loader": "^1.2.1",
    "stylus": "^0.54.5",
    "stylus-loader": "^3.0.1",
    "vue-cli-plugin-style-resources-loader": "^0.1.3",
    "vue-cli-plugin-vuetify": "^2.0.6",
    "vue-svg-loader": "^0.16.0",
    "vue-template-compiler": "^2.6.12",
    "vuetify-loader": "^1.7.3",
    }
}

Thank you for your time.


Solution

  • Components must avoid importing files that are already imported in the global variables stylesheet (src/styles/variables.scss). This was the case with app.module.scss (loaded in src/styles/variables.scss and in src/components/HelloWorld.vue), causing the error about the file being loaded twice.

    One solution is to move the color definitions from app.module.scss into its own file, and import that in variables.scss instead of app.module.scss. Then, components could import app.mdoule.scss without running into the original problem.

    /* src/styles/app.module.scss *
    :export {
      whitecolor: $white-color;
      darkcolor: $dark-color;
      lightcolor: $light-color;
      mediumcolor: $medium-color;
      alertcolor: $alert-color;
      lightblackcolor: $light-black-color;
      blackcolor: $black-color;
    }
    
    /* src/styles/colors.scss */
    $white-color: #fcf5ed;
    $dark-color: #402f2b;
    $light-color: #e6d5c3;
    $medium-color: #977978;
    $alert-color: #cb492a;
    $light-black-color: #706e72;
    $black-color: #414042;
    
    /* src/styles/variables.scss */
    @import "~vuetify/src/styles/settings/_colors.scss";
    @import "colors.scss";
    
    $material-light: (
      background: map-get($grey, "lighten-1")
    );
    

    demo