按需加载
antd 按需引入 css
spug 中使用的是 react-app-rewired,而 myspug 使用的是 react-scripts。
react-app-rewired 是一个对 create-react-app 进行自定义配置的社区解决方案。
react-app-rewired 的引入是作为 antd 按需引入 css 解决方案的一部分。
步骤如下:
安装 react-app-rewired
npm i react-app-rewired && yarn add react-app-rewired
安装 customize-cra
npm i customize-cra && yarn add customize-cra
安装 babel-plugin-import
npm i babel-plugin-import && yarn add babel-plugin-import
修改 package.json,通过 react-app-rewired 来启动、打包和测试
/* package.json */
"scripts": {
- "start": "react-scripts start",
- "build": "react-scripts build",
- "test": "react-scripts test",
+ "start": "react-app-rewired start",
+ "build": "react-app-rewired build",
+ "test": "react-app-rewired test",
}
项目根目录创建一个 config-overrides.js(内容请看链接) 用于修改默认配置 修改 App.js 用于验证 antd 样式按需引入是否生效
import { Button } from 'antd';
export default function App() {
return (
<div className="App">
<Button type="primary">Primary Button</Button>
</div >
);
}
最后启动服务 npm run start,浏览器访问 http://localhost:3000/,看见一个蓝色按钮说明成功。
packages.json
{
"name": "spug_web",
"version": "3.0.0",
"private": true,
"dependencies": {
// icon
"@ant-design/icons": "^4.3.0",
// 图表相关
"@antv/data-set": "^0.11.8",
// Ace 是一个用 JavaScript 编写的代码编辑器。 (不用)
"ace-builds": "^1.4.13",
// ui
"antd": "^4.19.2",
// http
"axios": "^0.21.0",
// 图表
"bizcharts": "^3.5.9",
// 小型功能路由器,通过搜索 `Enroute({` 发现只在 Test.js 中使用,应该是用于测试(不用)
"enroute": "^1.0.1",
// 路由相关
"history": "^4.10.1",
// jquery (不用)
"jquery": "^3.6.0",
"lodash": "^4.17.19",
// 状态
"mobx": "^5.15.6",
"mobx-react": "^6.3.0",
// 日期库
"moment": "^2.24.0",
// 数字
"numeral": "^2.0.6",
"react": "^16.13.1",
// 与 ace Editor 相关(不用)
"react-ace": "^9.5.0",
// react
"react-dom": "^16.13.1",
// 路由
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.3",
// 浏览器中使用终端(不用)
"xterm": "^4.6.0",
"xterm-addon-fit": "^0.5.0"
},
// 本地启动、打包
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
},
// eslint 相关。查找并修复JavaScript代码中的问题。
"eslintConfig": {
"extends": "react-app"
},
// 编译后的源码支持的浏览器。不用动
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
// 用于支持 es6 中装饰器的语法
"@babel/plugin-proposal-decorators": "^7.10.5",
"anywhere": "^1.5.0",
"bx-tooltip": "^0.1.6",
// 新的 react-app-rewired@2.x 版本的关系,你还需要安装 customize-cra
"customize-cra": "^1.0.0",
// http 代理中间件
"http-proxy-middleware": "0.19.2",
"less": "^3.12.2",
"less-loader": "^7.1.0",
"mockjs": "^1.1.0",
// 一个对 create-react-app 进行自定义配置的社区解决方案
"react-app-rewired": "^2.1.6"
}
}
对比我的 packages.json
{
"name": "antd-demo-ts",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^29.4.0",
"@types/node": "^18.14.6",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"antd": "^4.0.0",
"babel-plugin-import": "^1.13.6",
"customize-cra": "^1.0.0",
"react": "^18.2.0",
"react-app-rewired": "^2.2.1",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
解决问题
点击antd.css(@import '~antd/dist/antd.css';)报错,怀疑包下载有问题,最后卸载 antd,再次安装 antd@4即可。
"antd": "^4.19.2",
npm i antd@4.19.2 && npm i and@4.0.0
自定义主题
按照 配置主题 的要求,自定义主题需要用到 less 变量覆盖功能。我们可以引入 customize-cra 中提供的 less 相关的函数 addLessLoader 来帮助加载 less 样式,同时修改 config-overrides.js 文件如下。
- const { override, fixBabelImports } = require('customize-cra');
+ const { override, fixBabelImports, addLessLoader } = require('customize-cra');
module.exports = override(
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
- style: 'css',
+ style: true,
}),
+ addLessLoader({
+ javascriptEnabled: true,
+ modifyVars: { '@primary-color': '#1DA57A' },
+ }),
);
-
这里利用了 less-loader 的 modifyVars 来进行主题配置,变量和其他配置方式可以参考 配置主题 文档。
-
修改后重启 yarn start,如果看到一个绿色的按钮就说明配置成功了。
-
如果提示错误缺少 less-loader
安装: less less-loader
yarn add less less-loader
- 如果还报错 解决办法:将package.json中,"typescript": "~3.7.5"版本,更新ts到"typescript": "^3.8.3"
安装: typescript
yarn add typescript@3.8.3 -S
发现还是不行
什么情况呀?? 但是作为程序员解决问题我们必须要做的那就解决他.
这是什么问题呀?
刚刚我们安装了 less less-loader 造成的问题是这样&& 也许会碰到上面的那个问题
匹配版本less less-loader
现在来匹配一下版本:
npm i less@2.7.3 less-loader@4.1.0 post-loader3.0.0 --save-dev
yarn add less@2.7.3 less-loader@4.1.0 post-loader3.0.0 -D
运行之后发现 咦 不报错了, 但是按需加载的Button 不能全局自定义主题
import logo from './logo.svg';
import { Button } from 'antd'
import './App.css';
import '../src/assets/index.less'
import Home from './views/Home'
function App() {
return (
<div className="app">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
<Home/>
<span className='box'>我是谁!</span>
<Button type="primary" danger>
Primary
</Button>
<Button danger>Default</Button>
<Button type="dashed" danger>
Dashed
</Button>
<Button type="text" danger>
Text
</Button>
<Button type="link" danger>
Link
</Button>
<Button type="dashed">Danger Default</Button>
</div>
);
}
export default App;
好现在发现 不是less的问题, 也和antd的版本无关, 那是啥子问题呢,头大 那就是config-overrides他的问题了,
关于这个 rewired 有空再细说
现在先解决如何实现 antd 自定义主题的问题
config-overrides 改成 craco.config
首先我们把config-overrides 改成 craco.config
然后 使用 @craco/craco
npm i @craco/craco -D
配置 package.json
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test"
},
用于处理less
npm i craco-less -D //less处理插件
按需加载 babel-plugin-import
npm i babel-plugin-import -D
创建 craco.config.js
const CracoLessPlugin = require('craco-less');
module.exports = {
babel: {//支持装饰器
plugins: [
[
"import",
{
"libraryName": "antd",
"libraryDirectory": "es",
"style": true //设置为true即是less 用css写'css'
}
]
]
},
plugins: [
{
plugin: CracoLessPlugin,
options: {
lessLoaderOptions: {
lessOptions: {
modifyVars: {
'@primary-color': 'red', // 全局主色
},
javascriptEnabled: true,
},
}
},
},
],
};
解决
import logo from './logo.svg';
import { Button } from 'antd'
import './App.css';
import '../src/assets/index.less'
import Home from './views/Home'
function App() {
return (
<div className="app">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
<Home/>
<span className='box'>我是谁!</span>
<Button type="primary" danger>
Primary
</Button>
<Button danger>Default</Button>
<Button type="dashed" danger>
Dashed
</Button>
<Button type="text" danger>
Text
</Button>
<Button type="link" danger>
Link
</Button>
<Button type="dashed">Danger Default</Button>
</div>
);
}
export default App;