vite-plugin-taro 0.6.2 → 0.6.5

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.
Files changed (46) hide show
  1. package/README.en.md +8 -3
  2. package/README.md +8 -3
  3. package/dist/node/plugins/wx/dev/dev-host.d.ts +5 -4
  4. package/dist/node/plugins/wx/dev/dev-host.js +19 -43
  5. package/dist/node/plugins/wx/dev/plugins.d.ts +6 -15
  6. package/dist/node/plugins/wx/dev/plugins.js +16 -70
  7. package/dist/node/plugins/wx/dev/react-refresh.d.ts +9 -3
  8. package/dist/node/plugins/wx/dev/react-refresh.js +35 -7
  9. package/dist/node/plugins/wx/dev/wx-dev-options.d.ts +2 -3
  10. package/dist/node/plugins/wx/dev/wx-dev-options.js +6 -7
  11. package/dist/node/plugins/wx/plugins.js +5 -11
  12. package/dist/node/plugins/wx/resolve/resolver.js +4 -4
  13. package/dist/node/plugins/wx/resolve/{specialize-bootstrap.d.ts → specialize-app-capsule.d.ts} +2 -2
  14. package/dist/node/plugins/wx/resolve/{specialize-bootstrap.js → specialize-app-capsule.js} +2 -2
  15. package/dist/node/plugins/wx/styles/plugins.d.ts +141 -3
  16. package/dist/node/plugins/wx/styles/plugins.js +401 -89
  17. package/dist/node/utils/vite.d.ts +4 -14
  18. package/dist/node/utils/vite.js +7 -40
  19. package/dist/runtime/wx/amphibious/bootstrap.d.ts +0 -2
  20. package/dist/runtime/wx/amphibious/bootstrap.js +0 -2
  21. package/dist/runtime/wx/capsule/app.d.ts +2 -2
  22. package/dist/runtime/wx/capsule/app.js +2 -2
  23. package/dist/runtime/wx/dev/dev-runtime.js +55 -79
  24. package/package.json +4 -3
  25. package/src/node/plugins/wx/dev/dev-host.ts +22 -44
  26. package/src/node/plugins/wx/dev/plugins.ts +17 -73
  27. package/src/node/plugins/wx/dev/react-refresh.ts +36 -7
  28. package/src/node/plugins/wx/dev/wx-dev-options.ts +7 -10
  29. package/src/node/plugins/wx/plugins.ts +5 -11
  30. package/src/node/plugins/wx/resolve/resolver.ts +4 -4
  31. package/src/node/plugins/wx/resolve/{specialize-bootstrap.ts → specialize-app-capsule.ts} +2 -2
  32. package/src/node/plugins/wx/styles/plugins.ts +518 -93
  33. package/src/node/utils/vite.ts +13 -58
  34. package/src/runtime/wx/amphibious/bootstrap.ts +0 -5
  35. package/src/runtime/wx/capsule/app.ts +5 -2
  36. package/src/runtime/wx/dev/dev-runtime.ts +71 -120
  37. package/src/runtime/wx/wechat.d.ts +1 -2
  38. package/dist/node/plugins/wx/dev/create-style-capture.d.ts +0 -54
  39. package/dist/node/plugins/wx/dev/create-style-capture.js +0 -173
  40. package/dist/node/plugins/wx/styles/transform-wx-style.d.ts +0 -8
  41. package/dist/node/plugins/wx/styles/transform-wx-style.js +0 -9
  42. package/dist/node/plugins/wx/styles/utils.d.ts +0 -39
  43. package/dist/node/plugins/wx/styles/utils.js +0 -95
  44. package/src/node/plugins/wx/dev/create-style-capture.ts +0 -248
  45. package/src/node/plugins/wx/styles/transform-wx-style.ts +0 -11
  46. package/src/node/plugins/wx/styles/utils.ts +0 -119
@@ -3,11 +3,11 @@ import { normalizeModuleId, resolveAppComponentPath, resolvePageComponentPath }
3
3
  import { createAppConfig } from '../../../utils/project-config.js';
4
4
  import { appComponentId } from '../../client/constant.js';
5
5
  import { appCapsulePath, appShellFileName, appShellPath, bootstrapPath, componentCapsulePath, componentShellFileName, componentShellPath, pageCapsuleId, pageCapsulePath, pageComponentId, pageShellPath, transportPath, vitePreloadId } from '../module/module.js';
