从 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 项目,建议尽早规划迁移。

相关推荐
支支დ5 小时前
VO by Vercel 前端特定优势:为什么它是构建 AI 应用的新范式
前端·人工智能
香芋芋圆6 小时前
AI 冲击内卷之下,普通前端如何破局?WebGIS—— 低门槛突围赛道
前端·javascript·人工智能·学习·职场发展
INS_KF6 小时前
【编程笔记】成员函数中两个 const 的区别(const Data &getData() const;)
前端·javascript·笔记
宿6747 小时前
vue3-async
前端·javascript·vue.js
YXWik67 小时前
记录前端请求接口在浏览器请求响应的Preview和Response展示的一样的问题
前端
2501_928996227 小时前
GPT-4o换DeepSeek迁移成本多少?中科热备解析API聚合平台技术账本
前端·数据库·人工智能
东风破_7 小时前
从跨域到 WebSocket:前端跨域方案、SSE 与双向实时通信详解
前端·后端
原则猫7 小时前
TS 类型工具
前端
excel8 小时前
Nuxt + Twin CSS 中宽度超过屏幕时底部出现空白的原因与解决方案
前端·javascript
计算机魔术师9 小时前
美国司法部正式站队 OpenAI,AI 训练的版权账要这么算了
前端