react antd-theme-generator 换肤
antd 换肤
创建antd-demo项目
# 创建项目
$ npx create-react-app antd-demo
# 启动项目
$ cd antd-demo
$ yarn install
$ npm start
# 安装antd-theme-generator
$ yarn add antd-theme-generator --dev
# antd
$ yarn add antd
# 创建文件
$ touch color.js
$ mkdir src/styles
$ touch src/styles/main.less src/styles/vars.less
color.js
const path = require('path');
const fs = require('fs');
// const {generateTheme, getLessVars} = require('../../index');
// const { generateTheme, getLessVars } = require('../../../antd-theme-webpack-plugin/');
const {generateTheme, getLessVars} = require('antd-theme-generator');
const themeVariables = getLessVars(path.join(__dirname, './src/styles/vars.less'));
const defaultVars = getLessVars('./node_modules/antd/lib/style/themes/default.less');
const darkVars = {
...getLessVars('./node_modules/antd/lib/style/themes/dark.less'),
'@primary-color': defaultVars['@primary-color'],
'@picker-basic-cell-active-with-range-color': 'darken(@primary-color, 20%)'
};
const lightVars = {
...getLessVars('./node_modules/antd/lib/style/themes/compact.less'),
'@primary-color': defaultVars['@primary-color']
};
// fs.writeFileSync('./src/dark.json', JSON.stringify(darkVars));
// fs.writeFileSync('./src/light.json', JSON.stringify(lightVars));
// fs.writeFileSync('./src/theme.json', JSON.stringify(themeVariables));
const options = {
stylesDir: path.join(__dirname, './src'),
antDir: path.join(__dirname, './node_modules/antd'),
varFile: path.join(__dirname, './src/styles/vars.less'),
themeVariables: Array.from(
new Set([...Object.keys(darkVars), ...Object.keys(lightVars), ...Object.keys(themeVariables)])
),
outputFilePath: path.join(__dirname, './public/color.less')
};
generateTheme(options)
.then(less => {
console.log('Theme generated successfully');
})
.catch(error => {
console.log('Error', error);
});
生成 public/color.less
$ node color.js
public/index.html
<body>
<link rel="stylesheet/less" type="text/css" href="%PUBLIC_URL%/color.less" />
<script>
window.less = {
async: true,
env: 'production'
};
</script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/less.js/2.7.2/less.min.js"></script>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
浏览器 console
window.less
{version: Array(3), data: {…}, tree: {…}, Environment: ƒ, AbstractFileManager: ƒ, …}
package.json
"scripts": {
"start": "npm run color && react-scripts start",
"build": "npm run color && react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"color": "node color.js"
}
控制台报错 console
Warning: findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of Wave which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely
src/index.js
ReactDOM.render(<App />, document.getElementById('root'));
// ReactDOM.render(
// <React.StrictMode>
// <App />
// </React.StrictMode>,
// document.getElementById('root')
// );
安装 customize-cra
$ touch config-overrides.js
$ yarn add customize-cra react-app-rewired --dev
config-overrides.js
/**
* @file config
*/
const {override, fixBabelImports, addLessLoader} = require('customize-cra');
// https://github.com/arackaf/customize-cra/blob/HEAD/api.md
module.exports = override(
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
style: true
}),
addLessLoader({
lessOptions: {
javascriptEnabled: true
}
})
);
$ yarn add --dev less less-loader
package.json
"scripts": {
"start": "npm run color && react-app-rewired start",
"build": "npm run color && react-app-rewired build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"color": "node color.js"
},
运行npm start报错
Failed to compile
./src/index.js
Error: Cannot find module 'babel-plugin-import' from '/Users/v_lishaohai/Desktop/study/react/antd-demo'
at Array.map (<anonymous>)
$ yarn add babel-plugin-import --dev
$ yarn add postcss --dev
设置默认的主题色
src/styles/vars.less
@import '~antd/lib/style/themes/default.less';
@primary-color: #f00; // 全局主色
浏览器控制台 console
window.less.modifyVars({'@primary-color': '#00f'});
即可以看到效果
src/App.js
/**
* @file App.js
*/
import {useState, useEffect} from 'react';
import './App.css';
import {Button} from 'antd';
const THEME_RED = '#f00';
const THEME_BLUE = '#1890ff';
export default function App() {
const [theme, setTheme] = useState(THEME_BLUE);
useEffect(() => {
window.less.modifyVars({
'@primary-color': theme
});
// effect
return () => {};
}, [theme]);
return (
<div className="App">
<Button type="primary">当前主题颜色:{theme}</Button>
<hr />
<Button onClick={() => setTheme(THEME_RED)} type="default">
主题红色: {THEME_RED}
</Button>
<Button onClick={() => setTheme(THEME_BLUE)} type="default">
主题蓝色:{THEME_BLUE}
</Button>
</div>
);
}
最终效果
源码地址
项目源码地址:https://github.com/xieerduos/antd-theme-demo