ant-design V3升级V4记录(成功篇)
背景:
1、为什么要升级?
升级我个人认为是在研发软件过程中必不可少的,同样也是谨慎的,那为什么还要升级呢?一是antd是一个开源性生态框架,人家社区一直在更新迭代,如果产品不及时更新,一直在使用不维护的,甚至有问题的框架,后果可想而知。
且能享受到升级框架的优点,如性能、拓展组件等等。
另外在我升级V4时,其实框架已经到了V5了,无奈升级到V5前,必须先升级V4。
2、为什么现在升级?
因为现在年底,有时间折腾了。
年后新项目启动后就无法腾出那么多精力了。
也为升级V5打下基础。
好,我们继续....
这篇博客没有一步步记录升级过程中的错误以及解决办法,所以只罗列的大致的错误项,希望对在升级之路上的你有所帮助。
第一步:老老实实按照官网升级开始造,从 v3 到 v4 - Ant Design
使用工具antd4-codemod,键入antd4-codemod app 命令开始一顿操作,后续出现的问题及截图如下:
1、静态图片引入项目后,解析失败; 原因配置文件加装file-loader,移除url-loader^6.2.0。
use: [‘file-loader’]
2、浏览器报host 无效;原因:V4版本webpack的allowedHosts属性不适配,降级使用disableHostCheck: true。
3、Plugin/Preset files are not allowed to export objects,only functions.webpack; 原因:babel版本兼容问题以及.babelrc文件配置,可在下方沿用我的babel相关版本。
4、You may need an appropriate loader to handle this file type, currently no loaders are configured...
同上。
5、react-hot-loader不生效。原因:配置文件的入口配置
entry: [
'react-hot-loader/patch',
path.resolve('', 'app/index.jsx')],
6、Cannot assign to read only property 'exports' of object '#<Object>'。原因:函数式组件 import和module.export 不能搭配使用,切换import+ export default funName{}
7、css不生效或Operation on an invalid type。原因:检查style-loader\less-loader\css-loader版本,挨个尝试。
8、.plugins[0][1] must be an object, false, or undefined。 原因:babel-loader配置错误,查看V4 webpack官网文档即可。
9、antd 按需加载 tree shaking无效。原因:V4本身已包含按需加载功能,未生效可检查babel配置。
10、安装依赖之后,未生效。原因:建议删除node_modules,重新npm i。
其他报错,可依据控制台提示即可,等回想起来再补充。
.babelrc文件:
{
"presets": [
"@babel/preset-react", "@babel/preset-env"
],
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/plugin-transform-runtime",
"react-hot-loader/babel"
]
}
package.json文件:
{
"name": "casshand",
"version": "1.0.2",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server --devtool eval --progress --config build/webpack.config.js",
"build": "webpack --progress --config build/webpack.qas.config.js",
"dist": "webpack --progress --profile --colors --config webpack.production.config.js",
"test": "jest --colors --coverage"
},
"author": "Ime",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.5.5",
"@babel/plugin-proposal-class-properties": "^7.3.0",
"@babel/plugin-transform-runtime": "^7.19.6",
"@babel/preset-env": "^7.5.5",
"@babel/preset-react": "^7.0.0",
"@babel/preset-stage-0": "^7.8.3",
"@babel/runtime": "^7.3.1",
"@hot-loader/react-dom": "^16.13.0",
"autoprefixer": "^6.4.0",
"babel-jest": "^24.8.0",
"babel-loader": "^8.0.6",
"babel-plugin-component": "^1.1.1",
"babel-plugin-import": "^1.8.0",
"babel-plugin-react-transform": "^2.0.2",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-preset-es2015": "^6.14.0",
"bufferutil": "^4.0.1",
"compression-webpack-plugin": "^1.1.12",
"copy-webpack-plugin": "^4.6.0",
"css-loader": "^4.3.0",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"eslint": "^4.12.1",
"eslint-loader": "^1.5.0",
"eslint-plugin-react": "^7.27.1",
"eslint-plugin-react-hooks": "^4.3.0",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^4.4.1",
"jest": "^24.8.0",
"json-loader": "^0.5.4",
"koa": "^1.2.2",
"koa-router": "^5.4.0",
"less": "^3.9.0",
"less-loader": "^6.2.0",
"open-browser-webpack-plugin": "^0.0.2",
"postcss-loader": "^4.3.0",
"purgecss-webpack-plugin": "^5.0.0",
"react-hot-loader": "^3.1.0",
"react-test-renderer": "^16.8.6",
"react-transform-hmr": "^1.0.4",
"style-loader": "^1.3.0",
"uglifyjs-webpack-plugin": "^1.3.0",
"url-loader": "^0.5.7",
"utf-8-validate": "^6.0.0",
"webpack": "^4.29.3",
"webpack-cli": "^3.2.3",
"webpack-dev-server": "^3.1.14"
},
"dependencies": {
"@ant-design/compatible": "^1.1.2",
"@ant-design/icons": "^4.7.0",
"antd": "^4.24.7",
"axios": "^0.18.0",
"bizcharts": "^4.1.20",
"form-render": "^1.13.8-beta.5",
"fundebug-javascript": "^2.8.0",
"html2canvas": "^1.0.0-rc.7",
"lodash.clonedeep": "^4.5.0",
"react": "^18.2.0",
"react-dom": "^16.8.0",
"react-pdf": "^5.7.2",
"react-router-dom": "^4.3.1",
"react-viewer": "^2.10.2",
"redux": "^4.0.0",
"xlsx": "^0.16.9"
}
}
webpack.config.js:
/*
* @Author: [Ime] <1059070187@qq.com>
* @Date: 2018-06-21 10:27:55
* @Last Modified by: cassmall
* @Last Modified time: 2022-03-18 17:31:31
*/
var path = require('path');
const glob = require('glob');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var {PurgeCSSPlugin} = require('purgecss-webpack-plugin');
module.exports = {
entry: [
'react-hot-loader/patch',
path.resolve('', 'app/index.jsx')],
output: {
filename: 'bundle.js',
},
resolve:{
extensions:['.js','.jsx','.web.js'], //自动解析确定的扩展
alias:{'react-dom':'@hot-loader/react-dom'} //创建 import 或 require 的别名,来确保模块引入变得更简单
},
module: {
rules: [
{
test: /\.(js|jsx)$/i,
use: [
{loader: 'babel-loader',
options: {
presets: ['@babel/preset-react','@babel/preset-env'],
plugins: [
['@babel/plugin-transform-runtime'],
['import',
{libraryName:'antd', libraryDirectory: 'es', style:'css'}]
]
}
},
{loader: 'react-hot-loader/webpack'},
],
exclude: /node_modules/,
},
{ test: /\.less$/, use: [
{loader: 'style-loader'},
{loader: 'css-loader'},
{loader: 'postcss-loader'},
{loader: 'less-loader'}
] },
{ test: /\.css$/, use: [
{loader: 'style-loader'},
{loader: 'css-loader'},
{loader: 'postcss-loader'},
{loader: 'less-loader'}
] },
{ test: /\.(png|gif|jpg|jpeg|bmp)$/i, use: [
//{loader: 'url-loader?limit=10240&name=images/[name].[ext]'},
{loader: 'file-loader'}
] },
{ test: /\.(woff|woff2|svg|ttf|eot)($|\?)/i, use: 'url-loader?limit=10240&name=images/[name].[ext]' },
],
noParse: [/jszip.js$/],//解决预构建的javascript文件引入,获取原始源配置,
unknownContextCritical : false,
},
// postcss: [
// require('autoprefixer') //调用autoprefixer插件,例如 display: flex
// ],
plugins: [
// html 模板插件
new HtmlWebpackPlugin({
template: 'app/index.tmpl.html'
}),
// 热加载插件
new webpack.HotModuleReplacementPlugin(),
// 可在业务 js 代码中使用 __DEV__ 判断是否是dev模式(dev模式下可以提示错误、测试报告等, production模式不提示)
new webpack.DefinePlugin({
__DEV__: JSON.stringify(JSON.parse((process.env.NODE_ENV == 'dev') || 'false'))
}),
new CopyWebpackPlugin([
{
from: 'node_modules/pdfjs-dist/cmaps/',
to: 'cmaps/'
},
]),
new PurgeCSSPlugin({
paths: glob.sync(path.join(__dirname, 'app/index.tmpl.html')),
}),
],
mode: 'development',
devServer: {
compress: true,
historyApiFallback: true, //不跳转,在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
hot: true, // 使用热加载插件 HotModuleReplacementPlugin
host:'localhost',
port:'80',//8080
disableHostCheck: true,
proxy:{
}
}
};
结尾:
之后持续更新,希望本文对大家有所帮助。