vite-plugin-taro 0.0.1

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/dist/vite.js ADDED
@@ -0,0 +1,851 @@
1
+ import path from "node:path";
2
+ import process$1 from "node:process";
3
+ import { WeappTailwindcss } from "weapp-tailwindcss/vite";
4
+ import babel from "@rolldown/plugin-babel";
5
+ import react from "@vitejs/plugin-react";
6
+ import { createRequire } from "node:module";
7
+ import { recursiveMerge } from "@tarojs/helper";
8
+ import { Weapp } from "@tarojs/plugin-platform-weapp";
9
+ //#region src/vite/utils.ts
10
+ /**
11
+ * Derives a page component import from a Taro-style page path.
12
+ *
13
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/MiniPlugin.ts#L660-L668
14
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/utils/app.ts#L74-L90
15
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-loader/src/h5.ts#L12-L21
16
+ */
17
+ function createPageComponentImport(pagePath) {
18
+ return toImportPath(`src/${pagePath}.tsx`);
19
+ }
20
+ /**
21
+ * Converts a local file path into an absolute ESM import path for Vite.
22
+ */
23
+ function toImportPath(filePath) {
24
+ return path.resolve(filePath);
25
+ }
26
+ /**
27
+ * Removes Rollup/Vite's internal virtual-module prefix before ID comparisons.
28
+ */
29
+ function stripVirtualPrefix(id) {
30
+ return id.startsWith("\0") ? id.slice(1) : id;
31
+ }
32
+ /**
33
+ * Uses Taro-style slash normalization, plus Vite query-string stripping for module IDs.
34
+ *
35
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-helper/src/utils.ts#L32-L34
36
+ */
37
+ function normalizeModuleId(id) {
38
+ return id.replace(/\\/g, "/").replace(/\?.*$/, "");
39
+ }
40
+ //#endregion
41
+ //#region src/vite/plugins.ts
42
+ /**
43
+ * Applies Taro-style conditional compilation comments before Vite parses source files.
44
+ *
45
+ * Mirrors Taro's CSS #ifdef/#ifndef handling, generalized before Vite parses code.
46
+ */
47
+ function createTaroConditionalDirectivePlugin(context) {
48
+ const target = context.target;
49
+ return {
50
+ name: "vite-plugin-taro-conditional-directives",
51
+ enforce: "pre",
52
+ transform(code, id) {
53
+ if (!isConditionalDirectiveSource(id) || !code.includes("#if")) return;
54
+ return {
55
+ code: transformConditionalDirectives(code, target),
56
+ map: null
57
+ };
58
+ }
59
+ };
60
+ }
61
+ /**
62
+ * Filters files where Taro's conditional comments are meaningful.
63
+ *
64
+ * vite-plugin-taro-only: source filter for vite-plugin-taro's generalized conditional-directive transform.
65
+ */
66
+ function isConditionalDirectiveSource(id) {
67
+ const normalizedId = normalizeModuleId(id);
68
+ if (normalizedId.includes("/node_modules/")) return false;
69
+ return /\.(?:[cm]?[jt]sx?|css|s[ac]ss|less|styl)(?:\?|$)/.test(normalizedId);
70
+ }
71
+ /**
72
+ * Removes inactive blocks guarded by Taro conditional comments.
73
+ *
74
+ * Mirrors Taro's CSS #ifdef/#ifndef handling.
75
+ */
76
+ function transformConditionalDirectives(code, target) {
77
+ const lines = code.match(/[^\n]*(?:\n|$)/g) ?? [];
78
+ const frames = [];
79
+ let transformed = "";
80
+ for (const line of lines) {
81
+ if (!line) continue;
82
+ const directive = parseConditionalDirective(line);
83
+ const lineEnding = getLineEnding(line);
84
+ if (directive) {
85
+ updateConditionalDirectiveFrames(frames, directive, target);
86
+ transformed += lineEnding;
87
+ continue;
88
+ }
89
+ transformed += isDirectiveStackActive(frames) ? line : lineEnding;
90
+ }
91
+ return transformed;
92
+ }
93
+ /**
94
+ * Parses one Taro conditional compilation directive from a comment-only line.
95
+ *
96
+ * Mirrors Taro's CSS comment-token handling.
97
+ */
98
+ function parseConditionalDirective(line) {
99
+ const match = line.match(/^\s*(?:(?:\/\/)|(?:\/\*))\s*#(ifdef|ifndef|if|elif|else|endif)\b([^*\r\n]*)/);
100
+ if (!match) return;
101
+ const name = toConditionalDirectiveName(match[1]);
102
+ if (!name) return;
103
+ return {
104
+ name,
105
+ expression: match[2]?.replace(/\*\/$/, "").trim() ?? ""
106
+ };
107
+ }
108
+ /**
109
+ * Converts a regex capture into a supported directive name.
110
+ *
111
+ * Mirrors Taro's CSS #ifdef/#ifndef/#endif token handling.
112
+ */
113
+ function toConditionalDirectiveName(value) {
114
+ if (value === "ifdef" || value === "ifndef" || value === "if" || value === "elif" || value === "else" || value === "endif") return value;
115
+ }
116
+ /**
117
+ * Updates the active conditional stack using Taro-style #ifdef/#ifndef/#else/#endif semantics.
118
+ *
119
+ * vite-plugin-taro-only: stack-based #if/#elif/#else support has no Taro webpack counterpart.
120
+ */
121
+ function updateConditionalDirectiveFrames(frames, directive, target) {
122
+ if (directive.name === "ifdef" || directive.name === "ifndef" || directive.name === "if") {
123
+ const conditionMatched = evaluateConditionalDirective(directive, target);
124
+ const parentActive = isDirectiveStackActive(frames);
125
+ frames.push({
126
+ parentActive,
127
+ active: parentActive && conditionMatched,
128
+ matched: conditionMatched
129
+ });
130
+ return;
131
+ }
132
+ const currentFrame = frames.at(-1);
133
+ if (!currentFrame) return;
134
+ if (directive.name === "elif") {
135
+ if (currentFrame.matched) {
136
+ currentFrame.active = false;
137
+ return;
138
+ }
139
+ const conditionMatched = evaluateConditionalDirective(directive, target);
140
+ currentFrame.active = currentFrame.parentActive && conditionMatched;
141
+ currentFrame.matched = conditionMatched;
142
+ return;
143
+ }
144
+ if (directive.name === "else") {
145
+ currentFrame.active = currentFrame.parentActive && !currentFrame.matched;
146
+ currentFrame.matched = true;
147
+ return;
148
+ }
149
+ if (directive.name === "endif") frames.pop();
150
+ }
151
+ /**
152
+ * Evaluates the small expression subset used by Taro conditional comments.
153
+ *
154
+ * Mirrors Taro's simple CSS platform membership checks.
155
+ */
156
+ function evaluateConditionalDirective(directive, target) {
157
+ if (directive.name === "ifndef") return !matchesDirectiveTarget(directive.expression, target);
158
+ if (directive.name === "ifdef") return matchesDirectiveTarget(directive.expression, target);
159
+ return evaluateConditionalExpression(directive.expression, target);
160
+ }
161
+ /**
162
+ * Supports simple #if expressions with !, &&, and || over vite-plugin-taro target tokens.
163
+ *
164
+ * vite-plugin-taro-only: #if expressions with && and || have no Taro webpack counterpart.
165
+ */
166
+ function evaluateConditionalExpression(expression, target) {
167
+ return expression.split("||").some((term) => term.split("&&").map((factor) => factor.trim()).filter(Boolean).every((factor) => evaluateConditionalFactor(factor, target)));
168
+ }
169
+ /**
170
+ * Evaluates one vite-plugin-taro target token, optionally negated.
171
+ *
172
+ * vite-plugin-taro-only: negated #if factors have no Taro webpack counterpart.
173
+ */
174
+ function evaluateConditionalFactor(factor, target) {
175
+ let token = factor.replace(/[()]/g, "").trim();
176
+ let negated = false;
177
+ while (token.startsWith("!")) {
178
+ negated = !negated;
179
+ token = token.slice(1).trim();
180
+ }
181
+ const matched = matchesDirectiveTarget(token, target);
182
+ return negated ? !matched : matched;
183
+ }
184
+ /**
185
+ * Checks whether a directive target list includes the current vite-plugin-taro target.
186
+ *
187
+ * Mirrors Taro's simple CSS platform membership checks.
188
+ */
189
+ function matchesDirectiveTarget(expression, target) {
190
+ return expression.split(/[\s,|&()!]+/).map((token) => token.trim().toLowerCase()).filter(Boolean).includes(target);
191
+ }
192
+ /**
193
+ * Preserves source line counts when conditional blocks are stripped.
194
+ *
195
+ * vite-plugin-taro-only: preserves Vite source-map line counts while stripping conditional blocks.
196
+ */
197
+ function getLineEnding(line) {
198
+ return line.match(/\r?\n$/)?.[0] ?? "";
199
+ }
200
+ /**
201
+ * Returns whether all active nested conditional frames include the current line.
202
+ *
203
+ * vite-plugin-taro-only: stack activity helper for generalized conditional directives.
204
+ */
205
+ function isDirectiveStackActive(frames) {
206
+ return frames.every((frame) => frame.active);
207
+ }
208
+ //#endregion
209
+ //#region src/vite/tailwindcss.ts
210
+ function getProjectRoot() {
211
+ return process$1.cwd();
212
+ }
213
+ function getAppCssEntry(projectRoot) {
214
+ return path.resolve(projectRoot, "src/app.css");
215
+ }
216
+ function createTailwindcssPlugins(context) {
217
+ const projectRoot = getProjectRoot();
218
+ const appCssEntry = getAppCssEntry(projectRoot);
219
+ return WeappTailwindcss({
220
+ appType: "taro",
221
+ generator: { target: context.target === "h5" ? "web" : "weapp" },
222
+ tailwindcssBasedir: projectRoot,
223
+ cssEntries: [appCssEntry],
224
+ tailwindcss: {
225
+ version: 4,
226
+ packageName: "tailwindcss"
227
+ },
228
+ cssCalc: false,
229
+ autoprefixer: context.target === "h5",
230
+ postcssOptions: { plugins: [createWechatPseudoElementPlugin()] },
231
+ rem2rpx: true,
232
+ px2rpx: true
233
+ }) ?? [];
234
+ }
235
+ function createWechatPseudoElementPlugin() {
236
+ const legacyPseudoElementPattern = /(?<!:):(before|after)\b/g;
237
+ return {
238
+ postcssPlugin: "vite-plugin-taro-wechat-pseudo-elements",
239
+ Rule(rule) {
240
+ rule.selector = rule.selector.replace(legacyPseudoElementPattern, "::$1");
241
+ }
242
+ };
243
+ }
244
+ //#endregion
245
+ //#region src/vite/constants.ts
246
+ var isProd = process.env.NODE_ENV === "production";
247
+ var nodeRequire = createRequire(import.meta.url);
248
+ //#endregion
249
+ //#region src/vite/targets/h5.ts
250
+ var virtualH5Id = "virtual:vite-plugin-taro/h5";
251
+ var pluginTaroImport = "vite-plugin-taro/taro";
252
+ /**
253
+ * Checks whether an id belongs to an H5 virtual module.
254
+ */
255
+ function isH5VirtualModuleId(id) {
256
+ return id === virtualH5Id;
257
+ }
258
+ /**
259
+ * Loads generated source for H5 virtual modules.
260
+ */
261
+ function loadH5VirtualModule(cleanId, context) {
262
+ if (cleanId !== virtualH5Id) return;
263
+ return createWebEntry(context);
264
+ }
265
+ /**
266
+ * Configures the Vite pieces needed for Taro H5 resolve/runtime behavior.
267
+ */
268
+ function createH5ViteConfig() {
269
+ return {
270
+ define: createH5TaroDefines(),
271
+ resolve: {
272
+ mainFields: [
273
+ "main:h5",
274
+ "browser",
275
+ "module",
276
+ "jsnext:main",
277
+ "jsnext"
278
+ ],
279
+ alias: [
280
+ {
281
+ find: /^@tarojs\/components$/,
282
+ replacement: nodeRequire.resolve("@tarojs/components/lib/react")
283
+ },
284
+ {
285
+ find: /^@tarojs\/components\/dist\/components$/,
286
+ replacement: nodeRequire.resolve("@tarojs/components/dist/components")
287
+ },
288
+ {
289
+ find: /^@tarojs\/taro$/,
290
+ replacement: nodeRequire.resolve("@tarojs/plugin-platform-h5/dist/runtime/apis")
291
+ }
292
+ ]
293
+ },
294
+ build: {
295
+ target: "es2018",
296
+ minify: isProd
297
+ }
298
+ };
299
+ }
300
+ /**
301
+ * Creates H5-only support plugins used before the target emitter runs.
302
+ *
303
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-platform-h5/src/program.ts#L219-L249
304
+ */
305
+ function createH5SupportPlugins() {
306
+ return [...react(), babel({ plugins: [[nodeRequire.resolve("babel-plugin-transform-taroapi"), {
307
+ packageName: pluginTaroImport,
308
+ definition: nodeRequire(nodeRequire.resolve("@tarojs/plugin-platform-h5/dist/definition.json"))
309
+ }]] })];
310
+ }
311
+ /**
312
+ * Creates compile-time constants expected by Taro's Web runtime packages.
313
+ *
314
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/webpack/H5WebpackPlugin.ts#L51-L69
315
+ */
316
+ function createH5TaroDefines() {
317
+ return {
318
+ "process.env.FRAMEWORK": JSON.stringify("react"),
319
+ "process.env.SUPPORT_TARO_POLYFILL": JSON.stringify("disabled"),
320
+ "process.env.TARO_ENV": JSON.stringify("h5"),
321
+ "process.env.TARO_PLATFORM": JSON.stringify("web"),
322
+ IS_H5: "true",
323
+ IS_WEAPP: "false",
324
+ "process.env.SUPPORT_DINGTALK_NAVIGATE": JSON.stringify("disabled"),
325
+ DEPRECATED_ADAPTER_COMPONENT: "false"
326
+ };
327
+ }
328
+ /**
329
+ * Injects vite-plugin-taro's generated Web entry into Vite's HTML shell.
330
+ */
331
+ function createWebIndexHtmlTags(context) {
332
+ if (context.target !== "h5") return;
333
+ const tags = [];
334
+ tags.push({
335
+ tag: "script",
336
+ attrs: { type: "module" },
337
+ children: `import '${virtualH5Id}'`,
338
+ injectTo: "body"
339
+ });
340
+ return tags;
341
+ }
342
+ /**
343
+ * Builds the generated Web entry around Taro's official Web router/runtime APIs.
344
+ * vite-plugin-taro omits Taro's generated pxTransform initialization because styles are handled by Tailwind.
345
+ *
346
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-loader/src/h5.ts#L120-L150
347
+ */
348
+ function createWebEntry(context) {
349
+ const webAppConfigCode = JSON.stringify(createWebAppConfig(context.appConfig));
350
+ const webRoutesConfigCode = createWebRoutesConfig(context.pages);
351
+ return `import {
352
+ createHashHistory,
353
+ createReactApp,
354
+ createRouter,
355
+ handleAppMount,
356
+ window
357
+ } from 'vite-plugin-taro/shim/h5'
358
+ import React from 'react'
359
+ import ReactDOM from 'react-dom/client'
360
+ import AppComponent from '${context.appComponentImport}'
361
+
362
+ const config = window.__taroAppConfig = ${webAppConfigCode}
363
+ config.routes = ${webRoutesConfigCode}
364
+ const app = createReactApp(AppComponent, React, ReactDOM, config)
365
+ const history = createHashHistory({ window })
366
+ handleAppMount(config, history)
367
+ createRouter(history, app, config, React)
368
+ `;
369
+ }
370
+ /**
371
+ * Creates the H5 app config consumed by Taro's Web router.
372
+ * Taro's H5 runtime expects `config.router` to exist, even when it is an empty object.
373
+ *
374
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/H5Plugin.ts#L49-L53
375
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/H5Plugin.ts#L133-L138
376
+ */
377
+ function createWebAppConfig(sharedAppConfig) {
378
+ return {
379
+ router: {},
380
+ ...sharedAppConfig
381
+ };
382
+ }
383
+ /**
384
+ * Creates Web route records in the same shape as Taro's H5 loader.
385
+ *
386
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-loader/src/h5.ts#L12-L21
387
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-loader/src/h5.ts#L108-L114
388
+ */
389
+ function createWebRoutesConfig(webPages) {
390
+ return `[\n${webPages.map((page) => [
391
+ "Object.assign({",
392
+ ` path: ${JSON.stringify(page.path)},`,
393
+ " load: async function(context, params) {",
394
+ ` const page = await import(${JSON.stringify(createPageComponentImport(page.path))})`,
395
+ " return [page, context, params]",
396
+ " }",
397
+ `}, ${JSON.stringify(page.config)})`
398
+ ].join("\n")).join(",\n")}\n]`;
399
+ }
400
+ //#endregion
401
+ //#region src/vite/targets/wx.ts
402
+ var virtualWxAppId = "virtual:vite-plugin-taro/wx/app";
403
+ var virtualWxCompId = "virtual:vite-plugin-taro/wx/comp";
404
+ var virtualWxPagePrefix = "virtual:vite-plugin-taro/wx/page/";
405
+ /**
406
+ * Checks whether an id belongs to a wx virtual module.
407
+ */
408
+ function isWxVirtualModuleId(id) {
409
+ return id === virtualWxAppId || id === virtualWxCompId || id.startsWith(virtualWxPagePrefix);
410
+ }
411
+ function loadWxVirtualModule(cleanId, context) {
412
+ if (cleanId === virtualWxAppId) return createWxAppEntry(context);
413
+ if (cleanId === virtualWxCompId) return createWxCompEntry();
414
+ if (!cleanId.startsWith(virtualWxPagePrefix)) return;
415
+ const pagePath = cleanId.slice(33);
416
+ const page = context.pages.find((candidate) => candidate.path === pagePath);
417
+ if (page) return createWxPageEntry(page);
418
+ }
419
+ var taroWechatComponentsReactPath = nodeRequire.resolve("@tarojs/plugin-platform-weapp/dist/components-react");
420
+ var pluginSourcePath = normalizeModuleId(path.dirname(nodeRequire.resolve("vite-plugin-taro/vite")));
421
+ var taroVersion = String(nodeRequire("@tarojs/runtime/package.json").version);
422
+ /**
423
+ * Configures wx target entry, output, and chunk layout.
424
+ */
425
+ function createWxViteConfig(context) {
426
+ return {
427
+ define: createWechatTaroDefines(),
428
+ resolve: { alias: [{
429
+ find: /^@tarojs\/components$/,
430
+ replacement: taroWechatComponentsReactPath
431
+ }] },
432
+ build: {
433
+ target: "es2018",
434
+ assetsInlineLimit: 1024,
435
+ cssCodeSplit: false,
436
+ minify: isProd,
437
+ rolldownOptions: {
438
+ input: { app: virtualWxAppId },
439
+ experimental: { attachDebugInfo: "none" },
440
+ output: {
441
+ format: "cjs",
442
+ entryFileNames: "[name].js",
443
+ assetFileNames: "assets/[name][extname]",
444
+ chunkFileNames: createWechatChunkFileName,
445
+ strictExecutionOrder: true,
446
+ codeSplitting: {
447
+ includeDependenciesRecursively: false,
448
+ minSize: 0,
449
+ groups: [
450
+ {
451
+ name: "taro",
452
+ test: isWxTaroChunkModule,
453
+ priority: 100
454
+ },
455
+ {
456
+ name: "vendors",
457
+ test: isNodeModule,
458
+ priority: 10
459
+ },
460
+ {
461
+ name: "common",
462
+ minShareCount: 2,
463
+ minModuleSize: 1,
464
+ priority: 1
465
+ }
466
+ ]
467
+ }
468
+ }
469
+ }
470
+ }
471
+ };
472
+ }
473
+ /**
474
+ * Creates compile-time constants expected by Taro's WeChat runtime packages.
475
+ *
476
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/webpack/MiniWebpackPlugin.ts#L67-L94
477
+ */
478
+ function createWechatTaroDefines() {
479
+ return {
480
+ "process.env.FRAMEWORK": JSON.stringify("react"),
481
+ "process.env.SUPPORT_TARO_POLYFILL": JSON.stringify("disabled"),
482
+ "process.env.TARO_ENV": JSON.stringify("weapp"),
483
+ "process.env.TARO_PLATFORM": JSON.stringify("mini"),
484
+ "process.env.TARO_VERSION": JSON.stringify(taroVersion),
485
+ IS_H5: "false",
486
+ IS_WEAPP: "true",
487
+ ENABLE_ADJACENT_HTML: "false",
488
+ ENABLE_CLONE_NODE: "false",
489
+ ENABLE_CONTAINS: "false",
490
+ ENABLE_INNER_HTML: "false",
491
+ ENABLE_MUTATION_OBSERVER: "false",
492
+ ENABLE_SIZE_APIS: "false",
493
+ ENABLE_TEMPLATE_CONTENT: "false"
494
+ };
495
+ }
496
+ /**
497
+ * Checks whether a module should live in the Taro/framework base chunk.
498
+ * vite-plugin-taro support modules are kept with Taro so pages do not duplicate runtime facades.
499
+ *
500
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/webpack/MiniCombination.ts#L141-L144
501
+ */
502
+ function isWxTaroChunkModule(id) {
503
+ const normalizedId = normalizeModuleId(id);
504
+ return normalizedId.includes("/node_modules/@tarojs/") || normalizedId.startsWith(`${pluginSourcePath}/`);
505
+ }
506
+ /**
507
+ * Names Rolldown's helper chunk like Taro webpack's runtime chunk.
508
+ *
509
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/webpack/MiniCombination.ts#L96-L103
510
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/webpack/MiniCombination.ts#L115-L117
511
+ */
512
+ function createWechatChunkFileName(chunkInfo) {
513
+ return `${chunkInfo.name === "rolldown-runtime" ? "runtime" : chunkInfo.name}.js`;
514
+ }
515
+ /**
516
+ * Checks whether a module is a third-party dependency chunk candidate.
517
+ *
518
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/webpack/MiniCombination.ts#L132-L139
519
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-helper/src/utils.ts#L32-L36
520
+ */
521
+ function isNodeModule(id) {
522
+ return normalizeModuleId(id).includes("/node_modules/");
523
+ }
524
+ /**
525
+ * Emits page and component chunks like Taro Webpack's MiniPlugin generated entries.
526
+ *
527
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/MiniPlugin.ts#L228-L243
528
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/MiniPlugin.ts#L743-L777
529
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/TaroSingleEntryPlugin.ts#L18-L38
530
+ */
531
+ function emitWechatImplicitChunksForVirtualApp(emitter, context, cleanId) {
532
+ if (context.target !== "wx" || cleanId !== virtualWxAppId) return;
533
+ for (const page of context.pages) emitter.emitFile({
534
+ type: "chunk",
535
+ id: `${virtualWxPagePrefix}${page.path}`,
536
+ fileName: `${page.path}.js`,
537
+ implicitlyLoadedAfterOneOf: [cleanId]
538
+ });
539
+ emitter.emitFile({
540
+ type: "chunk",
541
+ id: virtualWxCompId,
542
+ fileName: "comp.js",
543
+ implicitlyLoadedAfterOneOf: [cleanId]
544
+ });
545
+ }
546
+ /**
547
+ * Builds the generated WeChat app entry that registers Taro's React App config.
548
+ * vite-plugin-taro omits Taro's generated pxTransform initialization because styles are handled by Tailwind.
549
+ *
550
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-loader/src/app.ts#L54-L63
551
+ */
552
+ function createWxAppEntry(context) {
553
+ const wechatAppConfigCode = JSON.stringify(context.appConfig);
554
+ return `import { createReactApp, ReactDOM } from 'vite-plugin-taro/shim/wx'
555
+ import React from 'react'
556
+ import AppComponent from '${context.appComponentImport}'
557
+
558
+ const appConfig = ${wechatAppConfigCode}
559
+ App(createReactApp(AppComponent, React, ReactDOM, appConfig))
560
+ `;
561
+ }
562
+ /**
563
+ * Builds a generated WeChat page entry that registers Taro's Page config.
564
+ *
565
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-loader/src/page.ts#L52-L78
566
+ */
567
+ function createWxPageEntry(pageOption) {
568
+ const wechatPageConfigCode = JSON.stringify(pageOption.config);
569
+ return `import { createPageConfig } from 'vite-plugin-taro/shim/wx'
570
+ import PageComponent from '${createPageComponentImport(pageOption.path)}'
571
+
572
+ const pageConfig = ${wechatPageConfigCode}
573
+ const taroPageConfig = createPageConfig(PageComponent, '${pageOption.path}', { root: { cn: [] } }, pageConfig)
574
+ if (PageComponent && PageComponent.behaviors) {
575
+ taroPageConfig.behaviors = (taroPageConfig.behaviors || []).concat(PageComponent.behaviors)
576
+ }
577
+ Page(taroPageConfig)
578
+ `;
579
+ }
580
+ /**
581
+ * Builds the generated JS companion for comp.wxml/comp.json. Without it WeChat
582
+ * can load recursive markup, but it will not have Taro's properties or `eh` event
583
+ * dispatch method.
584
+ *
585
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/template/comp.ts#L1-L4
586
+ */
587
+ function createWxCompEntry() {
588
+ return `import { createRecursiveComponentConfig } from 'vite-plugin-taro/shim/wx'
589
+
590
+ Component(createRecursiveComponentConfig())
591
+ `;
592
+ }
593
+ /**
594
+ * Creates Taro-style Mini Program template/config/style companion files.
595
+ *
596
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-platform-weapp/src/program.ts#L33-L55
597
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/MiniPlugin.ts#L1198-L1311
598
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/MiniPlugin.ts#L1346-L1390
599
+ */
600
+ function emitWechatAssets(emitter, bundle, context) {
601
+ if (context.target !== "wx") return;
602
+ for (const asset of createWechatAssets(bundle, context)) emitter.emitFile({
603
+ type: "asset",
604
+ fileName: asset.fileName,
605
+ source: asset.source
606
+ });
607
+ }
608
+ function createWechatAssets(bundle, context) {
609
+ const builder = createWechatTemplateBuilder();
610
+ return [
611
+ {
612
+ fileName: "app.json",
613
+ source: stringifyJsonAsset(context.appConfig)
614
+ },
615
+ {
616
+ fileName: "app.wxss",
617
+ source: collectWechatBundleWxss(bundle)
618
+ },
619
+ {
620
+ fileName: "base.wxml",
621
+ source: builder.buildTemplate(collectWechatTemplateComponentConfig(bundle))
622
+ },
623
+ {
624
+ fileName: "utils.wxs",
625
+ source: builder.buildXScript()
626
+ },
627
+ {
628
+ fileName: "comp.wxml",
629
+ source: builder.buildBaseComponentTemplate(".wxml")
630
+ },
631
+ {
632
+ fileName: "comp.json",
633
+ source: stringifyJsonAsset(createWechatCompJson())
634
+ },
635
+ {
636
+ fileName: "project.config.json",
637
+ source: stringifyJsonAsset(context.projectConfigJson)
638
+ },
639
+ {
640
+ fileName: "sitemap.json",
641
+ source: stringifyJsonAsset(context.sitemapJson)
642
+ },
643
+ ...context.pages.flatMap((page) => [
644
+ {
645
+ fileName: `${page.path}.wxml`,
646
+ source: builder.buildPageTemplate(relativeWechatRootAssetFromPage(page.path, "base.wxml"), {
647
+ content: page.config,
648
+ path: page.path
649
+ })
650
+ },
651
+ {
652
+ fileName: `${page.path}.json`,
653
+ source: stringifyJsonAsset({
654
+ ...page.config,
655
+ usingComponents: { comp: relativeWechatRootAssetFromPage(page.path, "comp") }
656
+ })
657
+ },
658
+ {
659
+ fileName: `${page.path}.wxss`,
660
+ source: ""
661
+ }
662
+ ])
663
+ ];
664
+ }
665
+ function createWechatTemplateBuilder() {
666
+ const wechatPlatform = new Weapp({
667
+ helper: { recursiveMerge },
668
+ modifyWebpackChain() {},
669
+ registerPlatform() {}
670
+ }, {}, {});
671
+ wechatPlatform.modifyTemplate({});
672
+ return wechatPlatform.template;
673
+ }
674
+ /**
675
+ * Computes a WeChat import path from a page file to a generated root asset.
676
+ *
677
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/MiniPlugin.ts#L1270-L1298
678
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-helper/src/utils.ts#L74-L88
679
+ */
680
+ function relativeWechatRootAssetFromPage(wechatPagePath, wechatRootAsset) {
681
+ const wechatPageDir = path.posix.dirname(wechatPagePath);
682
+ const relativePath = path.posix.relative(wechatPageDir, wechatRootAsset);
683
+ return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
684
+ }
685
+ /**
686
+ * Builds Taro's template component include config from official defaults plus
687
+ * the component exports that Rolldown kept in the @tarojs/components bundle.
688
+ *
689
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/utils/component.ts#L3-L8
690
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/TaroComponentsExportsPlugin.ts#L83-L124
691
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/TaroLoadChunksPlugin.ts#L165-L180
692
+ */
693
+ function collectWechatTemplateComponentConfig(bundle) {
694
+ const wechatComponentConfig = {
695
+ includes: new Set([
696
+ "view",
697
+ "catch-view",
698
+ "static-view",
699
+ "pure-view",
700
+ "click-view",
701
+ "scroll-view",
702
+ "image",
703
+ "static-image",
704
+ "text",
705
+ "static-text"
706
+ ]),
707
+ exclude: /* @__PURE__ */ new Set(),
708
+ thirdPartyComponents: /* @__PURE__ */ new Map(),
709
+ includeAll: false
710
+ };
711
+ const wechatComponentsModule = findBundleModule(bundle, taroWechatComponentsReactPath);
712
+ for (const item of wechatComponentsModule?.renderedExports ?? []) wechatComponentConfig.includes.add(toDashed(item));
713
+ return wechatComponentConfig;
714
+ }
715
+ function toDashed(s) {
716
+ return s.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
717
+ }
718
+ /**
719
+ * Finds a module record inside the generated bundle by normalized module ID.
720
+ *
721
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/TaroComponentsExportsPlugin.ts#L83-L124
722
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/TaroLoadChunksPlugin.ts#L165-L180
723
+ */
724
+ function findBundleModule(bundle, resolvedId) {
725
+ const normalizedResolvedId = normalizeModuleId(resolvedId);
726
+ for (const item of Object.values(bundle)) {
727
+ if (item.type !== "chunk") continue;
728
+ const found = Object.entries(item.modules ?? {}).find(([id]) => normalizeModuleId(id) === normalizedResolvedId);
729
+ if (found) return found[1];
730
+ }
731
+ }
732
+ /**
733
+ * Creates the JSON config for Taro's shared recursive component.
734
+ *
735
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/MiniPlugin.ts#L1228-L1252
736
+ */
737
+ function createWechatCompJson() {
738
+ return {
739
+ component: true,
740
+ styleIsolation: "apply-shared",
741
+ usingComponents: { comp: "./comp" }
742
+ };
743
+ }
744
+ /**
745
+ * Converts a WeChat-emitted asset's source into text.
746
+ */
747
+ function getWechatAssetSource(item) {
748
+ if (typeof item.source === "string") return item.source;
749
+ return item.source ? new TextDecoder().decode(item.source) : "";
750
+ }
751
+ /**
752
+ * Flattens Vite-emitted CSS into app.wxss and removes the intermediate CSS asset.
753
+ * This is vite-plugin-taro's Vite equivalent of Taro Webpack's app/common style consolidation.
754
+ *
755
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/MiniPlugin.ts#L1310-L1311
756
+ * https://github.com/NervJS/taro/blob/f0e5c39d5f04290db975670411e23c3a396e15f8/packages/taro-webpack5-runner/src/plugins/MiniPlugin.ts#L1471-L1528
757
+ */
758
+ function collectWechatBundleWxss(bundle) {
759
+ const wechatWxssChunks = [];
760
+ for (const [fileName, item] of Object.entries(bundle)) {
761
+ if (item.type !== "asset" || !fileName.endsWith(".css")) continue;
762
+ const source = getWechatAssetSource(item);
763
+ if (source) wechatWxssChunks.push(source);
764
+ delete bundle[fileName];
765
+ }
766
+ return wechatWxssChunks.join("\n");
767
+ }
768
+ /**
769
+ * Serializes generated Mini Program JSON assets; vite-plugin-taro pretty-prints non-prod output.
770
+ */
771
+ function stringifyJsonAsset(value) {
772
+ return isProd ? JSON.stringify(value) : JSON.stringify(value, null, 2);
773
+ }
774
+ //#endregion
775
+ //#region src/vite/taro.ts
776
+ /**
777
+ * Creates the Vite/Rolldown plugin that emits either WeChat Mini Program files
778
+ * or a Taro Web app using the official Taro runtime packages.
779
+ */
780
+ function taro(options) {
781
+ const context = createTaroBuildContext(options);
782
+ return [
783
+ createTaroConditionalDirectivePlugin(context),
784
+ ...createTargetSupportPlugins(context),
785
+ ...createTailwindcssPlugins(context),
786
+ createTaroPlugin(context)
787
+ ];
788
+ }
789
+ function createTargetSupportPlugins(context) {
790
+ switch (context.target) {
791
+ case "h5": return createH5SupportPlugins();
792
+ default: return [];
793
+ }
794
+ }
795
+ /**
796
+ * Creates the vite-plugin-taro plugin that emits H5 or Wx outputs.
797
+ */
798
+ function createTaroPlugin(context) {
799
+ return {
800
+ name: "vite-plugin-taro",
801
+ enforce: "post",
802
+ /** Configures Vite/Rolldown for the active target. */
803
+ config: {
804
+ order: "pre",
805
+ handler: () => {
806
+ return context.target === "wx" ? createWxViteConfig(context) : createH5ViteConfig();
807
+ }
808
+ },
809
+ /** Marks generated app/page/component entries as virtual modules. */
810
+ resolveId(id) {
811
+ if (isWxVirtualModuleId(id) || isH5VirtualModuleId(id)) return `\0${id}`;
812
+ },
813
+ /** Supplies source code for each virtual entry module. */
814
+ load(id) {
815
+ const cleanId = stripVirtualPrefix(id);
816
+ emitWechatImplicitChunksForVirtualApp(this, context, cleanId);
817
+ return loadWxVirtualModule(cleanId, context) ?? loadH5VirtualModule(cleanId, context);
818
+ },
819
+ /** Injects the generated Web entry into the app shell before Vite scans HTML imports. */
820
+ transformIndexHtml: {
821
+ order: "pre",
822
+ handler() {
823
+ return createWebIndexHtmlTags(context);
824
+ }
825
+ },
826
+ /** Emits the WeChat JSON/WXML/WXS/WXSS files that are not JS bundle chunks. */
827
+ generateBundle(_, bundle) {
828
+ emitWechatAssets(this, bundle, context);
829
+ }
830
+ };
831
+ }
832
+ /**
833
+ * Normalizes user options into the shared data used by both target builders.
834
+ */
835
+ function createTaroBuildContext(options) {
836
+ return {
837
+ target: options.target,
838
+ appComponentImport: toImportPath(options.app),
839
+ pages: options.pages,
840
+ appConfig: {
841
+ ...options.appJson,
842
+ pages: options.pages.map((page) => page.path)
843
+ },
844
+ projectConfigJson: options.projectConfigJson,
845
+ sitemapJson: options.sitemapJson
846
+ };
847
+ }
848
+ //#endregion
849
+ export { taro as default };
850
+
851
+ //# sourceMappingURL=vite.js.map