vite-plugin-taro 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.en.md ADDED
@@ -0,0 +1,457 @@
1
+ # vite-plugin-taro
2
+
3
+ [![npm version](https://img.shields.io/npm/v/vite-plugin-taro.svg)](https://www.npmjs.com/package/vite-plugin-taro)
4
+ [![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5
+
6
+ [简体中文](README.md) | English
7
+
8
+ Build WeChat Mini Apps with the latest standard frontend stack: Vite 8, React 19, and Tailwind CSS v4.
9
+
10
+ `vite-plugin-taro` is for applications that want Taro's cross-platform React components and APIs, but prefer Vite/Rolldown instead of Taro's webpack runner. The plugin generates app/page entries, target runtime aliases, H5 router bootstrap, WeChat companion files, Tailwind processing, and conditional compilation for you.
11
+
12
+ Live demo: <https://sep2.github.io/vite-plugin-taro>. See [Sample app](#sample-app) how to run it locally.
13
+
14
+ ## Install
15
+
16
+ ```sh
17
+ pnpm add -D vite-plugin-taro
18
+ ```
19
+
20
+ Your app must also provide Vite 8, React 19, React DOM 19, TypeScript, and React type packages. If your app does not already have them, install the missing packages:
21
+
22
+ ```sh
23
+ pnpm add react react-dom
24
+ pnpm add -D vite typescript @types/react @types/react-dom
25
+ ```
26
+
27
+ You should NOT have direct dependencies on `@tarojs/*` packages anymore. Remove them if you have.
28
+
29
+ ## Quick start
30
+
31
+ The examples below create this source shape:
32
+
33
+ ```text
34
+ my-app/
35
+ ├── index.html
36
+ ├── package.json
37
+ ├── tsconfig.json
38
+ ├── vite.config.ts
39
+ └── src/
40
+ ├── app.css
41
+ ├── app.ts
42
+ └── pages/
43
+ └── index/
44
+ └── index.tsx
45
+ ```
46
+
47
+ You can also see a sample layout at [packages/loan-genius](https://github.com/sep2/vite-plugin-taro/tree/main/packages/loan-genius).
48
+
49
+ ### 1. Add TypeScript declarations
50
+
51
+ Add the plugin client types to `tsconfig.json` so TypeScript knows about the virtual modules:
52
+
53
+ ```json
54
+ {
55
+ "compilerOptions": {
56
+ "jsx": "react-jsx",
57
+ "moduleResolution": "bundler",
58
+ "types": ["vite/client", "vite-plugin-taro/client"]
59
+ },
60
+ "include": ["src"]
61
+ }
62
+ ```
63
+
64
+ ### 2. Configure Vite
65
+
66
+ Create `vite.config.ts` and choose the plugin target from an environment variable:
67
+
68
+ ```ts
69
+ import { defineConfig, loadEnv } from 'vite'
70
+ import vitePluginTaro, { type VitePluginTaroTarget } from 'vite-plugin-taro'
71
+
72
+ const targetEnvName = 'VITE_PLUGIN_TARO_TARGET'
73
+
74
+ function getTarget(env: Record<string, string>): VitePluginTaroTarget {
75
+ const target = env[targetEnvName]
76
+ if (target === 'h5' || target === 'wx') return target
77
+ throw new Error(`${targetEnvName} must be "h5" or "wx".`)
78
+ }
79
+
80
+ export default defineConfig(({ mode }) => {
81
+ const env = loadEnv(mode, process.cwd(), 'VITE_PLUGIN_TARO_')
82
+ const target = getTarget(env)
83
+
84
+ return {
85
+ build: {
86
+ outDir: `dist/${target}`
87
+ },
88
+ plugins: [
89
+ vitePluginTaro({
90
+ target,
91
+ app: 'src/app.ts',
92
+ pages: [
93
+ {
94
+ path: 'pages/index/index',
95
+ config: {
96
+ navigationBarTitleText: 'Home'
97
+ }
98
+ }
99
+ ],
100
+ appJson: {
101
+ window: {
102
+ navigationBarTitleText: 'Demo',
103
+ navigationBarBackgroundColor: '#ffffff'
104
+ }
105
+ },
106
+ projectConfigJson: {
107
+ appid: env.VITE_PLUGIN_TARO_WECHAT_APP_ID || 'touristappid',
108
+ projectname: 'demo',
109
+ compileType: 'miniprogram'
110
+ },
111
+ sitemapJson: {
112
+ rules: [{ action: 'allow', page: '*' }]
113
+ }
114
+ })
115
+ ]
116
+ }
117
+ })
118
+ ```
119
+
120
+ Important conventions:
121
+
122
+ - `target` must be `h5` or `wx` for each Vite run.
123
+ - `app` is the root React app component module. It should default-export the app component.
124
+ - Every `pages[].path` maps to a file at `src/${path}.tsx`. For example, `pages/index/index` requires `src/pages/index/index.tsx`.
125
+ - `appJson.pages` is generated from `pages`; any `pages` field you put in `appJson` is overwritten.
126
+ - The plugin does not read Taro CLI config files such as `config/index.ts`, `app.config.ts`, or page `config.ts` files. Pass app and page config through the plugin options.
127
+
128
+ ### 3. Create the app component
129
+
130
+ `src/app.ts` is the shared application wrapper. It receives the current page as `children`.
131
+
132
+ ```tsx
133
+ import Taro from 'virtual:taro/api'
134
+ import type { PropsWithChildren } from 'react'
135
+ import './app.css'
136
+
137
+ function App({ children }: PropsWithChildren) {
138
+ Taro.useLaunch(() => {
139
+ console.log('App launched')
140
+ })
141
+
142
+ return children
143
+ }
144
+
145
+ export default App
146
+ ```
147
+
148
+ Import global styles from the app component. They are included in H5 output and collected into `app.wxss` for WeChat builds.
149
+
150
+ ### 4. Create a page component
151
+
152
+ `src/pages/index/index.tsx` is the React component for `pages/index/index`.
153
+
154
+ ```tsx
155
+ import { Button, Text, View } from 'virtual:taro/components'
156
+ import Taro from 'virtual:taro/api'
157
+
158
+ export default function IndexPage() {
159
+ const windowInfo = Taro.getWindowInfo()
160
+
161
+ return (
162
+ <View className="p-4">
163
+ <Text>Viewport width: {windowInfo.windowWidth}</Text>
164
+ <Button
165
+ onClick={() => {
166
+ Taro.showToast({ title: 'Hello from Taro' })
167
+ }}
168
+ >
169
+ Show toast
170
+ </Button>
171
+ </View>
172
+ )
173
+ }
174
+ ```
175
+
176
+ Use these imports in app code:
177
+
178
+ | Import | Use |
179
+ | --- | --- |
180
+ | `virtual:taro/components` | Taro React components such as `View`, `Text`, `Button`, `Image`, and `ScrollView`. |
181
+ | `virtual:taro/api` | Taro APIs and hooks such as `Taro.navigateTo`, `Taro.getWindowInfo`, and `Taro.useLaunch`. |
182
+
183
+ Do not import `@tarojs/*` packages directly in application code. Direct `@tarojs/*` usage is forbidden and unsupported by this plugin because it can bypass target-specific runtime aliases and H5 API transforms. Use `virtual:taro/api` and `virtual:taro/components` only.
184
+
185
+ ### 5. Add the H5 HTML shell
186
+
187
+ For H5, keep a normal Vite `index.html` with an `#app` mount node. The plugin injects the generated Taro H5 entry automatically, so you do not need a normal Vite `src/main.tsx` script.
188
+
189
+ ```html
190
+ <!doctype html>
191
+ <html lang="en">
192
+ <head>
193
+ <meta charset="UTF-8" />
194
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
195
+ <title>Taro Vite App</title>
196
+ </head>
197
+ <body>
198
+ <div id="app"></div>
199
+ </body>
200
+ </html>
201
+ ```
202
+
203
+ ### 6. Add scripts
204
+
205
+ ```json
206
+ {
207
+ "scripts": {
208
+ "dev:h5": "NODE_ENV=development VITE_PLUGIN_TARO_TARGET=h5 vite",
209
+ "build:h5": "NODE_ENV=production VITE_PLUGIN_TARO_TARGET=h5 vite build",
210
+ "dev:wx": "NODE_ENV=development VITE_PLUGIN_TARO_TARGET=wx vite build --watch",
211
+ "build:wx": "NODE_ENV=production VITE_PLUGIN_TARO_TARGET=wx vite build"
212
+ }
213
+ }
214
+ ```
215
+
216
+ On Windows shells, use `cross-env`.
217
+
218
+ ### 7. Run each target
219
+
220
+ ```sh
221
+ pnpm dev:h5 # Start the H5 dev server
222
+ pnpm build:h5 # Build dist/h5
223
+ pnpm build:wx # Build dist/wx
224
+ pnpm dev:wx # Rebuild dist/wx in watch mode
225
+ ```
226
+
227
+ Open the generated `dist/wx` directory in WeChat DevTools.
228
+
229
+ | Target | Meaning | output dirs |
230
+ | --- |--------------------------------------------|-------------|
231
+ | `h5` | H5 production output. | `dist/h5` |
232
+ | `wx` | WeChat Mini Program in both dev/prod mode. | `dist/wx` |
233
+
234
+ ## Options
235
+
236
+ ```ts
237
+ type VitePluginTaroTarget = 'wx' | 'h5'
238
+
239
+ type VitePluginTaroPageOption = {
240
+ path: string
241
+ config: Record<string, unknown>
242
+ }
243
+
244
+ type VitePluginTaroOptions = {
245
+ target: VitePluginTaroTarget
246
+ app: string
247
+ pages: VitePluginTaroPageOption[]
248
+ appJson: Record<string, unknown>
249
+ projectConfigJson: Record<string, unknown>
250
+ sitemapJson: Record<string, unknown>
251
+ }
252
+ ```
253
+
254
+ | Option | Description |
255
+ | --- | --- |
256
+ | `target` | Active target for this Vite invocation. Use `h5` for Web and `wx` for WeChat Mini Program. |
257
+ | `app` | Source file that default-exports the root React app component, for example `src/app.ts` or `src/app.tsx`. |
258
+ | `pages` | Ordered page list. The order becomes `app.json.pages` and the H5 route order. |
259
+ | `pages[].path` | Taro-style route and output path without extension, for example `pages/index/index`. The page component must exist at `src/${path}.tsx`. |
260
+ | `pages[].config` | Page config merged into the generated WeChat page JSON and H5 route config. |
261
+ | `appJson` | Base app config. The plugin overwrites the `pages` field from `options.pages`. |
262
+ | `projectConfigJson` | WeChat `project.config.json` content emitted for `wx` builds. It is required by the option type even when the current target is `h5`. |
263
+ | `sitemapJson` | WeChat `sitemap.json` content emitted for `wx` builds. It is required by the option type even when the current target is `h5`. |
264
+
265
+ ## Styling
266
+
267
+ You can use plain CSS, CSS modules, or Tailwind CSS v4.
268
+
269
+ For Tailwind CSS v4, import Tailwind from a global CSS file such as `src/app.css`:
270
+
271
+ ```css
272
+ @import "tailwindcss/theme.css";
273
+ @import "tailwindcss/preflight.css";
274
+ @import "tailwindcss/utilities.css";
275
+
276
+ @source "./";
277
+ ```
278
+
279
+ The plugin registers `@tailwindcss/vite` for `h5` builds and `weapp-tailwindcss` for `wx` builds. For `wx`, CSS emitted by Vite is collected into `app.wxss`, and page `.wxss` companion files are emitted for each page.
280
+
281
+ ## Conditional compilation
282
+
283
+ The plugin strips inactive Taro-style conditional comment blocks before Vite parses source. This works in TypeScript, JavaScript, JSX/TSX, CSS, Sass, Less, and Stylus files outside `node_modules`.
284
+
285
+ ```ts
286
+ // #ifdef wx
287
+ console.log('WeChat only')
288
+ // #endif
289
+
290
+ // #ifdef h5
291
+ console.log('H5 only')
292
+ // #endif
293
+
294
+ // #if h5 && !wx
295
+ console.log('H5 expression')
296
+ // #elif wx
297
+ console.log('WeChat expression')
298
+ // #else
299
+ console.log('fallback')
300
+ // #endif
301
+ ```
302
+
303
+ Supported directives are `#ifdef`, `#ifndef`, `#if`, `#elif`, `#else`, and `#endif`. Conditions use the plugin target tokens `h5` and `wx`; `#if` expressions support `!`, `&&`, and `||`.
304
+
305
+ ## Output by target
306
+
307
+ ### H5
308
+
309
+ For `target: 'h5'`, the plugin injects a generated module into `index.html`, imports Taro's H5 component styles, builds route records from `pages`, and mounts the app with Taro's hash-history router. Routes use the page paths from your config, for example `#/pages/index/index`.
310
+
311
+ ### WeChat Mini Program
312
+
313
+ For `target: 'wx'`, the plugin configures Vite/Rolldown to emit WeChat-compatible CommonJS chunks and Mini Program companion files.
314
+
315
+ Typical output:
316
+
317
+ ```text
318
+ dist/wx/
319
+ ├── app.js
320
+ ├── app.json
321
+ ├── app.wxss
322
+ ├── base.wxml
323
+ ├── comp.js
324
+ ├── comp.json
325
+ ├── comp.wxml
326
+ ├── project.config.json
327
+ ├── sitemap.json
328
+ ├── utils.wxs
329
+ └── pages/**
330
+ ```
331
+
332
+ Open `dist/wx` with WeChat DevTools; do not open the source project directory.
333
+
334
+ ## Migrating from Taro
335
+
336
+ You can keep most React page components, business logic, assets, and styles, but the build entry moves from Taro CLI config to Vite config.
337
+
338
+ Migration checklist:
339
+
340
+ 1. Install `vite-plugin-taro` and create `vite.config.ts` with `vitePluginTaro(...)`.
341
+ 2. Move app config and page config into the plugin options. The plugin does not read Taro CLI files such as `config/index.ts`, `app.config.ts`, or page `config.ts` files.
342
+ 3. Register every page in `pages`. Each page path must match `src/${path}.tsx`.
343
+ 4. Replace Taro scripts with Vite scripts that set `VITE_PLUGIN_TARO_TARGET=h5` or `VITE_PLUGIN_TARO_TARGET=wx`.
344
+ 5. For H5, add a normal Vite `index.html` with `<div id="app"></div>` and no separate `src/main.tsx` entry.
345
+ 6. Replace application imports from `@tarojs/*` with the plugin virtual modules.
346
+
347
+ Before:
348
+
349
+ ```tsx
350
+ import Taro from '@tarojs/taro'
351
+ import { Text, View } from '@tarojs/components'
352
+ ```
353
+
354
+ After:
355
+
356
+ ```tsx
357
+ import Taro from 'virtual:taro/api'
358
+ import { Text, View } from 'virtual:taro/components'
359
+ ```
360
+
361
+ Direct `@tarojs/*` imports in application code are forbidden. Let the plugin own Taro runtime resolution so H5 and WeChat builds receive the correct target-specific aliases.
362
+
363
+ ## Sample app
364
+
365
+ The sample app lives in [`packages/loan-genius`](https://github.com/sep2/vite-plugin-taro/tree/main/packages/loan-genius). It demonstrates the page convention, target selection, H5 routing, Tailwind styling, and WeChat output.
366
+
367
+ ```sh
368
+ git clone https://github.com/sep2/vite-plugin-taro.git
369
+
370
+ # Install dependencies
371
+ pnpm install
372
+
373
+ # Run once, it generates the patched Taro packages
374
+ pnpm prepare:taro
375
+
376
+ # Build the plugin for sample app to use
377
+ pnpm build:plugin
378
+
379
+ # Run the sample app in H5 in Dev mode
380
+ pnpm dev:sample:h5
381
+
382
+ # Build the sample app to H5 output and preview it
383
+ pnpm build:sample:h5
384
+ pnpm preview:sample:h5
385
+
386
+ # Run the sample app in WeChat
387
+ pnpm dev:sample:wx
388
+
389
+ # Build the sample app to WeChat output
390
+ pnpm build:sample:wx
391
+ ```
392
+
393
+ Open `packages/loan-genius/dist/wx` with WeChat DevTools to test the Mini Program output.
394
+
395
+
396
+ ## Develop this repository
397
+
398
+ ```sh
399
+ pnpm install
400
+ pnpm prepare:taro
401
+ pnpm build:plugin
402
+ pnpm typecheck
403
+ ```
404
+
405
+ Common scripts:
406
+
407
+ | Script | Description |
408
+ | --- | --- |
409
+ | `pnpm prepare:taro` | Regenerate the patched React 19 Taro packages from upstream npm tarballs and local patch files. |
410
+ | `pnpm build:plugin` | Build `packages/vite-plugin-taro` into `dist`. |
411
+ | `pnpm typecheck` | Typecheck the plugin and sample app with `tsgo`. |
412
+ | `pnpm lint` | Run Biome checks. |
413
+ | `pnpm format` | Apply Biome formatting. |
414
+ | `pnpm dev:sample:h5` | Start the sample H5 app in Vite dev mode. Build the plugin first. |
415
+ | `pnpm dev:sample:wx` | Build the sample WeChat Mini Program in watch mode. Build the plugin first. |
416
+ | `pnpm build:sample:h5` | Build the sample H5 app to `packages/loan-genius/dist/h5`. |
417
+ | `pnpm preview:sample:h5` | Preview the built H5 sample. |
418
+ | `pnpm build:sample:wx` | Build the sample WeChat Mini Program to `packages/loan-genius/dist/wx`. |
419
+ | `pnpm publish:dry` | Dry-run package validation and publishing. |
420
+ | `pnpm publish:all` | Publish the public packages in dependency order. |
421
+
422
+ ## Limitations
423
+
424
+ - Only `h5` and `wx` targets are generated today.
425
+ - Application code must not import `@tarojs/*` packages directly.
426
+
427
+
428
+ ## Troubleshooting
429
+
430
+ | Problem | Check |
431
+ | --- | --- |
432
+ | `VITE_PLUGIN_TARO_TARGET must be "h5" or "wx"` | Set the target environment variable in your script or `.env` file. |
433
+ | A page cannot be resolved | Confirm that `pages[].path` has a matching `src/${path}.tsx` file. |
434
+ | H5 shows a blank page | Keep `<div id="app"></div>` in `index.html`, register the plugin, and avoid adding a separate default Vite `main.tsx` entry. |
435
+ | Taro APIs are missing or behave differently | Remove direct `@tarojs/*` imports from application code and import Taro from `virtual:taro/api`. |
436
+ | Components render without expected styles on H5 | Import components from `virtual:taro/components` and keep the plugin enabled for the `h5` target. |
437
+ | WeChat DevTools cannot open the app | Open the generated `dist/wx` folder and check `projectConfigJson.appid`. |
438
+ | Tailwind classes do not appear | Ensure your global CSS imports Tailwind and includes an `@source` path that covers your source files. |
439
+
440
+ ## Release workflow
441
+
442
+ Validate the publishable packages before publishing:
443
+
444
+ ```sh
445
+ pnpm publish:dry
446
+ ```
447
+
448
+ Publish all public packages in the required order:
449
+
450
+ ```sh
451
+ pnpm publish:all
452
+ ```
453
+
454
+
455
+ ## License
456
+
457
+ MIT