antd中的scripts 中的start 定义的脚本如下
"start": "rimraf _site && mkdir _site && node ./scripts/generateColorLess.js && cross-env NODE_ENV=development bisheng start -c ./site/bisheng.config.js",
可以按照他的执行顺序挨个来看
- rimraf _site
- mkdir _site
- node ./scripts/generateColorLess.js
- cross-env NODE_ENV=development bisheng start -c ./site/bisheng.config.js"
前两个没什么可说的清空然后创建_site目录
node ./scripts/generateColorLess.js
执行了scripts/generateColorLess.js
这个脚本 代码如下
const path = require('path');
const {
generateTheme } = require('antd-theme-generator');
const options = {
stylesDir: path.join(__dirname, '../site/theme/static'),
antdStylesDir: path.join(__dirname, '../components'),
varFile: path.join(__dirname, '../components/style/themes/default.less'),
mainLessFile: path.join(__dirname, '../site/theme/static/index.less'),
themeVariables: ['@primary-color'],
outputFilePath: path.join(__dirname, '../_site/color.less'),
};
generateTheme(options);
关键的地方就是这个generateTheme 函数啥 其实翻开antd-theme-generator
这个包的介绍可以看到
This script generates color specific styles/less file which you can use to change theme dynamically in browser
他其实是为切换主题色服务的源码如下
const fs = require("fs");
const path = require("path");
const glob = require("glob");
const postcss = require("postcss");
const less = require("less");
// 把多个less 文件合并为一个
const bundle = require("less-bundle-promise");
const hash = require("hash.js");
// 从npm impirt less
const NpmImportPlugin = require('less-plugin-npm-import');
// const colorsOnly = require('postcss-colors-only');
const options = {
withoutGrey: true, // set to true to remove rules that only have grey colors
withoutMonochrome: true, // set to true to remove rules that only have grey, black, or white colors
};
let hashCache = "";
let cssCache = "";
// 生成随机色
function randomColor() {
return '#' + (Math.random() * 0xFFFFFF << 0).toString(16);
}
/*
Recursively get the color code assigned to a variable e.g.
@primary-color: #1890ff;
@link-color: @primary-color;
@link-color -> @primary-color -> #1890ff
Which means
@link-color: #1890ff
*/
function getColor(varName, mappings) {
const color = mappings[varName];
if (color in mappings) {
return getColor(color, mappings);
} else {
return color;
}
}
/*
Read following files and generate color variables and color codes mapping
- Ant design color.less, themes/default.less
- Your own variables.less
It will generate map like this
{
'@primary-color': '#00375B',
'@info-color': '#1890ff',
'@success-color': '#52c41a',
'@error-color': '#f5222d',
'@normal-color': '#d9d9d9',
'@primary-6': '#1890ff',
'@heading-color': '#fa8c16',
'@text-color': '#cccccc',
....
}
*/
function generateColorMap(content) {
return content
.split("\n")
.filter(line => line.startsWith("@") && line.indexOf(":") > -1)
.reduce((prev, next) => {
try {
const matches = next.match(
/(?=\S*['-])([@a-zA-Z0-9'-]+).*:[ ]{1,}(.*);/
);
if (!matches) {
return prev;
}
let [, varName, color] = matches;
if (color && color.startsWith("@")) {
color = getColor(color, prev);
if (!isValidColor(color)) return prev;
prev[varName] = color;
} else if (isValidColor(color)) {
prev[varName] = color;
}
return prev;
} catch (e) {
console.log("e", e);
return prev;
}
}, {
});
}
/*
This plugin will remove all css rules except those are related to colors
e.g.
Input:
.body {
font-family: 'Lato';
background: #cccccc;
color: #000;
padding: 0;
pargin: 0
}
Output:
.body {
background: #cccccc;
color: #000;
}
*/
const reducePlugin = postcss.plugin("reducePlugin", () => {
const cleanRule = rule => {
// 清除掉.main-color .palatte- 开口的css 语句