跳转到内容

从 Taro 迁移

本指南适用于使用 Taro 3 或 Taro 4 的 React 项目。迁移后继续使用 Taro 组件、API、生命周期和页面路径,但构建入口、配置位置与导入路径会改变。vpt 使用 Taro 4 运行时,来自 Taro 3 的项目还需要处理已经废弃或改变的 Taro API。

迁移涉及配置拆分、导入替换、React 19 兼容性和构建插件清理,推荐让 AI 编程助手直接读取新旧两个项目并执行迁移。AI 可以根据实际源码逐文件修改,比照着通用步骤手动批量替换更可靠。

可以把本指南链接和下面的任务说明交给 AI:

请将旁边的 Taro React 项目迁移到这个 create-vite-taro 项目。
开始修改前:
1. 请先完整阅读 vpt 的文档。
2. 阅读旧项目的 package.json、config、app.config、所有页面配置和构建插件。
3. 阅读新项目的 vite.config.ts、package.json 和现有页面约定。
4. 列出不能直接迁移的能力和需要我确认的行为变化。
迁移时:
1. 保留新项目的 Vite 构建结构,逐项迁移业务源码和配置。
2. 将项目源码中的 Taro 导入改为 virtual:taro/api 和 virtual:taro/components。
3. 不要批量修改第三方依赖或生成文件。
4. 每完成一个阶段就运行 typecheck、微信构建和 Web 构建。
5. 对照旧项目逐页检查路由、样式、资源、生命周期和 Taro API。

让 AI 分阶段提交修改,并要求它解释删除的每一项 Taro 配置。涉及原生页面分包、自定义原生组件、Taro 插件或 webpack 定制时,应先确认替代方案,不要让 AI 静默删除。

建议先创建一个新的 vpt 项目,再逐步复制业务源码,而不是直接修改原项目的构建配置。这样可以保留一份可运行的 Taro 项目,用于逐页比较结果。

主要变化如下:

Taro 项目vpt 项目
taro build --type weappvite,目标为 wx
taro build --type h5vite,目标为 h5
config/index.tsconfig/dev.tsconfig/prod.tsvite.config.ts 与 Vite 配置
src/app.config.ts.jsvpt({ appJson, pages })
页面旁的 *.config.ts.js对应 pages[].config
project.config.jsonproject.private.config.jsonsitemap.json对应的插件选项
src/index.html项目根目录的 index.html
@tarojs/tarovirtual:taro/api
@tarojs/componentsvirtual:taro/components
手动维护分包vpt全自动分包

在原项目旁创建一个新目录:

终端窗口
pnpm --config.minimum-release-age=0 create vite-taro@latest my-app-vpt
cd my-app-vpt
pnpm install

先运行模板,确认微信和 Web 都能启动,再复制业务代码:

终端窗口
pnpm dev:wx
pnpm dev:h5

两个开发命令需要在不同终端运行。微信开发者工具应导入新项目的 dist/wx

从原项目复制以下内容:

  • src/app.tsx 与全局样式。
  • src/pages 中的 React 页面。
  • 业务组件、hooks、状态管理、请求模块和工具函数。
  • 图片、字体等业务资源。

保留新项目生成的以下文件,再按需合并内容:

  • 根目录 index.html
  • vite.config.ts
  • tsconfig.jsontsconfig.app.jsontsconfig.node.json
  • .env.local
  • package.json 中的开发和构建脚本。

Taro 官方模板把 Web HTML 放在 src/index.html,vpt 使用根目录的 Vite index.html。不要用旧文件覆盖新项目的根入口;如果旧文件包含标题、meta 或其他标签,只合并需要的部分,并保留:

<div id="app"></div>