6
- import { specializeBootstrap } from './specialize-bootstrap.js';
6
+ import { specializeAppCapsule } from './specialize-app-capsule.js';
7
7
  import { specializePageCapsule } from './specialize-page-capsule.js';
8
8
  /** Creates the resolver and source specializer for the wx module graph. */
9
9
  export function createResolver(options) {
10
- const normalizedBootstrapPath = normalizePath(bootstrapPath);
10
+ const normalizedAppCapsulePath = normalizePath(appCapsulePath);
11
11
  const normalizedPageCapsulePath = normalizePath(pageCapsulePath);
12
12
  // Construct output input and application traversal roots together once so style order cannot drift from route order.
13
13
  const entryGraph = createEntryGraph(options.pages);
@@ -42,8 +42,8 @@ export function createResolver(options) {
42
42
  },
43
43
  specialize(code, id, sourcemap = true) {
44
44
  const normalizedId = normalizeModuleId(id);
45
- if (normalizedId === normalizedBootstrapPath) {
46
- return specializeBootstrap({ code, id, appConfig: createAppConfig(options), sourcemap });
45
+ if (normalizedId === normalizedAppCapsulePath) {
46
+ return specializeAppCapsule({ code, id, appConfig: createAppConfig(options), sourcemap });
47
47
  }
48
48
  if (normalizedId === normalizedPageCapsulePath) {
49
49
  return specializePageCapsule({
@@ -1,7 +1,7 @@
1
1
  import type { VptJsonObject } from '../../../../options.ts';
2
2
  import { type AstTransformResult } from '../../../utils/transform.ts';
3
- /** Specializes the amphibious bootstrap with the shared App configuration. */
4
- export declare function specializeBootstrap({ code, id, appConfig, sourcemap }: {
3
+ /** Specializes the App capsule with its normalized native configuration. */
4
+ export declare function specializeAppCapsule({ code, id, appConfig, sourcemap }: {
5
5
  code: string;
6
6
  id: string;
7
7
  appConfig: VptJsonObject;
@@ -1,8 +1,8 @@
1
1
  import * as types from '@babel/types';
2
2
  import { replaceWithAst } from '../../../utils/transform.js';
3
3
  const appConfigPlaceholder = '__VPT_APP_CONFIG__';
4
- /** Specializes the amphibious bootstrap with the shared App configuration. */
5
- export function specializeBootstrap({ code, id, appConfig, sourcemap = true }) {
4
+ /** Specializes the App capsule with its normalized native configuration. */
5
+ export function specializeAppCapsule({ code, id, appConfig, sourcemap = true }) {
6
6
  return replaceWithAst(code, id, {
7
7
  [appConfigPlaceholder]: types.valueToNode(appConfig)
8
8
  }, sourcemap);
@@ -1,3 +1,141 @@
1
- import type { PluginOption } from 'vite';
2
- /** Creates the complete WX Tailwind and global-style pipeline. */
3
- export declare function createWxStylePlugins(): PluginOption[];
1
+ import { type Plugin } from 'vite';
2
+ import { createContext } from 'weapp-tailwindcss/core';
3
+ /** JavaScript code plus the physical filename required by the Weapp JavaScript transformer. */
4
+ type JavaScriptArtifact = Readonly<{
5
+ code: string;
6
+ filename: string;
7
+ }>;
8
+ /** Vite plugin with the development-host operation that finalizes one coherent WX style/JavaScript transaction. */
9
+ export type WxStylePlugin = Plugin & Readonly<{
10
+ /** Converts patch factories and publishes their matching global WXSS through the host's atomic writer. */
11
+ finalizeUpdate: <Artifact extends JavaScriptArtifact>(artifacts: readonly Artifact[], writeWxss: (wxss: string) => Promise<void>) => Promise<readonly Artifact[]>;
12
+ }>;
13
+ /**
14
+ * Creates the single owner of global WX style compilation, graph projection, JavaScript class rewriting, and publication.
15
+ *
16
+ * ## Architectural invariant
17
+ *
18
+ * A WX transaction must expose JavaScript and WXSS produced from one class-identity snapshot. Tailwind utility names can be
19
+ * rewritten for WeChat—for example, `py-5.5` becomes `py-5_d5`—so publishing either side independently can leave running code
20
+ * referring to selectors that do not yet exist. This plugin therefore treats reachable CSS, Tailwind candidates, converted
21
+ * WXSS, and converted JavaScript as one output. Complete builds and HMR updates both call `finalizeOutput()`; they differ only
22
+ * in how the returned bytes are materialized.
23
+ *
24
+ * ## Ownership boundaries
25
+ *
26
+ * The pipeline deliberately gives each subsystem one responsibility:
27
+ *
28
+ * 1. Rolldown owns module reachability and invalidation. VPT reads `getModuleInfo()` and registers watch files, but does not
29
+ * maintain a second import graph or decide independently which root should rerun.
30
+ * 2. The persistent Tailwind generator owns candidate discovery and incremental candidate removal. VPT invokes it only from
31
+ * the owning CSS root's Rolldown transform and never rescans the project during output publication.
32
+ * 3. Vite owns preprocessors, PostCSS, CSS Modules, and final module CSS semantics. VPT observes the input to the resolved
33
+ * `vite:css-post` hook only after the original hook succeeds; it never rereads source files or repeats CSS preprocessing.
34
+ * 4. The Weapp transformation context owns WX selector conversion and JavaScript class-string conversion. One retained context
35
+ * and one projected candidate set drive both operations.
36
+ * 5. VPT owns physical global WXSS and patch publication. Vite's browser CSS asset is only an intermediate carrier and is
37
+ * removed before VPT emits `assets/global.wxss`.
38
+ *
39
+ * Native Page and component WXSS are outside this global pipeline. The WX output plugin is registered after this style plugin
40
+ * and emits those opaque companions later. The WX configuration also enforces `cssCodeSplit: false`, so Vite contributes at
41
+ * most one browser compiler stylesheet for this plugin to replace.
42
+ *
43
+ * ## Compilation phases
44
+ *
45
+ * ### 1. Tailwind pre-transform
46
+ *
47
+ * The pre-transform checks physical application CSS for Tailwind imports or directives. Ordinary styles pass through. A
48
+ * Tailwind root compiles to browser CSS before Vite's normal CSS pipeline runs. Successful generation records the generator,
49
+ * scanner, current class set, compiler dependencies, and exact root source under the normalized physical module ID.
50
+ *
51
+ * Candidate files and compiler dependencies intentionally have different invalidation behavior:
52
+ *
53
+ * - Candidate-file changes rerun the root with the existing generator and scanner. `incrementalCache: true` updates additions
54
+ * and removals without discarding the generator's authoritative cache.
55
+ * - Compiler-dependency changes mark the root invalid. Its next Rolldown transform resolves a new Tailwind source and creates a
56
+ * new generator and scanner. Replacement is delayed until that transform has current source and plugin context.
57
+ * - If a stylesheet stops being a Tailwind root, its generator is disposed and its Tailwind state is removed. The later Vite
58
+ * CSS hook replaces the retained CSS after normal processing succeeds.
59
+ *
60
+ * ### 2. Vite-final CSS capture
61
+ *
62
+ * `configResolved` wraps the concrete `vite:css-post` transform while preserving its hook metadata, filter, ordering, and
63
+ * plugin context. The original Vite hook executes first, which preserves CSS Module exports and Vite's internal extraction
64
+ * state. Only a successful transform updates `styleByModuleId`; syntax errors therefore leave the last successful CSS available
65
+ * to the currently running application. Query modes such as `?raw`, `?url`, and `?inline` are excluded because they represent
66
+ * values rather than graph-owned stylesheets.
67
+ *
68
+ * ### 3. Live-graph projection
69
+ *
70
+ * Output finalization starts from resolved App/Page entry IDs and traverses Rolldown's current static and dynamic import edges
71
+ * in dependency-first post-order. Transaction-local visited sets terminate cycles and deduplicate shared modules and physical
72
+ * stylesheets. A retained stylesheet contributes only when its module is still reachable, so removing an import prunes its CSS
73
+ * and Tailwind candidates without a separate prune protocol or persistent topology cache. Candidate sets are unioned only from
74
+ * the Tailwind roots whose captured CSS survives that exact traversal, preserving the CSS/class identity invariant.
75
+ *
76
+ * ### 4. Shared WX finalization
77
+ *
78
+ * `finalizeOutput()` first converts the concatenated reachable CSS to WXSS, then transforms every supplied JavaScript artifact
79
+ * with the same projected class set. It returns data and performs no bundle mutation or filesystem publication. If either
80
+ * transformation fails, the promise rejects before callers expose partial output. JavaScript conversion is skipped when the
81
+ * projection contains no Tailwind candidates, preserving ordinary bundle bytes.
82
+ *
83
+ * ### 5a. Complete-build commit
84
+ *
85
+ * The post-order `generateBundle` hook gathers all JavaScript chunks, finalizes them as one operation, and only then mutates the
86
+ * bundle. It assigns converted code, clears invalid source maps, removes Vite's intermediate browser stylesheet, and always
87
+ * emits `assets/global.wxss`. Emitting an empty global file is required because `app.wxss` imports it even when the application
88
+ * currently has no styles. Native output hooks run afterward and emit Page/component companion files independently.
89
+ *
90
+ * ### 5b. Development commit
91
+ *
92
+ * The development host calls `finalizeUpdate()` after Rolldown produces patch factories or a complete-output notification.
93
+ * Finalization uses the `PluginContext` captured by `buildStart`, so it observes the same current graph as the compiler. After
94
+ * all conversion succeeds, the host's atomic writer publishes changed WXSS before `finalizeUpdate()` returns converted patch
95
+ * factories. The patch publisher therefore cannot expose newer JavaScript class identities before matching selectors exist.
96
+ * `publishedWxss` advances only after a successful write and suppresses byte-identical writes that would otherwise trigger
97
+ * unnecessary WeChat DevTools reload events.
98
+ *
99
+ * ## Retained state and lifecycle
100
+ *
101
+ * The factory retains four explicit mutable state owners plus one library-owned transformation context:
102
+ *
103
+ * - `entryIds`: graph-exact App/Page entry identities resolved at the start of each build;
104
+ * - `graphContext`: the active Rolldown graph reader needed by host calls made outside plugin hooks;
105
+ * - `styleByModuleId`: the latest successful Vite CSS plus optional Tailwind state at one normalized module identity;
106
+ * - `publishedWxss`: the last durably published development stylesheet used for unchanged-write suppression;
107
+ * - `weappContext`: Weapp's internal conversion state, retained so selector and JavaScript rewriting share one context.
108
+ *
109
+ * The state owners remain scoped to one plugin instance; `entryIds` is atomically replaced after each complete resolution.
110
+ * Build-command bundles dispose Tailwind generators after bundle generation. A development watcher otherwise keeps them alive
111
+ * across updates and disposes them when it closes. Captured CSS survives compiler cleanup because output notifications can
112
+ * arrive after that cleanup, and is cleared only when the watcher terminates.
113
+ *
114
+ * ## Cost model
115
+ *
116
+ * Projection is `O(V + E + B + C)` for reachable modules, import edges, concatenated CSS bytes, and candidate insertions.
117
+ * JavaScript conversion is linear in the total supplied chunk or patch-factory bytes, subject to the Weapp parser's own cost.
118
+ * Retained memory is `O(B + C + D + F)` for latest CSS, candidate sets, compiler dependencies, and scanner file identities; no
119
+ * second application graph is retained. Tailwind's generator and Oxide scanner caches are intentionally persistent because
120
+ * recreating them on every candidate edit would repeat source normalization and scanning work.
121
+ */
122
+ export declare function createWxStylePlugin(applicationEntryIds: readonly string[]): WxStylePlugin;
123
+ /**
124
+ * Produces WXSS and JavaScript from one live-graph projection.
125
+ *
126
+ * The function receives every stateful dependency explicitly so tests and both output modes execute the same algorithm. It
127
+ * completes WXSS conversion before JavaScript conversion and returns bytes without publishing or mutating caller artifacts.
128
+ */
129
+ export declare function finalizeOutput(entryIds: readonly string[], styleByModuleId: ReadonlyMap<string, Readonly<{
130
+ css: string | undefined;
131
+ tailwind: Readonly<{
132
+ classSet: ReadonlySet<string>;
133
+ }> | undefined;
134
+ }>>, getModuleInfo: (moduleId: string) => Readonly<{
135
+ importedIds: readonly string[];
136
+ dynamicallyImportedIds: readonly string[];
137
+ }> | null | undefined, weappContext: Pick<ReturnType<typeof createContext>, 'transformJs' | 'transformWxss'>, javaScript: readonly JavaScriptArtifact[]): Promise<{
138
+ javaScript: string[];
139
+ wxss: string;
140
+ }>;
141
+ export {};