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

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

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

相关推荐
Csvn1 小时前
并发模式:让渲染学会排队、插队和让路
前端
可乐鸡翅yeah_1 小时前
新手梳理:M3U8 线上问题,哪些是前端锅,哪些是后端锅
前端·ios·音视频·实时音视频·m3u8·音视频在线播放
Flynt1 小时前
Linear 用 1000 个 PR 换掉 styled-components,我写了 200 个按钮,把这笔账复现了一遍
前端·css·preact
JavaGuide2 小时前
NVIDIA 又开源了!这次给 AI Agent 加上权限管控
前端·后端
excel2 小时前
prisma 如何处理数据库竞态
前端·数据库·后端
莪_幻尘4 小时前
Skill 体检:30 个 Skill 全凭感觉?体检器先自曝了 8 个“假 0 分
前端·人工智能·llm
风骏时光牛马4 小时前
AI模型综合能力评测:性能、指令遵循与多场景实测对比
前端
Frag0ut4 小时前
Chrome与Chromium内核浏览器在Windows 11上的新特性全景解析
前端·chrome·windows·web安全·chromium·gemini ai·playready drm
hiahiahia1234 小时前
实现完整 Tool Dispatcher
开发语言·前端
IT_陈寒5 小时前
Java线程池这破玩意,差点让我周末加班排查到凌晨
前端·人工智能·后端