从 CRA 到 Vite:含 Cesium 的真实项目迁移实战记录

背景: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.excludereact-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 的项目,有几点经验值得注意:

  1. Cesium 资源路径是头号坑 :务必确认 CESIUM_BASE_URL 和实际资源输出路径一致,建议先用 debug 模式验证
  2. CommonJS 兼容库要单独处理react-virtualizedprop-types 这类老库可能需要 optimizeDepscommonjsOptions 的特殊配置
  3. 渐进式迁移可行 :可以先让 .js 文件通过 include 配置兼容 JSX,再逐步重命名为 .jsx
  4. 产物体积要关注 :Cesium 本身很大,配合 manualChunks 做代码分割可以进一步优化加载性能

CRA 的时代已经结束,Vite 是当下 React 项目最稳妥的迁移方向。如果你还在维护 CRA 项目,建议尽早规划迁移。

相关推荐
cyadyx14 小时前
Vite 比 Webpack 构建效率更高
前端·webpack·node.js·vite
mCell15 小时前
AI 时代 SVG 画图的潜力
前端·agent·svg
我命由我1234521 小时前
CesiumJS 笔记 - 获取容器中心点、Cartesian3 clone 方法、修改 Cartesian3 对象的高度
前端·javascript·css·前端框架·html·html5·js
Hopebearer_1 天前
页面突然只剩 DOM?一次静态资源版本错配排查
前端·部署
东风破_1 天前
ESLint 是什么?为什么你的项目需要它?
前端·后端·代码规范
圣殿骑士-Khtangc1 天前
Go字符串高效拼接性能对比与底层原理分析
服务器·前端·golang
BigTopOne1 天前
【ijkplayer】 硬解码流程
前端
kyriewen1 天前
DeepSeek Harness开源第一天我就上手了——和Claude Code的差距比想象中大
前端·ai编程·deepseek
捡田螺的小男孩1 天前
什么是 Skill?手把手带你写一个简单有用的 Skill!
前端·后端·程序员
IT_陈寒1 天前
Redis集群这个坑,差点让我通宵
前端·人工智能·后端