背景:CRA 时代的终结
随着 Create React App(CRA)被官方正式标记为废弃,大量依赖它的项目面临着构建工具的选型与迁移。本文记录了我将一个基于 CRA + CRACO + Cesium 的真实生产项目迁移到 Vite 的完整过程,包括踩过的坑、做过的优化,以及最终的性能收益。
为什么必须迁移?
CRA 多年来确实是 React 项目的默认选择,但它的短板在今天已经越来越明显:
表格
| 指标 | CRA (Webpack) | Vite (esbuild) |
|---|---|---|
| 开发服务器冷启动 | ~15s | ~2s |
| HMR 热更新响应 | ~1000ms | ~200ms |
| 底层构建引擎 | Webpack | esbuild / Rollup |
| 维护状态 | 已废弃 | 活跃迭代 |
核心差距来自底层工具链:Vite 在开发阶段使用 esbuild 做依赖预构建,速度是 Webpack 的 10-100 倍;生产构建则基于 Rollup,产物体积更优。对于一个集成了 Cesium 这种重量级 3D 库的项目来说,构建速度的提升尤为明显。
迁移实战步骤
第一步:清理 CRA / CRACO 遗留物
先卸载所有 CRA 和 CRACO 相关依赖:
bash
bash
npm uninstall react-scripts @craco/craco craco-cesium
然后更新 package.json 中的脚本命令:
json
json
{
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"lint": "eslint src/**/*.{js,jsx,ts,tsx,json}",
"format": "prettier --write src/**/*.{js,jsx,ts,tsx,css,md,json,scss} --config ./.prettierrc"
}
}
第二步:安装 Vite 与必要插件
bash
bash
# Vite 核心与 React 支持
npm install --save-dev vite @vitejs/plugin-react
# Cesium 集成插件
npm install --save-dev vite-plugin-cesium
npm install cesium
注意:这里使用的是
vite-plugin-cesium(面向完整cesium包),如果你只用@cesium/engine核心库,更推荐上一篇文章介绍的vite-plugin-cesium-engine。
第三步:编写 vite.config.js
这是迁移中最核心的配置文件,涵盖了 React JSX 转换、Cesium 集成、API 代理、路径别名和构建优化:
javascript
运行
javascript
import { defineConfig, loadEnv } from 'vite';
import react from '@vitejs/plugin-react';
import cesium from 'vite-plugin-cesium';
export default defineConfig(({ command, mode }) => {
// 根据 mode 加载对应环境变量
const env = loadEnv(mode, process.cwd(), '');
return {
plugins: [
react({
include: ['**/*.jsx', '**/*.js', '**/*.tsx', '**/*.ts'],
babel: {
plugins: [
['@babel/plugin-transform-react-jsx', { runtime: 'automatic' }]
]
}
}),
cesium(),
],
server: {
proxy: {
'/api': env.VITE_PORT_API_KEY,
'/tilesets': env.VITE_PORT_API_KEY
},
},
resolve: {
alias: {
'@': '/src',
},
},
optimizeDeps: {
exclude: ['react-virtualized'],
include: ['prop-types'],
},
build: {
assetsInlineLimit: 0,
commonjsOptions: {
include: [/react-virtualized/, /node_modules/],
},
chunkSizeWarningLimit: 1600,
},
};
});
几个关键配置的解释:
react({ include: [...] }):让 Vite 同时处理.js和.jsx文件中的 JSX 语法,兼容老项目中混用的情况optimizeDeps.exclude:react-virtualized这类对 CommonJS 兼容有问题的库,排除预构建可以避免运行时报错assetsInlineLimit: 0:Cesium 项目有大量静态资源,禁止内联为 base64,避免产物体积爆炸chunkSizeWarningLimit: 1600:Cesium 本身体积很大,适当提高 chunk 告警阈值,避免构建日志被无意义警告刷屏
第四步:Cesium 静态资源的特殊处理
Cesium 运行时依赖大量静态文件(Workers、Widgets、Assets、ThirdParty),这是迁移中最容易出问题的环节。
虽然 vite-plugin-cesium 会自动处理大部分资源,但在某些复杂项目中,手动拷贝一份到 public 目录是最稳妥的方案:
bash
bash
# 清理旧的拷贝
rm -rf public/cesium
# 从 node_modules 拷贝完整的 Cesium 构建产物
cp -r node_modules/cesium/Build/Cesium public/cesium
同时在 Vite 配置中定义基础路径:
javascript
运行
css
define: {
CESIUM_BASE_URL: JSON.stringify('/cesium'),
}
这样生产环境中 Cesium 会从 /cesium 路径加载所有资源。
第五步:HTML 入口文件改造
Vite 不支持 CRA 的 %PUBLIC_URL% 占位符,直接使用根路径即可:
html
预览
xml
<!-- index.html -->
<link rel="icon" href="/favicon.ico" />
<script type="module" src="/src/index.jsx"></script>
注意:Vite 的 index.html 放在项目根目录,而不是 CRA 的 public/ 目录下。
第六步:.js 与 .jsx 文件重命名
CRA 允许在 .js 文件中写 JSX,但 Vite 默认只对 .jsx / .tsx 文件做 JSX 转换。如果你的老项目里有大量 .js 文件包含 JSX,可以用脚本批量重命名:
bash
bash
#!/bin/bash
# rename-jsx.sh
echo "🔍 正在扫描 .js 文件中的 JSX 语法..."
find ./src -name "*.js" | while read file; do
if grep -qE "</?[A-Za-z].*?>" "$file"; then
newfile="${file%.js}.jsx"
mv "$file" "$newfile"
echo "✅ 已重命名: $file → $newfile"
fi
done
echo "🎉 完成!所有含 JSX 的文件已重命名为 .jsx"
运行:
bash
perl
chmod +x rename-jsx.sh
./rename-jsx.sh
更稳妥的做法是配合
vite.config.js中的react({ include: ['**/*.js'] })配置,这样即使不重命名也能正常工作,但重命名是更规范的长期方案。
第七步:环境变量迁移
Vite 要求客户端可访问的环境变量必须以 VITE_ 为前缀:
bash
ini
# .env
VITE_FLAG_SMITH_API_KEY=abc123
使用方式从 CRA 的 process.env 改为:
javascript
运行
ini
const key = import.meta.env.VITE_FLAG_SMITH_API_KEY;
第八步:静态资源处理
将图片、字体、Logo 等资源移到 /public 目录,引用时直接使用根路径:
javascript
运行
javascript
// CRA 旧写法
require('../../assets/logo.png')
// Vite 新写法(资源在 public 目录下)
src="/logo.png"
如果老项目中 require() 用法太多不想逐个改,可以安装兼容插件:
bash
css
npm install vite-plugin-commonjs --save-dev
但更推荐逐步替换为标准的 ES Module import 语法。
第九步:清理冗余依赖
bash
css
npm uninstall html-webpack-plugin
迁移效果
完成以上步骤后,项目的开发体验有了质的飞跃:
- 冷启动:15s → 2s,提升约 7.5 倍
- HMR 热更新:1000ms → 200ms,提升约 5 倍
- 配置复杂度 :从厚重的 Webpack + CRACO 配置,简化为一个几十行的
vite.config.js - Cesium 集成:通过插件 + 手动拷贝双保险,开发和生产环境都稳定运行
总结与建议
从 CRA 迁移到 Vite 不是简单的换个构建工具,而是一次工具链现代化的升级。对于集成了 Cesium 的项目,有几点经验值得注意:
- Cesium 资源路径是头号坑 :务必确认
CESIUM_BASE_URL和实际资源输出路径一致,建议先用debug模式验证 - CommonJS 兼容库要单独处理 :
react-virtualized、prop-types这类老库可能需要optimizeDeps和commonjsOptions的特殊配置 - 渐进式迁移可行 :可以先让
.js文件通过include配置兼容 JSX,再逐步重命名为.jsx - 产物体积要关注 :Cesium 本身很大,配合
manualChunks做代码分割可以进一步优化加载性能
CRA 的时代已经结束,Vite 是当下 React 项目最稳妥的迁移方向。如果你还在维护 CRA 项目,建议尽早规划迁移。