You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rollup构建React组件库如何保留SCSS变量支持自定义覆盖

问题背景

你正在开发基于SCSS编写原子组件样式的轻量React组件库,项目结构特征如下:

  • 每个组件配有独立样式表
  • 所有组件样式统一引入全局common.scss,文件内定义了颜色、渐变、边框等通用SCSS变量,变量已添加!default标识支持默认值覆盖
  • 当前Rollup构建逻辑会直接预处理SCSS,将变量替换为静态属性值,最终生成的CSS直接绑定到对应组件,导致使用方无法自定义变量
  • 预期目标:组件库自带变量默认值,使用方可创建自有global.scss文件,引入组件库导出的common.scss后重写需要自定义的变量值

当前现有配置

rollup.config.js

import peerDepsExternal from "rollup-plugin-peer-deps-external";
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "rollup-plugin-typescript2";
import postcss from "rollup-plugin-postcss";

const packageJson = require("./package.json");

export default {
  input: "src/index.ts",
  output: [
    {
      file: packageJson.main,
      format: "cjs",
      sourcemap: true,
    },
    {
      file: packageJson.module,
      format: "esm",
      sourcemap: true,
    }
  ],
  plugins: [
    peerDepsExternal(),
    resolve(),
    commonjs(),
    typescript({ useTsconfigDeclarationDir: true }),
    postcss({
        extensions: ['.scss']
    })
  ]
};

common.scss 变量片段

$primary-text: #3C3C3C !default;
$secondary-text: #5C5C5C !default;
$tertiary-text: #7C7C7C !default;

解决方案

一、Rollup配置调整

核心逻辑是不在构建阶段把SCSS完全编译为不可变的静态CSS,同时将源码中的SCSS变量文件单独导出给使用方,分三步调整:

  1. 修改postcss插件配置,拆分样式输出,默认提供编译完成的静态CSS供无定制需求的用户直接使用
  2. 单独导出common.scss作为组件库公开入口,方便有定制需求的用户引入修改变量
  3. 调整package.json导出配置,明确SCSS文件的引入路径

具体修改步骤如下:
首先安装需要的依赖:

npm i -D rollup-plugin-copy

修改后的rollup.config.js配置:

import peerDepsExternal from "rollup-plugin-peer-deps-external";
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "rollup-plugin-typescript2";
import postcss from "rollup-plugin-postcss";
import copy from "rollup-plugin-copy";

const packageJson = require("./package.json");

export default {
  input: "src/index.ts",
  output: [
    {
      file: packageJson.main,
      format: "cjs",
      sourcemap: true,
    },
    {
      file: packageJson.module,
      format: "esm",
      sourcemap: true,
    }
  ],
  plugins: [
    peerDepsExternal(),
    resolve(),
    commonjs(),
    typescript({ useTsconfigDeclarationDir: true }),
    postcss({
      extensions: ['.scss'],
      extract: 'style/index.css', // 将所有组件样式抽离为独立CSS文件,默认使用变量初始值
      inject: false, // 关闭自动注入样式,避免自定义场景下样式重复引入
      modules: false, // 未使用CSS Module则保持false,使用的话按需配置规则
      use: [
        ['sass', {
          silenceDeprecations: ['legacy-js-api']
        }]
      ]
    }),
    // 将源码中的common.scss复制到构建产物目录,作为公开SCSS入口
    copy({
      targets: [
        { src: 'src/styles/common.scss', dest: 'build/style' } // 替换为你项目实际的common.scss存放路径和输出目录
      ]
    })
  ]
};

最后调整package.json的导出配置,增加SCSS入口映射:

{
  "main": "build/index.cjs.js",
  "module": "build/index.esm.js",
  "exports": {
    ".": {
      "import": "./build/index.esm.js",
      "require": "./build/index.cjs.js"
    },
    "./style/common.scss": "./build/style/common.scss",
    "./style/index.css": "./build/style/index.css"
  }
}

二、使用方自定义变量方式

配置完成后,使用方可根据需求选择两种使用模式:

  • 无自定义需求:直接引入组件库JS和编译好的静态CSS即可,和普通组件库用法一致
  • 需要自定义变量:在项目全局SCSS文件中先声明自定义变量值,再引入组件库的common.scss和样式文件,示例:
// 项目内的global.scss
// 先声明自定义变量,会自动覆盖common.scss中带!default标识的默认值
$primary-text: #1D2129;
$secondary-text: #4E5969;
$tertiary-text: #86909C;

// 再引入组件库的变量文件和样式
@import 'your-component-lib/style/common.scss';
@import 'your-component-lib/style/index.css';

注意:如果使用方需要通过SCSS编译全量覆盖变量,不要在组件库的JS入口中自动注入CSS,避免样式重复打包,可以在组件库文档中明确说明两种样式引入方式的差异。


关于Rollup是否适合该类组件库构建场景

Rollup非常适合这类React组件库的构建场景,相比其他构建工具它的优势很明确:

  • 构建产物干净冗余少,Tree Shaking支持成熟,非常适合分发独立组件库、工具包
  • 插件生态完善,TS处理、样式编译、外部依赖隔离等常见需求都有稳定插件覆盖
  • 原生支持同时输出CJS、ESM多种模块格式产物,适配不同业务项目的模块规范
  • 配置灵活度高,可以按需调整样式、静态资源的处理规则,完全满足暴露SCSS变量、自定义主题这类定制需求

后续如果要扩展按需引入、组件自动导入等能力,Rollup也有对应插件可以快速实现,不需要切换构建工具。


内容的提问来源于stack exchange,提问作者Nikhil Jagtap

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 12:18:15