在一个项目中可能需要同时依赖 antd的两个版本,
npm 6.9.0 添加了 package aliases
功能可以用来解决这个问题
antd多个版本共存的好处,渐进式升级,减少技术风险,实现思路
- package.json npm 别名安装antd4,
{"antd4": "npm:antd@^4.24.5"}
- 别名以
npm:
开头 npm install antd5@npm:antd@^5.0.3
- 安装成功后,会显示 antd@5.0.4 (as antd5)
- 别名以
- dva修改 webpackrc.js 配置;umijs 修改config.ts
- 新增lessLoaderOptions,配置less插件,处理antd4内样式内@antd-prefix
- 根组件,ConfigProvider统一修改前缀为antd5
npm alias 自定义安装包别名
https://github.com/jht6/blogs/issues/63
https://github.com/npm/rfcs/blob/main/implemented/0001-package-aliases.md
dva .webpackrc.js配置参考
https://www.jianshu.com/p/c7b3b9c98d04
https://juejin.cn/post/7088140437004746782
package.json
同时安装同一个包的多个版本
antd3x 正常安装,yarn add antd@3.26.19
antd4x 别名安装,yarn add antd4@npm:antd@^4.23.6
antd5x 别名安装,yarn add antd5@npm:antd@^5.0.3yarn add babel-plugin-import --dev
安装成功后,提示 +antd@4.24.5 (as antd4)
{
"dependencies": {
"antd": "^3.26.20",
"antd4": "npm:antd@^4.24.5",
"antd5": "npm:antd@^5.0.3",
},
"devDependencies": {
"babel-plugin-import": "^1.13.5",
}
}
// 使用不同版本的 antd
import{ Button as ButtonV3 } from 'antd'
import{ Button, Space, Segmented, Cascader } from 'antd5'
antd多版本共存问题
- index.css样式冲突
- 默认用 cdn引入 antd/index.css 是 antdx3x版本
- cdn引入 antd4x的 index.css,不要引入 antd3x,css自己维护样式错乱的组件
- antd4的样式需要按需加载
- 优化点,自己维护 antd4x的 index.css,修改 prefixCls=antd4后,单独打包构建,然后cdn引入
- antd 多版本共存的缺点:造成打包后的 index.js 尺寸增大
- antd3x样式,ant-xxx
- antd4x样式,antd4-xxx
ConfigProvider
index.js 入口文件,修改 ConfigProvider
ConfigProvider设置prefixCls,修改 antd.css的 ant- 前缀
import { ConfigProvider } from 'antd';
import { ConfigProvider as ConfigProviderV4 } from 'antd4';
import zhCN from 'antd/lib/locale/zh_CN'
import zhCNV4 from 'antd4/lib/locale/zh_CN'
export function routerConfig(props) {
return (
<ConfigProvider locale={zhCN}>
<ConfigProviderV4 locale={zhCNV4} prefixCls="antd4">
{props.children}
</ConfigProviderV4>
</ConfigProvider>
)
}
prefixCls
antd 的组件都有一个 prefixCls 叫 ant-xxx,比如 按钮 组件是 ant-btn。
当多版本 antd 混合的时候,为了解决样式冲突,一般我们会改这个 prefixCls叫一个其他名字然后重新编译一份对应的 css 文件。
但是问题来了,对于静态方法,其实你并没有设置它的 prefixCls,
所以 antd 里又提供了一个静态方法用于设置静态方法的 prefixCls。好吧,这的确有点绕,代码却很简单:
ConfigProvider.config({
prefixCls: xxxx,
});
// 没有 context,那么我们如果要在不同场景下去做不同的 context 该如何处理呢
Notification.open({
prefixCls: xxx,
message: 'Hello World',
});
Notification.open({
getContainer: () => xxx,
message: 'Hello World',
});
.webpackrc.js
- env 字段是针对特定环境进行配置,HMR 只在开发环境下使用,所以将配置添加到 development 字段即可
- extraBabelPlugins antd 按需引入 ```json const theme = require(‘@ant-design/aliyun-theme’); const modifyVarsPlugin = require(‘./modifyVarsPlugin’)
module.exports = { “extraBabelPlugins”: [ [ “import”, // antd4 按需引入 { “libraryName”: “antd4”, “libraryDirectory”: “es”, “style”: true }, “antd4” ] ], “env”: { “development”: { “extraBabelPlugins”: [ “babel-plugin-dva-hmr”, // HMR 模块热替换 //“dva-hmr” ] } }, // theme, 删除,移动到下面 lessLoaderOptions: { javascriptEnabled: true, modifyVars: { // 重要的设置,修改 css前缀 “@ant-prefix”: “antd4”, …theme, }, // antd4文件需要经过 loader 处理,node_modules/antd/*.less // include: [/node_modules[\|\/]antd4/], sourceMap: false, plugins: [ modifyVarsPlugin( {‘ant-prefix’: ‘antd4’}, { pathReg: /antd@4/i } ) ] }, }
midifyVars 参考 [https://github.com/ant-design/ant-design/issues/14272#issuecomment-453359894](https://github.com/ant-design/ant-design/issues/14272#issuecomment-453359894)<br />less-load [https://webpack.js.org/loaders/less-loader](https://webpack.js.org/loaders/less-loader)<br />用别名同时安装 antd3和 antd4 两个版本 [https://blog.csdn.net/web220507/article/details/124864455](https://blog.csdn.net/web220507/article/details/124864455)<br />webpack配置参考 [https://www.kancloud.cn/yanli/notebook/1163898](https://www.kancloud.cn/yanli/notebook/1163898)
<a name="NEs9S"></a>
### modifyVarsPlugins
```javascript
module.exports = (vars, options) => {
const patterns = Object.entries(vars)
.map(item => {
const [key, val] = item;
return { key, val, reg: new RegExp(`(@${key}):[^;]*;`, 'ig') }
});
return {
install(less, pluginManager) {
pluginManager.addPreProcessor({
process(str, {fileInfo}) {
let result = str;
if (result && options.pathReg.test(fileInfo.filename)) {
patterns.forEach(it => {
result = result.replace(it.reg, `$1: ${it.val};`);
});
return result;
}
return result;
},
});
}
}
}
dva2.4.1 升级 antd5报错
antd 3x,升级到 antd4x,通过 npm别名方式,可以兼容升级;
antd3x,升级到 antd5x,报错,主要是编译 cssinjs的错误,编译无法通过。
- 升级 antd5,推荐使用 umi4
- 如果是 antd3x,推荐升级到 antd4x