目的
- 为了提高开发者效率,提高组件库的可定制化,组件库需要提供换肤功能以及多种类组件中的样式定制功能,允许用户将应用切换不同主题风格的皮肤,也允许开发者对指定组件进行样式改造。
- 为了减少代码的体积,组件库需要提供按需引入的功能,组件只用在被手动引入的时候,才会被打包进项目当中,无论是html、js,还是css,都需要做到按需引入。
样式选择
sass/less | css in js | |
---|---|---|
完全支持样式覆盖 | ✅ | ❗(需要使用className支持) |
支持rem布局 | ✅ | ❗(大部分库支持) |
可读性 | 强 | 强 |
上手成本 | 低 | 高 |
是否支持SSR | 天然支持 | 需要额外支持 |
是否支持流式渲染 | 天然支持 | 需要额外支持 |
支持postcss | ✅ | ❗(有自己的plugin生态) |
样式按需引入
使用组件库时, 需要加载组件库的全部样式, 但是我们大部分时候不需要使用到组件库所有的组件, 更不需要载入所有组件的样式。所以组件库需要提供按需引入。
比如我们现在需要使用Button
组件,我们会写如下代码:
import {Button} from "@bufang/dogc"
因为此时没用引入全部样式文件,按钮样式不会生效,需要我们手动引入Button
样式:
import "@bufang/dogc/lib/button/style"
到这里的要解决如下两个问题。
要做到组件的样式单独引入,在打包的时候就需要把组件的样式单独打包,如何实现单独打包?
- 安装
npm install rollup-plugin-styles
,可以与preserveModules
做适配,即输出按照组件维度拆分的 css 文件。 - 配置rollup.config.js
output = {
dir: "cjs",
format: "cjs",
preserveModules: true,
preserveModulesRoot: "components",
exports: "named",
assetFileNames: ({ name }) => {
const { ext, dir, base } = path.parse(name);
if (ext !== ".css") return "[name].[ext]";
// 规范 style 的输出格式
return path.join(dir, "style", base);
},
};
plugins:[
styles({
mode: "extract", // 使得 css 是抽离的,而不是打包进 js 的
less: { javascriptEnabled: true },
extensions: [".less"],
minimize: false,
use: ["less"],
url: {
inline: true,
},
sourceMap: true, // 必须开启,否则 rollup-plugin-styles 会有 bug
onExtract(data) {
const { name } = data;
const { base } = path.parse(name);
if (base !== "index.css") return false;
return true;
},
}),
]
每引入一个组件都需要手动引入样式,是不是比较繁琐,如何自动引入组件的样式?
npm install babel-plugin-import --save-dev
- 配置babel
module.exports = {
plugins: [
[
"import",
{
libraryName: "@bufang/dogc",
libraryDirectory: "es", // default: lib
camel2DashComponentName: true,
style: name => {
// 注意这里的name为组件所在的路径,按需加载样式配置提取对应组件名称的css即可
return `${name}/style/index.less`;
},
},
],
]
};
主题配置
- 方案一:css3 Variables 定义一个全局颜色变量,改变这个变量的值页面内所有引用这个变量的元素都会进行改变。
@import "./color/index.less";
body,
body[theme-mode="dark"] .dogc-always-light {
--dogc-color-white: rgba(
var(--dogc-white),
1
); // 浅色模式下深色背景内容Inverse
--dogc-color-black: rgba(
var(--dogc-black),
1
); // 深色模式下浅色背景内容Inverse
--dogc-color-primary: rgba(
var(--dogc-blue-5),
1
); // 主要颜色。仅在需要非常强调的情况下使用。
}
如果要修改主题色时: document.body.style.setProperty('--dogc-color-primary', 'blue');
即可,非常方便。
- 方案二:less modifyVars
modifyVars
方法是是基于 less 在浏览器中的编译来实现。所以在引入less文件的时候需要通过link方式引入,然后基于less.js中的方法来进行修改变量。操作起来比较麻烦,如果有兴趣可以自己去研究一下。
所以,最终选择了css variables
方案。