如何写一个允许scss变量被覆盖的React组件库

How to write A React component library that allow scss variables to be overwriten

我有几个 React 项目,它们共享的组件很少。 所以我想创建一个包含它们共享组件的库。

例如,我有一个 ActionButton 组件,如下所示:

import React from 'react';
import PropTypes from 'prop-types';
import './ActionButton.scss';

const ActionButton = ({ children }) => (
    <button className="action-button"> {children}</button>
 )

export default ActionButton;

这是 scss 文件:

@import "../../styles/variables";

.action-button {
    background-color: $primary; // this is defined in the variables scss file.
}

并在 variable.scss

$primary: blue !default;

现在我希望能够使用 ActionButton 创建一个库,并能够更改 $primary 的值。

我正在使用 rollup 使用此配置构建库:

import babel from 'rollup-plugin-babel'
import commonjs from 'rollup-plugin-commonjs'
import external from 'rollup-plugin-peer-deps-external'
import postcss from 'rollup-plugin-postcss'
import sass from 'rollup-plugin-sass';
import scssVariable from 'rollup-plugin-sass-variables'
import resolve from 'rollup-plugin-node-resolve'
import url from 'rollup-plugin-url'
import svgr from '@svgr/rollup'
import pkg from './package.json'

export default {
    input: 'src/index.js',
    treeshake: false,
    output: [
    {
       file: pkg.main,
       format: 'cjs',
       sourcemap: true
    },
    {
      file: pkg.module,
      format: 'es',
      sourcemap: true
    }
  ],
   plugins: [
     external(),
     postcss({
       modules: false,
       extract: true
     }),
     url(),
     svgr(),
     babel({
        exclude: 'node_modules/**',
        plugins: [ 'external-helpers' ]
     }),
     resolve({
       extensions: ['.js', '.jsx'],
     }),
     commonjs(),
     scssVariable(),
   ]
}

现在在使用这个库的项目中,我尝试导入 variables.scss 并覆盖变量,但它不起作用:

// this is in the package that uses this library
@import '<PackageName>/src/styles/variables.scss;
$primary: red;

然后当我画 ActionButton 它仍然是蓝色的。

我需要在我的图书馆中做什么才能允许这种功能?

只需在组件变量之前将 !default 变量导入您的特定项目。

这是 SASS 文档中的描述:

Variable Defaults: !default You can assign to variables if they aren't already assigned by adding the !default flag to the end of the value. This means that if the variable has already been assigned to, it won't be re-assigned, but if it doesn't have a value yet, it will be given one.

它转换为逻辑,那么如果默认变量值已经在项目中定义,则不会被下一个默认值重新定义。 仅第一个 !default 变量值适用。

示例:

$primary: blueviolet !default;
$primary: greenyellow !default;

.element {
  color: $primary; // will resolve to 'blueviolet'
}

查看 stackblitz:https://stackblitz.com/edit/react-sfbwtj?file=style.scss

更新: 要将它与您当前的配置一起使用,请直接从您的库中使用 scss 文件导入样式:

// this is in the package that uses this library
@import './your-redefined-variables.scss';
@import '<PackageName>/src/styles/variables.scss';
@import '<PackageName>/src/styles/library-styles.scss';

.element {
  color: $primary;
}