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

时间:2018-12-19 09:04:07

标签: reactjs sass rollup rollupjs

我的反应项目很少,它们共享的部分也很少。 因此,我想创建一个包含它们共享的组件的库。

例如,我有一个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时,它仍然是蓝色的。

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

1 个答案:

答案 0 :(得分:1)

只需将!default变量导入组件中的变量之前的特定项目中即可。

这是SASS文档的描述:

  

可变默认值:!default   如果尚未分配变量,则可以通过将!default标志添加到值的末尾来分配它们。这意味着,如果变量已被分配,则不会被重新分配,但是如果它还没有值,它将被赋予一个值。

它将转换为逻辑,然后如果项目中已经定义了默认变量值,则下一个默认值将不会重新定义它。 仅第一个!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;
}