技术债务来自旧项目的依赖过久,React 16 + antd 3 + webpack 4。React 新版本的批处理优化了,antd 最新已经由 css-in-js 重写了,不用再配置 less 等预先编译器。旧版本的 webpack 在 nodejs 20 会出现 openssl 的报错,需要配置以下环境变量才能正常运行,长期看,这些项目依赖已经不符合长期迭代。
NODE_OPTIONS=--openssl-legacy-provider
首先我们要检查依赖版本,针对核心工具库依赖升级,把打包工具从 webpack 切换成为 vite。最后总结老旧项目的升级收益。
推荐,vscode插件查看 package.json 中各依赖最新的版本,你可以挑取核心依赖专门进行升级。也可以利用 knip 剪枝掉没用的 dependencies。
该工具是命令行工具,它可以按照规则批量升级依赖。它可以按照 sermer 版本号规则,利用其major/minor/patch 的规则,升级版本号,更有把握地批量升级。
旧代码存在不规范的 case:“在 promise 当中设置 setState,然后立即获取 this.state。”这类的逻辑是能够在 react 16 跑通的,但是 react 18 已经优化了批处理的逻辑,所以 setState 会合并,this.state 由于 setState 是异步的,所以不能获取设置后的状态。
修改方法:绕过 setState,异步直接导出数据。
const fetchApi = async () => {
const resp = await requestApi();
this.setState({data: resp.data});
return resp.data;
}
const init = async () => {
const resp = await fetchApi();
// 修改前
console.log(this.state.data);
// 修改后
console.log(resp);
setState...
}
利用 createRoot 进行根节点的初始化。
// 修改前
ReactDOM.render(<App />, document.querySelector('#root'));
// 修改后
const root = createRoot(document.querySelector('#root'));
root.render(<App />);