业务代码不再直接导入 @tarojs/*。将组件导入改为 virtual:taro/components,将 API 和生命周期导入改为 virtual:taro/api

迁移前:

import { Button, Text, View } from '@tarojs/components'
import Taro, { useDidShow, useLoad } from '@tarojs/taro'

迁移后:

import Taro, { useDidShow, useLoad } from 'virtual:taro/api'
import { Button, Text, View } from 'virtual:taro/components'

Taro.request()Taro.navigateTo()useLaunch()useLoad() 等调用方式不变。process.env.TARO_ENV 也可以继续用于目标判断:微信、支付宝、抖音和 Web 构建中的值分别为 weappalipaytth5

Taro 会读取 app.config.ts 和每个页面旁边的 *.config.ts。vpt 不读取这些文件,配置必须写入 vite.config.ts

假设原来的 src/app.config.ts 为:

export default defineAppConfig({
pages: ['pages/index/index', 'pages/profile/index'],
window: {
navigationBarTitleText: '示例应用'
},
tabBar: {
color: '#64748b',
selectedColor: '#16a34a',
list: [
{ pagePath: 'pages/index/index', text: '首页' },
{ pagePath: 'pages/profile/index', text: '我的' }
]
}
})

页面配置为:

export default definePageConfig({
navigationBarTitleText: '个人中心',
enablePullDownRefresh: true
})

将页面顺序和页面配置合并到 pages,其余应用配置放入 appJson。在新模板现有的 vpt() 调用中替换这两个字段,保留其他字段:

pages: [
{
path: 'pages/index/index',
config: {}
},
{
path: 'pages/profile/index',
config: {
navigationBarTitleText: '个人中心',
enablePullDownRefresh: true
}
}
],
appJson: {
window: {
navigationBarTitleText: '示例应用'
},
tabBar: {
color: '#64748b',
selectedColor: '#16a34a',
list: [
{ pagePath: 'pages/index/index', text: '首页' },
{ pagePath: 'pages/profile/index', text: '我的' }
]
}
}

上面以 WX/H5 配置为例。微信、支付宝与抖音构建都应使用对应平台的原生字段,vpt 不执行 Taro CLI 的配置转换。例如,ZFB 分支应把 navigationBarTitleText 写为 defaultTitle、把 enablePullDownRefresh 写为 pullRefresh,并使用支付宝的 tabBar 结构;TT 分支应按抖音文档提供应用和页面配置,不要复制微信专属的 Skyline 字段。可以参考生成模板中的 createAppJson(target)createPageJson(target)

配置迁移规则:

  • pages 的顺序就是生成的 app.json.pages 顺序,也是 Web 路由顺序。
  • appJson.pages 会被 pages 覆盖,不要重复填写。
  • appJson.subPackagesappJson.subpackages 会被移除,不要从旧配置复制。
  • 每个页面的 config 会生成当前目标的页面 JSON,同时参与 Web 路由配置;字段名不会跨平台转换。
  • window、普通 tabBar 和权限配置可以保留在对应目标的 appJson;Skyline 配置只能进入 WX 分支。
  • defineAppConfig()definePageConfig() 包装函数不再需要。

vpt全自动分包处理的是通过动态 import() 加载的 JavaScript 模块,不是微信原生页面分包。所有 pages 条目都会生成到主包页面列表。

如果原项目使用以下能力,不能直接复制对应配置:

  • subPackagessubpackages 中的页面。
  • 独立分包。
  • 指向手动分包根目录的 preloadRule

请先把页面整理为普通主包页面,再使用动态 import() 延迟加载页面内部的大型功能。具体行为参见全自动分包

以新模板的 projectConfigJson 为基础,迁移旧 project.config.json 中仍然需要的字段,例如 projectnamedescriptionsetting

注意以下区别:

  • App ID 建议继续从 .env.local 读取,不要提交到仓库。
  • 不要复制旧的 miniprogramRoot;微信开发者工具直接打开 dist/wx
  • 保留模板的 compileHotReLoad: true 才能使用开发者工具热更新。
  • project.private.config.json 的内容放入 projectPrivateConfigJson
  • sitemap.json 的内容放入 sitemapJson

projectConfigJsonsitemapJson 在类型上始终需要提供,但只会在小程序构建中写出。

config/index.tsconfig/dev.tsconfig/prod.ts 不会再执行。按下面的对应关系迁移真正需要的配置:

Taro 配置vpt / Vite 中的做法
sourceRoot页面源码固定放在 src 下。
outputRoot使用 Vite 的 build.outDir,建议保持 dist/${target}
alias使用 Vite 的 resolve.alias,并同步 TypeScript 路径配置。
defineConstants使用 Vite 的 define
copy.patterns将原样复制的文件放入 public,或使用普通 Vite 复制插件。
mini.postcssh5.postcss使用 Vite 的 css.postcss 或 PostCSS 配置。
mini.webpackChainh5.webpackChain删除并改写为 Vite 插件或 Vite 配置。
H5 history 与 publicPathWeb 固定使用 hash 路由;资源路径交给 Vite 的 base
Taro plugins不会运行;确认用途后改写为 Vite 插件或业务代码。
compilerframework删除;vpt 已确定使用 Vite 与 React。

designWidthdeviceRatio 和 Taro pxtransform 配置没有可直接复制的选项。vpt 会为微信样式转换 pxrem,迁移后应逐页检查尺寸,不要假设旧的自定义换算比例仍然生效。

Vite 客户端代码只会公开以 VITE_ 开头的环境变量。将旧环境变量改名后通过 import.meta.env 使用:

const apiBaseUrl = import.meta.env.VITE_API_BASE_URL

vite.config.ts 中的变量通过 loadEnv() 读取。不要继续依赖 Taro 在构建配置中注入的自定义环境变量。

构建时仍会替换 process.env.TARO_ENV:wx、zfb、tt 和 h5 构建中的值分别为 weappalipaytth5。如果迁移后的 TypeScript 配置不再声明 process,优先改用下面的注释指令;也可以在项目自己的类型文件中为 process.env.TARO_ENV 添加窄类型声明。

注释指令中的微信小程序需要从 WEAPP 改为 wx

// #ifdef wx
console.log('微信小程序')
// #endif
// #ifdef h5
console.log('Web')
// #endif

vpt 支持 #ifdef#ifndef#else#endif,不支持 #if#elif

  • 保留 src/app.tsx 对全局样式的导入。
  • 页面和组件可以继续导入 CSS、Sass、Less 或 Stylus;对应预处理器需要作为项目依赖安装。
  • CSS Modules 使用 Vite 的 *.module.css*.module.scss 等文件约定。
  • 由源码 import 的图片和字体继续交给 Vite 处理。
  • 原来通过 copy.patterns 复制且不参与模块构建的文件,移到 public 后检查最终路径。

新模板默认启用 Tailwind CSS v4。如果原项目不使用 Tailwind,可以删除 app.css 中的 Tailwind 导入和 @source,再保留迁移过来的普通全局样式。不要在未检查页面效果前同时引入旧 reset 样式和 Tailwind Preflight。

迁移项目应保留新模板中的 React 19、Vite、TypeScript 和 vite-plugin-taro 版本。将旧项目的业务依赖逐个安装,不要整段复制旧 dependenciesdevDependencies

通常可以删除仅服务于 Taro 构建链的直接依赖:

  • @tarojs/cli
  • @tarojs/webpack5-runner
  • @tarojs/vite-runner
  • @tarojs/plugin-framework-react
  • @tarojs/plugin-platform-*
  • @tarojs/taro-loader
  • babel-preset-taro
  • webpack 专用 loader 和插件

也不要在应用中直接安装 @tarojs/taro@tarojs/components。它们由 vpt 统一提供。

完成迁移后按以下顺序检查:

  1. 运行 TypeScript 检查,修复所有旧导入和类型错误。
  2. 启动 Web,逐个访问 pages 中的路由。
  3. 启动微信开发构建,在开发者工具中导入 dist/wx
  4. 检查 App 生命周期、页面生命周期、路由参数和 globalData
  5. 检查 tab bar、导航栏、下拉刷新和授权配置。
  6. 检查图片、字体、全局样式、CSS Modules 和各页面尺寸。
  7. 检查网络请求、登录、支付、订阅消息等微信 API。
  8. 修改一个深层 React 组件,确认热更新保留当前页面状态。
  9. 分别执行微信和 Web 生产构建。
  10. 使用微信开发者工具检查最终主包、分包和上传体积。
终端窗口
pnpm typecheck
pnpm build:wx
pnpm build:h5

迁移完成后可以删除旧的 config 目录、app.config.ts、页面 *.config.ts、旧构建脚本与不再使用的依赖。删除前先确认新项目的两个生产构建都通过。