带有 Vuetify SCSS 变量和 CSS 导入的 Vue CLI 5

Vue CLI 5 with Vuetify SCSS variables and CSS imports

我在一家尝试将项目从 Vue CLI 4 迁移到 Vue CLI 5 的组织工作。 该项目使用 Vuetify,我们有 SCSS 文件,这些文件在 styles/variables.scss 文件中使用(Vuetify 需要自定义样式)并且还通过 @import 在 Vue 组件文件中使用(SCSS 变量有时需要在 <script> 部分)。
这里有一些示例显示了如何通过应用程序使用 SCSS 变量:

// 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>

在 Vue CLI 迁移过程中,我们还尝试升级了一些 Vuetify 依赖项(sassvuetify-loader)。将 sass 从 8 版本升级到 10 版本会触发编译 sass 错误。

使用此复制分支:https://github.com/KevinFabre/vue-cli-5-vuetify-scss-variables-in-js (sass 8.0.0),该项目可以编译。 对于这个:https://github.com/KevinFabre/vue-cli-5-vuetify-scss-variables-in -js/tree/error/sass-error (sass 10.0.0),它不编译:

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

是否有额外的 Vue CLI 5 配置允许 CSS 在使用 Vuetify sass 覆盖时在 JS 中导入?

我们已经向 vuetify-loader 和 Vue CLI 提交了问题,但暂时没有收到任何回复:

{
    "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",
    }
}

感谢您的宝贵时间。

这基本上与在您的 vuejs 应用程序中声明的导入文件的重复解析有关。

有两种方法可以解决:

  1. 在出现 Sass 导入错误的地方使用 @use 而不是 @import。比如,@import "app.module.scss"; 变成 @use "app.module.scss";
  2. 另一种选择是将 sass-loader 库降级为“^8.0.2”

让我知道以上解决方案是否适合您,同时如果我找到任何新的解决方案,我会更新我的答案。

组件必须避免导入已在全局变量样式表 (src/styles/variables.scss) 中导入的文件。 app.module.scss 就是这种情况(在 src/styles/variables.scsssrc/components/HelloWorld.vue 中加载),导致有关文件被加载两次的错误。

一个解决方案是将颜色定义从 app.module.scss 移动到它自己的文件中,并将其导入 variables.scss 而不是 app.module.scss。然后,组件可以将 app.mdoule.scss 而不是 运行 导入到原始问题中。

/* 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