vite-plugin-taro
v0.1.7
Published
Vite 8 plugin for building one React/Taro codebase for WeChat Mini Program and H5 targets.
Maintainers
Readme
vite-plugin-taro
简体中文 | English
使用最新标准化前端技术栈 Vite 8、React 19 和 Tailwind CSS v4 构建微信小程序。
vite-plugin-taro 适用于希望使用 Taro 跨平台 React 组件和 API,但更偏好 Vite 而非 Taro webpack 的应用。你只需要这个插件,就能构建完整的微信小程序。
在线演示:https://sep2.github.io/vite-plugin-taro。如何在本地运行,请参见示例应用。
- 原生 Vite 构建 使用标准 Vite 8 配置,无需维护老旧的 webpack 配置,并支持所有 Vite 插件。
- 热更新 微信小程序与 H5 都支持开发模式 watch,基于 Vite 8 热更新/快速重建即时预览。
- 依托成熟 Taro 能力 复用久经实战检验的 Taro API 和组件,完整使用 Taro 跨端能力。
- Tailwind 就绪 内置 Tailwind CSS v4 支持,微信小程序与 H5 样式开箱即用。
- 条件编译 支持 Taro 风格
#ifdef/#ifndef/#if,可按微信 / Web 裁剪代码和样式。 - 工作区友好 支持普通项目与 monorepo,兼容 npm、pnpm、Yarn、Bun 等包管理器。
- 类型友好 项目全链路支持 TypeScript。
- 微信 Skyline 支持微信小程序 Skyline 渲染模式输出。
快速开始
新应用推荐使用 create-vite-taro。它会生成 Vite 8 + React 19 + Tailwind CSS v4 + Taro 4 项目。
1. 创建并安装
# 使用默认模板创建新应用
npm create vite-taro@latest my-app
# 进入项目并安装依赖
cd my-app
npm install2. 配置微信小程序 App Id
模板会创建 .env.local。请将 VITE_PLUGIN_TARO_WECHAT_APP_ID 设置为你的微信小程序 App Id。
3. 开发模式运行
# 微信小程序:以 watch 模式重新构建 dist/wx
npm run dev:wx
# 然后在微信开发者工具中打开 dist/wx
# H5:启动 Vite 开发服务器
npm run dev:h5
# 然后在浏览器中打开标准 Vite 地址
# http://localhost:5173你可以在两个终端中同时运行 npm run dev:wx 和 npm run dev:h5。
提示:受微信限制,开发者工具热重载有时不会完整生效。建议日常优先使用 H5 的 Vite 热更新快速调试,并定期在微信开发者工具中验证小程序端效果。
4. 构建、预览和类型检查
# 生产微信小程序产物
npm run build:wx
# 生产 H5 产物
npm run build:h5
# 预览构建后的 H5 应用
npm run preview:h5
# 使用 tsgo 进行类型检查
npm run typecheck5. 使用 Taro 虚拟模块
应用代码请使用这些导入:
import Taro from 'virtual:taro/api'
import { Text, View } from 'virtual:taro/components'| 导入 | 用途 |
| --- | --- |
| virtual:taro/components | Taro React 组件,例如 View、Text、Button、Image 和 ScrollView。 |
| virtual:taro/api | Taro API 和 hooks,例如 Taro.navigateTo、Taro.getWindowInfo 和 Taro.useLaunch。 |
用法与 Taro 本身一致;组件和 API 的具体用法请参考 Taro 官网。
你不再需要安装 @tarojs/* 包;应用代码也不要从 @tarojs/* 导入。
手动接入已有应用
已有应用或自定义项目结构,可以按下面的步骤手动接入插件。先安装插件:
npm install -D vite-plugin-taro你的应用还必须提供 Vite 8、React 19、React DOM 19、TypeScript 检查器,以及 Node/React 类型包。如果应用尚未安装它们,请安装缺失的包:
npm install react react-dom
npm install -D vite @typescript/native-preview @types/node @types/react @types/react-dom你不应再直接依赖任何 @tarojs/* 包。如果已经依赖,请将它们移除。
下面的步骤会创建如下源码结构:
my-app/
├── index.html
├── package.json
├── tsconfig.json
├── vite.config.ts
└── src/
├── app.css
├── app.ts
└── pages/
└── index/
└── index.tsx你也可以参考 packages/loan-genius 中的示例布局。
1. 添加 TypeScript 声明
将插件客户端类型添加到 tsconfig.json,让 TypeScript 识别虚拟模块:
{
"compilerOptions": {
"jsx": "react-jsx",
"moduleResolution": "bundler",
"types": ["vite/client", "vite-plugin-taro/client"]
},
"include": ["src"]
}2. 配置 Vite
创建 vite.config.ts,并从环境变量中选择插件目标:
import { defineConfig, loadEnv } from 'vite'
import vitePluginTaro, { type VitePluginTaroTarget } from 'vite-plugin-taro'
const targetEnvName = 'VITE_PLUGIN_TARO_TARGET'
function getTarget(env: Record<string, string>): VitePluginTaroTarget {
const target = env[targetEnvName]
if (target === 'wx' || target === 'h5') return target
throw new Error(`${targetEnvName} must be "wx" or "h5".`)
}
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), 'VITE_PLUGIN_TARO_')
const target = getTarget(env)
return {
build: {
outDir: `dist/${target}`
},
plugins: [
vitePluginTaro({
target,
app: 'src/app.ts',
pages: [
{
path: 'pages/index/index',
config: {
navigationBarTitleText: 'Home'
}
}
],
appJson: {
window: {
navigationBarTitleText: 'Demo',
navigationBarBackgroundColor: '#ffffff'
}
},
projectConfigJson: {
appid: env.VITE_PLUGIN_TARO_WECHAT_APP_ID || 'touristappid',
projectname: 'demo',
compileType: 'miniprogram'
},
sitemapJson: {
rules: [{ action: 'allow', page: '*' }]
}
})
]
}
})重要约定:
- 每次 Vite 运行时,
target必须是wx或h5。 app是 React 根应用组件模块,应默认导出应用组件。- 每个
pages[].path都会映射到src/${path}.tsx文件。例如,pages/index/index需要src/pages/index/index.tsx。 appJson.pages会根据pages自动生成;你在appJson中传入的任何pages字段都会被覆盖。- 插件不会读取 Taro CLI 配置文件,例如
config/index.ts、app.config.ts或页面config.ts文件。请通过插件选项传入应用和页面配置。
3. 创建应用组件
src/app.ts 是共享应用包装组件。它会通过 children 接收当前页面。
import Taro from 'virtual:taro/api'
import type { PropsWithChildren } from 'react'
import './app.css'
function App({ children }: PropsWithChildren) {
Taro.useLaunch(() => {
console.log('App launched')
})
return children
}
export default App请在应用组件中导入全局样式。微信构建会将它们收集到 app.wxss,H5 输出也会包含它们。
4. 创建页面组件
src/pages/index/index.tsx 是 pages/index/index 对应的 React 页面组件。
import Taro from 'virtual:taro/api'
import { Button, Text, View } from 'virtual:taro/components'
export default function IndexPage() {
const windowInfo = Taro.getWindowInfo()
return (
<View className="p-4">
<Text>Viewport width: {windowInfo.windowWidth}</Text>
<Button
onClick={() => {
Taro.showToast({ title: 'Hello from Taro' })
}}
>
Show toast
</Button>
</View>
)
}5. 添加 H5 HTML 外壳
对于 H5,请保留一个普通的 Vite index.html,并包含 #app 挂载节点。插件会自动注入生成的 Taro H5 入口,因此你不需要普通 Vite 的 src/main.tsx 脚本。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Taro Vite App</title>
</head>
<body>
<div id="app"></div>
</body>
</html>6. 添加脚本
使用与 create-vite-taro 生成项目一致的脚本:
{
"scripts": {
"dev:wx": "NODE_ENV=development VITE_PLUGIN_TARO_TARGET=wx vite build --watch",
"dev:h5": "NODE_ENV=development VITE_PLUGIN_TARO_TARGET=h5 vite",
"build:wx": "NODE_ENV=production VITE_PLUGIN_TARO_TARGET=wx vite build",
"build:h5": "NODE_ENV=production VITE_PLUGIN_TARO_TARGET=h5 vite build",
"preview:h5": "NODE_ENV=production VITE_PLUGIN_TARO_TARGET=h5 vite preview --outDir dist/h5",
"typecheck": "tsgo -b"
}
}在 Windows shell 中,请使用 cross-env。
7. 运行每个目标
npm run dev:wx # 以 watch 模式重新构建 dist/wx
npm run dev:h5 # 启动 H5 开发服务器
npm run build:wx # 构建 dist/wx
npm run build:h5 # 构建 dist/h5
npm run preview:h5 # 预览 dist/h5
npm run typecheck # 使用 tsgo 进行类型检查在微信开发者工具中打开生成的 dist/wx 目录。
| 目标 | 含义 | 输出目录 |
| --- | --- | --- |
| wx | 开发/生产模式下的微信小程序。 | dist/wx |
| h5 | H5 生产输出。 | dist/h5 |
选项
type VitePluginTaroTarget = 'wx' | 'h5'
type VitePluginTaroPageOption = {
path: string
config: Record<string, unknown>
}
type VitePluginTaroOptions = {
target: VitePluginTaroTarget
app: string
pages: VitePluginTaroPageOption[]
appJson: Record<string, unknown>
projectConfigJson: Record<string, unknown>
sitemapJson: Record<string, unknown>
}| 选项 | 描述 |
| --- | --- |
| target | 本次 Vite 调用的活动目标。微信小程序使用 wx,Web 使用 h5。 |
| app | 默认导出根 React 应用组件的源码文件,例如 src/app.ts 或 src/app.tsx。 |
| pages | 有序页面列表。该顺序会成为 app.json.pages 和 H5 路由顺序。 |
| pages[].path | 不带扩展名的 Taro 风格路由和输出路径,例如 pages/index/index。页面组件必须存在于 src/${path}.tsx。 |
| pages[].config | 合并到生成的微信页面 JSON 和 H5 路由配置中的页面配置。 |
| appJson | 基础应用配置。插件会用 options.pages 覆盖其中的 pages 字段。 |
| projectConfigJson | wx 构建时输出的微信 project.config.json 内容。即使当前目标是 h5,选项类型也要求提供它。 |
| sitemapJson | wx 构建时输出的微信 sitemap.json 内容。即使当前目标是 h5,选项类型也要求提供它。 |
样式
你可以使用普通 CSS、CSS Modules 或 Tailwind CSS v4。
对于 Tailwind CSS v4,请从全局 CSS 文件(例如 src/app.css)导入 Tailwind:
@import "tailwindcss/theme.css";
@import "tailwindcss/preflight.css";
@import "tailwindcss/utilities.css";
@source "./";插件会为 wx 构建注册 weapp-tailwindcss,并为 h5 构建注册 @tailwindcss/vite。对于 wx,Vite 输出的 CSS 会被收集到 app.wxss,并为每个页面生成配套的 .wxss 文件。
条件编译
插件会在 Vite 解析源码前移除未激活的 Taro 风格条件注释块。它适用于 node_modules 之外的 TypeScript、JavaScript、JSX/TSX、CSS、Sass、Less 和 Stylus 文件。
// #ifdef wx
console.log('WeChat only')
// #endif
// #ifdef h5
console.log('H5 only')
// #endif
// #if wx && !h5
console.log('WeChat expression')
// #elif h5
console.log('H5 expression')
// #else
console.log('fallback')
// #endif支持的指令包括 #ifdef、#ifndef、#if、#elif、#else 和 #endif。条件使用插件目标标记 wx 和 h5;#if 表达式支持 !、&& 和 ||。
按目标输出
微信小程序
对于 target: 'wx',插件会配置 Vite,输出微信兼容的 CommonJS chunk 和小程序配套文件。
典型输出:
dist/wx/
├── app.js
├── app.json
├── app.wxss
├── base.wxml
├── comp.js
├── comp.json
├── comp.wxml
├── project.config.json
├── sitemap.json
├── utils.wxs
└── pages/**请使用微信开发者工具打开 dist/wx;不要打开源码项目目录。
H5
对于 target: 'h5',插件会向 index.html 注入生成模块,导入 Taro 的 H5 组件样式,根据 pages 构建路由记录,并使用 Taro 的 hash-history 路由挂载应用。路由使用配置中的页面路径,例如 #/pages/index/index。
从 Taro 迁移
你可以保留大多数 React 页面组件、业务逻辑、资源和样式,但构建入口会从 Taro CLI 配置迁移到 Vite 配置。
迁移清单:
- 安装
vite-plugin-taro,并创建包含vitePluginTaro(...)的vite.config.ts。 - 将应用配置和页面配置移到
vite.config.ts中。插件不会读取config/index.ts、app.config.ts或页面config.ts等 Taro 文件。 - 在
pages中注册每个页面。每个页面路径都必须匹配src/${path}.tsx。 - 将 Taro 脚本替换为设置
VITE_PLUGIN_TARO_TARGET=wx或VITE_PLUGIN_TARO_TARGET=h5的 Vite 脚本。 - 对于 H5,添加普通 Vite
index.html,其中包含<div id="app"></div>,且不要添加单独的src/main.tsx入口。 - 将应用代码中的
@tarojs/*导入替换为插件虚拟模块。
迁移前:
import Taro from '@tarojs/taro'
import { Text, View } from '@tarojs/components'迁移后:
import Taro from 'virtual:taro/api'
import { Text, View } from 'virtual:taro/components'应用代码中禁止直接导入 @tarojs/*。请让插件负责 Taro 运行时解析,使微信和 H5 构建都获得正确的目标特定别名。
示例应用
示例应用位于 packages/loan-genius。它展示了页面约定、目标选择、微信输出、H5 路由和 Tailwind 样式。
git clone https://github.com/sep2/vite-plugin-taro.git
# 安装依赖
pnpm install
# 首次运行,生成打过补丁的 Taro 包
pnpm prepare:taro
# 构建插件,供示例应用使用
pnpm build:plugin
# 运行微信示例应用
pnpm dev:sample:wx
# 将示例应用构建为微信输出
pnpm build:sample:wx
# 以开发模式运行 H5 示例应用
pnpm dev:sample:h5
# 将示例应用构建为 H5 输出并预览
pnpm build:sample:h5
pnpm preview:sample:h5使用微信开发者工具打开 packages/loan-genius/dist/wx,以测试小程序输出。
开发本仓库
pnpm install
pnpm prepare:taro
pnpm build:plugin
pnpm typecheck常用脚本:
| 脚本 | 描述 |
| --- | --- |
| pnpm prepare:taro | 从上游 npm tarball 和本地 patch 文件重新生成打过补丁的 React 19 Taro 包。 |
| pnpm build:plugin | 将 packages/vite-plugin-taro 构建到 dist。 |
| pnpm typecheck | 使用 tsgo 对插件和示例应用进行类型检查。 |
| pnpm lint | 运行 Biome 检查。 |
| pnpm format | 应用 Biome 格式化。 |
| pnpm dev:sample:wx | 以 watch 模式构建微信小程序示例。请先构建插件。 |
| pnpm dev:sample:h5 | 以 Vite 开发模式启动 H5 示例应用。请先构建插件。 |
| pnpm build:sample:wx | 将微信小程序示例构建到 packages/loan-genius/dist/wx。 |
| pnpm build:sample:h5 | 将 H5 示例应用构建到 packages/loan-genius/dist/h5。 |
| pnpm preview:sample:h5 | 预览构建后的 H5 示例。 |
| pnpm publish:dry | 干运行包校验和发布流程。 |
| pnpm release <version\|bump> | 验证发布、更新版本、创建 release commit 和 tag,并推送触发 CI 发布。 |
| pnpm publish:all | 按依赖顺序发布公开包;主要由基于 tag 的 Trusted Publishing 工作流调用。 |
限制
- 目前只生成
wx和h5目标。 - 应用代码不能直接导入
@tarojs/*包。
排查问题
| 问题 | 检查项 |
| --- | --- |
| VITE_PLUGIN_TARO_TARGET must be "wx" or "h5" | 在脚本或 .env 文件中设置目标环境变量。 |
| pnpm install 提示忽略了依赖构建脚本 | 运行 pnpm approve-builds,按提示批准需要构建的依赖。 |
| 页面无法解析 | 确认 pages[].path 有匹配的 src/${path}.tsx 文件。 |
| 微信开发者工具无法打开应用 | 打开生成的 dist/wx 文件夹,并检查 projectConfigJson.appid。 |
| H5 显示空白页 | 确保 index.html 中保留 <div id="app"></div>,已注册插件,并避免添加单独的默认 Vite main.tsx 入口。 |
| Taro API 缺失或行为不同 | 移除应用代码中直接导入的 @tarojs/*,并从 virtual:taro/api 导入 Taro。 |
| 组件在 H5 上渲染时缺少预期样式 | 从 virtual:taro/components 导入组件,并确保 h5 目标启用了插件。 |
| Tailwind 类没有生效 | 确保全局 CSS 导入 Tailwind,并包含覆盖源码文件的 @source 路径。 |
发布流程
本仓库使用 npm Trusted Publishing 和 GitHub Actions 自动发布。普通推送到 main 不会发布;只有推送匹配 v*.*.* 的 tag 才会触发 .github/workflows/publish.yml。
创建发布:
pnpm release patchpnpm release 会要求干净的 main 工作区,运行 pnpm version:bump,执行 pnpm publish:dry -- --no-git-check 验证,创建 chore: release vX.Y.Z commit 和 vX.Y.Z tag,然后推送 branch 与 tag 触发 CI。也可以发布精确版本或预发布版本:
pnpm release 0.2.0
pnpm release prerelease --preid beta
pnpm release patch --dry-run
pnpm release patch --no-pushCI 会运行 pnpm publish:all -- --no-git-check,按依赖顺序打包并通过 npm OIDC 发布公开包。不要为发布工作流配置 NPM_TOKEN;每个 npm 包的 Trusted Publisher 应指向 publish.yml。
许可证
MIT
