webpack 在scss中使用JavaScript变量

uttx8gqw  于 2023-06-23  发布在  Webpack
关注(0)|答案(1)|浏览(190)

这将是一段时间,我试图找到一个解决方案,使用javascript变量有scss值。
让我解释一下我的问题。我使用VueJs/Vuetify,我有两个入口点为我的主题。

    • 第一个是这样的json文件:**
module.exports = {
  primary: { base: '#4d7cff', dark: '#2756d8', light: '#96b0fb' },
  secondary: { base: '#00bda5', dark: '#209284', light: '#cef1ec' },
  content: { base: '#37467a', dark: '#242c47', light: '#c3cbe6' },
  danger: { base: '#e43858', dark: '#d22545', light: '#E36d83' },
  success: { base: '#00c28d', dark: '#199c79', light: '#0bebae' },
  accent: '#f5f8fa',
  gradient: 'linear-gradient(45deg, #00bda5, #4d7cff)'
}

此文件是必需的,并使用vuetify两个创建自定义颜色值和完美的作品。

    • 第二个是简单的scss文件:**
// Theme colors
$color-primary-base: #4d7cff;
$color-primary-dark: #2756d8;
$color-primary-light: #96b0fb;

$color-secondary-base: #4d7cff;
$color-secondary-dark: #209284;
$color-secondary-light: #cef1ec;

$color-content-base: #37467a;
$color-content-dark: #242c47;
$color-content-light: #c3cbe6;

$color-danger-base: #e43858;
$color-danger-dark: #d22545;
$color-danger-light: #ff8097;

$color-success-base: #00c28d;
$color-success-dark: #199c79;
$color-success-light: #14e1a9;

$color-accent: #f5f8fa;

我的目标是将json文件与scss变量连接起来,从而为整个应用程序提供一个入口点。

    • 为什么要这样做?* * Vuetify提供了一个scss变量重载系统来修改组件的样式。

这个想法是从javascript文件控制这个重载
除此之外,由于vuetify的限制,在某些情况下,我必须在响应上下文中控制颜色(例如桌面上的白色标题和移动设备上的蓝色标题),因此必须使用scss变量。
我在媒体上找到了this article,乍一看似乎回答了我的问题。
但当我尝试测试它时,我得到了以下错误:

in ./src/assets/styles/vuetify.scss

Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
ValidationError: Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
 - options has an unknown property 'options'. These properties are valid:
   object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }
    at validate (C:\Users\33770\Documents\Calimed\novalys-front\node_modules\schema-utils\dist\validate.js:96:11)
    at Object.loader (C:\Users\33770\Documents\Calimed\novalys-front\node_modules\sass-loader\dist\index.js:36:28)
    • Vuetify. scss**
@import './novalys/map.scss';
@import '~vuetify/src/styles/main.sass';
    • vue.config.js**
const sass = require('node-sass')
const sassUtils = require('node-sass-utils')(sass)
const sassVars = require(__dirname + '/src/theme/index.js')

module.exports = {
  css: {
    loaderOptions: {
      scss: {
        prependData: `@import "@/assets/styles/novalys/map.scss";`,
        options: {
          functions: {
            'get($keys)': function(keys) {
              keys = keys.getValue().split('.')
              let result = sassVars
              let i
              for (i = 0; i < keys.length; i++) {
                result = result[keys[i]]
              }
              result = sassUtils.castToSass(result)
              return result
            }
          }
        }
      }
    }
  },
  transpileDependencies: ['vuetify']
}

有人能帮我找到一个可能的解决方案吗?
我听说过通过导出一个像那样的SCSS变量的逆解

:export {
    some-variable: 'some-value';
}

但我的想法是让入口点在json中而不是scss文件中。
感谢您的评分

qyswt5oh

qyswt5oh1#

根据加载程序版本的不同,相关选项名称也会有所不同(doc)

  • 最新的sass-loader使用additionalData
  • sass-loader版本8使用prependData
  • 版本8以下的sass-loader使用data
{
  loader: 'sass-loader',
  options: {
    // you can also read from a file, e.g. `variables.scss`
    // use `prependData` here if sass-loader version = 8, or
    // `data` if sass-loader version < 8
    additionalData: `$color: red;`
  }
}

你可以把它和js-to-scssnpm)结合起来,把你的json文件转换成一个包含scss语法中所有变量的字符串:

const const flattenObjSass = require("js-to-scss");
const colors = require("./colors.json");

// ...

{
  loader: 'sass-loader',
  options: {
    additionalData: flattenObjSass(colors, '$color-')
  }
}

所以

{
  primary: { base: '#4d7cff', dark: '#2756d8', light: '#96b0fb' },
  secondary: { base: '#00bda5', dark: '#209284', light: '#cef1ec' },
}

将会变成

$color-primary-base: #4d7cff;
$color-primary-dark: #2756d8;
$color-primary-light: #96b0fb;
$color-secondary-base: #00bda5;
$color-secondary-dark: #209284;
$color-secondary-light: #cef1ec;

相关问题