vite-plugin-taro 0.6.18 → 0.6.19

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 (133) hide show
  1. package/client.d.ts +2 -3
  2. package/dist/index.js +213574 -0
  3. package/dist/node/plugins/wx/dev/react-refresh.d.ts +14 -13
  4. package/dist/node/utils/packages.d.ts +2 -0
  5. package/package.json +26 -26
  6. package/dist/node/plugins/client/client-taro.js +0 -59
  7. package/dist/node/plugins/client/constant.js +0 -4
  8. package/dist/node/plugins/client/inject-taro-framework-apis.js +0 -9
  9. package/dist/node/plugins/conditional/conditional-directives.js +0 -76
  10. package/dist/node/plugins/h5/constant.js +0 -3
  11. package/dist/node/plugins/h5/create-stencil-client-adapter.js +0 -94
  12. package/dist/node/plugins/h5/plugins.js +0 -179
  13. package/dist/node/plugins/h5/resolver/module-resolver.js +0 -20
  14. package/dist/node/plugins/h5/transform-app.js +0 -48
  15. package/dist/node/plugins/tailwind/tailwind-css.js +0 -3
  16. package/dist/node/plugins/wx/dev/create-hmr-results-stream.js +0 -57
  17. package/dist/node/plugins/wx/dev/dev-host.js +0 -361
  18. package/dist/node/plugins/wx/dev/hmr-files.js +0 -56
  19. package/dist/node/plugins/wx/dev/host-actions.js +0 -58
  20. package/dist/node/plugins/wx/dev/patch-publisher.js +0 -77
  21. package/dist/node/plugins/wx/dev/plugins.js +0 -164
  22. package/dist/node/plugins/wx/dev/react-refresh.js +0 -231
  23. package/dist/node/plugins/wx/dev/runtime-reports.js +0 -45
  24. package/dist/node/plugins/wx/dev/wx-dev-options.js +0 -178
  25. package/dist/node/plugins/wx/module/chunk-path.js +0 -18
  26. package/dist/node/plugins/wx/module/module.js +0 -79
  27. package/dist/node/plugins/wx/native/compile-native-component-interface.js +0 -30
  28. package/dist/node/plugins/wx/native/create-native-component-output.js +0 -39
  29. package/dist/node/plugins/wx/native/native-component-assets.js +0 -76
  30. package/dist/node/plugins/wx/native/native-component-interface.js +0 -203
  31. package/dist/node/plugins/wx/output/files.js +0 -21
  32. package/dist/node/plugins/wx/output/relative-root.js +0 -6
  33. package/dist/node/plugins/wx/output/templates.js +0 -358
  34. package/dist/node/plugins/wx/placer/placement.js +0 -245
  35. package/dist/node/plugins/wx/placer/placer.js +0 -147
  36. package/dist/node/plugins/wx/plugins.js +0 -152
  37. package/dist/node/plugins/wx/render/capsule.js +0 -54
  38. package/dist/node/plugins/wx/render/native.js +0 -543
  39. package/dist/node/plugins/wx/render/system-js/string-editor.js +0 -94
  40. package/dist/node/plugins/wx/render/system-js/system-js.js +0 -588
  41. package/dist/node/plugins/wx/render/transport.js +0 -103
  42. package/dist/node/plugins/wx/resolve/resolver.js +0 -102
  43. package/dist/node/plugins/wx/resolve/specialize-app-capsule.js +0 -9
  44. package/dist/node/plugins/wx/resolve/specialize-page-capsule.js +0 -11
  45. package/dist/node/plugins/wx/styles/plugins.js +0 -459
  46. package/dist/node/utils/constant.js +0 -1
  47. package/dist/node/utils/memoize.js +0 -86
  48. package/dist/node/utils/modules.js +0 -22
  49. package/dist/node/utils/once.js +0 -20
  50. package/dist/node/utils/oxc-transform.js +0 -57
  51. package/dist/node/utils/packages.js +0 -9
  52. package/dist/node/utils/project-config.js +0 -8
  53. package/dist/node/utils/transform.js +0 -32
  54. package/dist/node/utils/vite.js +0 -10
  55. package/dist/node/vpt.js +0 -15
  56. package/dist/options.js +0 -1
  57. package/dist/vite.js +0 -1
  58. package/src/node/plugins/client/client-taro.ts +0 -71
  59. package/src/node/plugins/client/constant.ts +0 -5
  60. package/src/node/plugins/client/inject-taro-framework-apis.ts +0 -11
  61. package/src/node/plugins/conditional/conditional-directives.ts +0 -94
  62. package/src/node/plugins/h5/constant.ts +0 -4
  63. package/src/node/plugins/h5/create-stencil-client-adapter.ts +0 -111
  64. package/src/node/plugins/h5/plugins.ts +0 -194
  65. package/src/node/plugins/h5/resolver/module-resolver.ts +0 -33
  66. package/src/node/plugins/h5/transform-app.ts +0 -90
  67. package/src/node/plugins/tailwind/tailwind-css.ts +0 -4
  68. package/src/node/plugins/wx/dev/create-hmr-results-stream.ts +0 -71
  69. package/src/node/plugins/wx/dev/dev-host.ts +0 -453
  70. package/src/node/plugins/wx/dev/hmr-files.ts +0 -80
  71. package/src/node/plugins/wx/dev/host-actions.ts +0 -88
  72. package/src/node/plugins/wx/dev/patch-publisher.ts +0 -92
  73. package/src/node/plugins/wx/dev/plugins.ts +0 -176
  74. package/src/node/plugins/wx/dev/react-refresh.ts +0 -253
  75. package/src/node/plugins/wx/dev/runtime-reports.ts +0 -70
  76. package/src/node/plugins/wx/dev/wx-dev-options.ts +0 -226
  77. package/src/node/plugins/wx/module/chunk-path.ts +0 -22
  78. package/src/node/plugins/wx/module/module.ts +0 -110
  79. package/src/node/plugins/wx/native/compile-native-component-interface.ts +0 -48
  80. package/src/node/plugins/wx/native/create-native-component-output.ts +0 -60
  81. package/src/node/plugins/wx/native/native-component-assets.ts +0 -113
  82. package/src/node/plugins/wx/native/native-component-interface.ts +0 -267
  83. package/src/node/plugins/wx/output/files.ts +0 -40
  84. package/src/node/plugins/wx/output/relative-root.ts +0 -7
  85. package/src/node/plugins/wx/output/templates.ts +0 -448
  86. package/src/node/plugins/wx/placer/placement.ts +0 -364
  87. package/src/node/plugins/wx/placer/placer.ts +0 -180
  88. package/src/node/plugins/wx/plugins.ts +0 -183
  89. package/src/node/plugins/wx/render/capsule.ts +0 -57
  90. package/src/node/plugins/wx/render/native.ts +0 -694
  91. package/src/node/plugins/wx/render/system-js/string-editor.ts +0 -116
  92. package/src/node/plugins/wx/render/system-js/system-js.ts +0 -821
  93. package/src/node/plugins/wx/render/transport.ts +0 -173
  94. package/src/node/plugins/wx/resolve/resolver.ts +0 -145
  95. package/src/node/plugins/wx/resolve/specialize-app-capsule.ts +0 -27
  96. package/src/node/plugins/wx/resolve/specialize-page-capsule.ts +0 -29
  97. package/src/node/plugins/wx/styles/plugins.ts +0 -595
  98. package/src/node/utils/constant.ts +0 -1
  99. package/src/node/utils/memoize.ts +0 -149
  100. package/src/node/utils/modules.ts +0 -37
  101. package/src/node/utils/once.ts +0 -21
  102. package/src/node/utils/oxc-transform.ts +0 -76
  103. package/src/node/utils/packages.ts +0 -11
  104. package/src/node/utils/project-config.ts +0 -10
  105. package/src/node/utils/transform.ts +0 -48
  106. package/src/node/utils/vite.ts +0 -22
  107. package/src/node/vpt.ts +0 -18
  108. package/src/options.ts +0 -82
  109. package/src/runtime/client/taro/api.ts +0 -11
  110. package/src/runtime/client/taro/component.ts +0 -1
  111. package/src/runtime/client/taro/define-native-component.ts +0 -15
  112. package/src/runtime/h5/app.ts +0 -25
  113. package/src/runtime/h5/taro-css.d.ts +0 -3
  114. package/src/runtime/h5/taro-runtime.ts +0 -7
  115. package/src/runtime/wx/amphibious/bootstrap.ts +0 -17
  116. package/src/runtime/wx/amphibious/transport.ts +0 -8
  117. package/src/runtime/wx/capsule/app.ts +0 -12
  118. package/src/runtime/wx/capsule/component.ts +0 -7
  119. package/src/runtime/wx/capsule/page.ts +0 -29
  120. package/src/runtime/wx/capsule/taro-runtime.ts +0 -8
  121. package/src/runtime/wx/dev/dev-runtime.ts +0 -464
  122. package/src/runtime/wx/native/app.ts +0 -4
  123. package/src/runtime/wx/native/component.ts +0 -4
  124. package/src/runtime/wx/native/custom-wrapper.ts +0 -4
  125. package/src/runtime/wx/native/page.ts +0 -6
  126. package/src/runtime/wx/systemjs/LICENSE +0 -10
  127. package/src/runtime/wx/systemjs/system-core.js +0 -370
  128. package/src/runtime/wx/systemjs/system.d.ts +0 -55
  129. package/src/runtime/wx/wechat.d.ts +0 -56
  130. package/src/vite.ts +0 -2
  131. /package/dist/{vite.d.ts → index.d.ts} +0 -0
  132. /package/dist/runtime/client/taro/{define-native-component.d.ts → native.d.ts} +0 -0
  133. /package/dist/runtime/client/taro/{define-native-component.js → native.js} +0 -0
@@ -1,164 +0,0 @@
1
- import { normalizePath, transformWithOxc } from 'vite';
2
- import { esTarget } from '../../../utils/constant.js';
3
- import { memoize } from '../../../utils/memoize.js';
4
- import { normalizeModuleId } from '../../../utils/modules.js';
5
- import { pageShellPath, rolldownRuntimeId } from '../module/module.js';
6
- import { createWxDevHost } from './dev-host.js';
7
- import { developmentAppWxssFileName } from './hmr-files.js';
8
- import { createWxReactRefreshTransforms } from './react-refresh.js';
9
- /** Selects the sole Vite environment that owns the physical Mini Program development project. */
10
- export function isWxClientEnvironment(environment) {
11
- return environment.name === 'client';
12
- }
13
- /**
14
- * Adds the serve-only bundled-development plugin set for the wx target: the dev adapter,
15
- * Page HMR activation, and React Refresh adaptation transforms.
16
- *
17
- * The shared style pipeline already owns the resolver's ordered App/Page cascade policy, so the host does not reconstruct it
18
- * from unrelated Rolldown shell and transport entries.
19
- */
20
- export function createWxDevelopmentPlugin(options, styles) {
21
- /*
22
- * Vite creates this plugin descriptor before a server or DevEngine exists, then invokes configureServer and closeBundle on
23
- * different lifecycle stacks. This mutable handle transfers the one client-owned host between those hooks: configureServer
24
- * assigns it after asynchronous construction, and closeBundle reads it to drain the same engine. Environment scoping ensures
25
- * only the client hook pair participates. Capturing a construction Promise would start too early, while recreating the host
26
- * in closeBundle would lose every live action, patch, style, and client frontier owned by the running instance.
27
- */
28
- let host = null;
29
- // Portable hook filters stay broad; these exact identities exclude similarly named user modules.
30
- const normalizedPageShellPath = normalizePath(pageShellPath);
31
- return [
32
- {
33
- name: 'vpt:wx-dev',
34
- apply: 'serve',
35
- // The physical WX DevEngine is a client build. Native environment scoping gives its shared host exactly one
36
- // generate/close lifecycle instead of admitting hooks from Vite's unrelated SSR environment.
37
- applyToEnvironment: isWxClientEnvironment,
38
- config() {
39
- return {
40
- build: {
41
- // The development output is the live Mini Program project opened by WeChat DevTools, not a disposable
42
- // build artifact. Deleting and recreating its directory tree during a dev-server restart disrupts
43
- // DevTools' hot-reload watcher; recreating the same paths does not reliably attach that watcher again.
44
- // The host then continues writing hmr/patches.js, but DevTools no longer observes it and therefore never
45
- // re-executes the Page shell that consumes and acknowledges the patches. Keep the watched paths present
46
- // across host restarts and let the initial complete build overwrite active outputs. This plugin applies
47
- // only to `serve`; production builds retain Vite's normal output cleanup.
48
- emptyOutDir: false,
49
- // Disable maps in resolved environment config as well as final output so Oxc and Babel skip producing
50
- // intermediate maps that Rolldown would discard.
51
- sourcemap: false
52
- },
53
- experimental: {
54
- // Ask Vite to resolve its bundled-development graph and expose the private adapter instance. The wx
55
- // configureServer hook replaces only its startup method with the directly writing DevEngine.
56
- bundledDev: true
57
- }
58
- };
59
- },
60
- configureServer: {
61
- // Install after Vite and user plugins have finished configuring the environment, but before server.listen()
62
- // asks bundledDev to create its hard-coded skip-write DevEngine.
63
- order: 'post',
64
- async handler(server) {
65
- host = await createWxDevHost({
66
- server: server,
67
- options: options,
68
- styles: styles
69
- });
70
- }
71
- },
72
- generateBundle: {
73
- order: 'post',
74
- handler(_, bundle) {
75
- // `vpt:wx` emits the production App wrapper during every complete build: initial startup and each
76
- // recovery build, not just once when this plugin instance is created. Development transfers that file
77
- // to the host so its only physical write happens after the matching build identity is durable.
78
- removeDevelopmentAppWxss(bundle);
79
- }
80
- },
81
- closeBundle() {
82
- return host?.close();
83
- }
84
- },
85
- {
86
- name: 'vpt:wx-runtime-lowering',
87
- apply: 'serve',
88
- transform: {
89
- order: 'post',
90
- // The dev-mode transform assembles the runtime chunk (Rolldown's base runtime
91
- // plus our injected implement) as this module's transform output, which
92
- // bypasses the build's es2018 lowering. Real-device engines and WeChat's
93
- // upload parser predate class fields and nullish operators, so the assembled
94
- // runtime is lowered here — the only module that needs it. The exact id
95
- // filter needs no code scan; the id must stay in sync with rolldownRuntimeId
96
- // in module.ts (kept as a regex for the Rolldown-side filter).
97
- filter: { id: /^\0rolldown\/runtime\.js(?:\?|$)/ },
98
- handler(code) {
99
- // The `setPublicClassFields` assumption emits plain `this.x = ...`
100
- // assignments instead of external helpers, whose references the later
101
- // minifier would mangle.
102
- return fixRolldownRuntime(code);
103
- }
104
- }
105
- },
106
- {
107
- name: 'vpt:wx-page-shell-hmr',
108
- apply: 'serve',
109
- transform: {
110
- order: 'post',
111
- filter: { id: /\/runtime\/wx\/native\/page\.js(?:\?|$)/ },
112
- handler(code, id) {
113
- if (normalizeModuleId(id) !== normalizedPageShellPath)
114
- return;
115
- return injectPageShellHmr(code);
116
- }
117
- }
118
- },
119
- ...createWxReactRefreshTransforms()
120
- ];
121
- }
122
- /**
123
- * Transfers development ownership of `app.wxss` from complete output to the dev host.
124
- *
125
- * The ordinary WX output hook emits the static production wrapper during every complete build. In development, the existing
126
- * physical wrapper instead contains the previous build ID. If the static asset remained in this bundle, the DevEngine would:
127
- *
128
- * 1. replace the versioned wrapper with static production bytes while JavaScript and HMR metadata are still being finalized;
129
- * 2. let DevTools observe that root-style change and reload the App against the previous build identity;
130
- * 3. let the host replace the wrapper again with the new build ID, causing a second App reload.
131
- *
132
- * Deleting only the in-memory bundle entry avoids both premature writes. Development sets `emptyOutDir: false`, so the prior
133
- * physical `app.wxss` remains available while the complete output is written. The host replaces it exactly once after
134
- * `hmr/patches.js` and `hmr/info.js` are durable. Incremental HMR never enters this complete-output hook and continues changing
135
- * only `assets/global.wxss`, which preserves the App heap. The serve-only plugin leaves production output unchanged.
136
- */
137
- export function removeDevelopmentAppWxss(bundle) {
138
- delete bundle[developmentAppWxssFileName];
139
- }
140
- /** Injects the retained snapshot at the exact native Page registration edge. */
141
- export function injectPageShellHmr(code) {
142
- const registration = 'Page(pageConfig)';
143
- if (!code.includes(registration)) {
144
- throw new Error('WX native Page shell must register pageConfig');
145
- }
146
- return {
147
- code: code.replace(registration, 'Page(__rolldown_runtime__.injectPageHmr(pageConfig))'),
148
- map: null
149
- };
150
- }
151
- /*
152
- * memoize owns a mutable one-entry-by-input cache. The assembled runtime source is byte-identical across complete generations
153
- * because both the Rolldown base and injected implementation are immutable for the server lifetime. Reusing its lowered result
154
- * avoids repeating the only large Oxc transform on every rebuild; keying by source still invalidates correctly if a future Vite
155
- * generation changes the runtime, unlike a module-global cached string detached from its actual input.
156
- */
157
- const fixRolldownRuntime = memoize((code) => {
158
- return transformWithOxc(code, rolldownRuntimeId, {
159
- lang: 'js',
160
- target: esTarget,
161
- sourcemap: false,
162
- assumptions: { setPublicClassFields: true }
163
- });
164
- });
@@ -1,231 +0,0 @@
1
- import { isReferenceIdentifier } from 'oxc-walker';
2
- import { memoize } from '../../../utils/memoize.js';
3
- import { normalizeModuleId } from '../../../utils/modules.js';
4
- import { transformWithOxcWalker } from '../../../utils/oxc-transform.js';
5
- import { reactReconcilerRoot } from '../module/module.js';
6
- /** The React DevTools hook protocol name; free references must target `global` in wx. */
7
- const reactDevtoolsHookProtocol = '__REACT_DEVTOOLS_GLOBAL_HOOK__';
8
- /**
9
- * Refresh protocol globals that must live on the WeChat `global` object:
10
- * - `__registerBeforePerformReactRefresh` is assigned at module evaluation so the HMR client can register work that
11
- * must finish before a refresh. Leaving it on `window` throws before the refresh runtime can initialize.
12
- * - `__getReactRefreshIgnoredExports` is an optional extension point read while validating a refresh boundary.
13
- * Leaving that read on the nonexistent `window` crashes every update validation pass.
14
- *
15
- * Keeping this list explicit prevents the adapter from rewriting unrelated browser accesses if the refresh runtime
16
- * gains new code. Any future React Refresh protocol addition therefore requires a deliberate compatibility decision.
17
- */
18
- const refreshRuntimeWindowGlobals = ['__registerBeforePerformReactRefresh', '__getReactRefreshIgnoredExports'];
19
- /**
20
- * Creates the serve-only React Refresh adaptation transforms for the wx target.
21
- *
22
- * @vitejs/plugin-react's generated refresh code assumes the web HTML preamble and a browser
23
- * global scope; wx has neither. Each transform adapts one piece of that contract:
24
- * - the refresh runtime module (id-filtered): the runtime reads and assigns
25
- * `window` protocol globals (rewritten to `global`) and must inject itself at evaluation;
26
- * - React Reconciler: its renderer injection statically depends on the refresh runtime, fixing cold-start order;
27
- * - react-family modules (filtered on free references): the DevTools hook is read as a free
28
- * variable, which the WeChat runtime scope never resolves against `global` — every free
29
- * reference becomes an explicit member access;
30
- * - boundary modules (filtered on the guard): the preamble's `$RefreshReg$` global is not
31
- * needed because the transform generates local wrappers over the imported refresh
32
- * runtime, so the guard that checks for the global is removed.
33
- *
34
- * Filters route every adaptation directly. The Reconciler intentionally receives the renderer dependency first and the
35
- * global-hook rewrite second; modules outside these explicit domains never reach a handler.
36
- */
37
- export function createWxReactRefreshTransforms() {
38
- return [
39
- {
40
- name: 'vpt:wx-react-refresh-runtime',
41
- apply: 'serve',
42
- transform: {
43
- order: 'post',
44
- // The refresh runtime module is id-filtered, so no code scan is needed.
45
- filter: { id: /^\/@react-refresh(?:\?|$)/ },
46
- handler(code, id) {
47
- return fixRefreshRuntime({ code, id });
48
- }
49
- }
50
- },
51
- {
52
- name: 'vpt:wx-react-refresh-renderer-dependency',
53
- apply: 'serve',
54
- transform: {
55
- order: 'post',
56
- filter: { id: /\/react-reconciler\/cjs\/react-reconciler\.development\.js(?:\?|$)/ },
57
- handler(code, id) {
58
- const rendererId = `${reactReconcilerRoot}/cjs/react-reconciler.development.js`;
59
- if (normalizeModuleId(id) !== rendererId)
60
- return;
61
- return injectReactRefreshRendererDependency(code);
62
- }
63
- }
64
- },
65
- {
66
- name: 'vpt:wx-react-devtools-hook',
67
- apply: 'serve',
68
- transform: {
69
- order: 'post',
70
- // Matches only free references (react-family modules). The member accesses in
71
- // the refresh runtime and the dev runtime chunk never match, so they need no
72
- // id exclusion.
73
- filter: { code: /(^|[^.\w$])__REACT_DEVTOOLS_GLOBAL_HOOK__/ },
74
- handler(code, id) {
75
- return fixReactDevtoolsHook({ code, id });
76
- }
77
- }
78
- },
79
- {
80
- name: 'vpt:wx-refresh-preamble-guard',
81
- apply: 'serve',
82
- transform: {
83
- order: 'post',
84
- // Vite's documented refresh protocol global; the generated guard is its only
85
- // occurrence, in boundary modules.
86
- filter: { code: /window\.\$RefreshReg\$/ },
87
- handler(code, id) {
88
- return removeRefreshPreambleGuard({ code, id });
89
- }
90
- }
91
- }
92
- ];
93
- }
94
- /**
95
- * React-family modules: free `__REACT_DEVTOOLS_GLOBAL_HOOK__` reads must target `global`.
96
- *
97
- * The renderer checks the hook with `typeof __REACT_DEVTOOLS_GLOBAL_HOOK__` and injects via
98
- * `hook.inject(...)` — but in the WeChat runtime, free-variable reads never resolve against
99
- * `global`'s properties (verified: the free lookup is undefined while
100
- * `global.__REACT_DEVTOOLS_GLOBAL_HOOK__` exists). The renderer would therefore silently
101
- * skip injection, leaving React Refresh with no renderer on which to schedule re-renders.
102
- *
103
- * The protocol name is unique, but only reference identifiers are rewritten. Declaration
104
- * keys and explicit members such as `global.__REACT_DEVTOOLS_GLOBAL_HOOK__` must remain
105
- * untouched; rewriting those would either produce invalid syntax or double-prefix the hook.
106
- * The Reconciler's injected static dependency orders hook injection before renderer initialization independently of Rolldown's
107
- * final chunking decision.
108
- */
109
- function createReactDevtoolsHookVisitor(editor) {
110
- return function enter(node, parent) {
111
- if (node.type !== 'Identifier' ||
112
- node.name !== reactDevtoolsHookProtocol ||
113
- !isReferenceIdentifier(node, parent)) {
114
- return;
115
- }
116
- // An explicit member access is required because WeChat does not expose properties of
117
- // its global object as free lexical bindings. Removing this edit disables renderer
118
- // registration even though the hook object itself still exists.
119
- editor.overwrite(node.start, node.end, `global.${reactDevtoolsHookProtocol}`);
120
- };
121
- }
122
- /**
123
- * Refresh runtime module: self-inject at evaluation and rewrite its browser protocol globals.
124
- *
125
- * In web Vite, an HTML preamble calls `injectIntoGlobalHook(window)` before application
126
- * modules load. wx has no HTML document or preamble, so nothing performs that bootstrap.
127
- * The call must live in the refresh runtime module itself:
128
- * - this module's closure owns `helpersByRendererID`, mounted roots, and the update helpers;
129
- * - the wx dev-runtime chunk cannot call into it because the refresh module is in a later,
130
- * lazily loaded chunk and does not exist when the dev-runtime chunk evaluates.
131
- *
132
- * Unlike the preamble's `$RefreshReg$` globals, which boundary modules replace with local
133
- * wrappers, the renderer-hook machinery has no local equivalent. Without this injected call,
134
- * the runtime never learns about the renderer or mounted roots and updates cannot refresh UI.
135
- *
136
- * Appending the call is safe even when React has already registered its renderer: the refresh
137
- * runtime replays `hook.renderers` during injection, then its patched commit hooks observe all
138
- * later mounts and remounts. The same module also contains two browser-only `window` protocol
139
- * accesses; those must point at `global` or evaluation/update validation throws in WeChat.
140
- */
141
- function createRefreshRuntimeVisitor(editor) {
142
- // The declarations must execute before self-injection, so the call is appended instead of
143
- // prepended. Removing it would leave the web preamble's only essential responsibility
144
- // unimplemented in wx.
145
- editor.append('\ninjectIntoGlobalHook(global);');
146
- return function enter(node) {
147
- if (node.type === 'MemberExpression' &&
148
- !node.computed &&
149
- node.object.type === 'Identifier' &&
150
- node.object.name === 'window' &&
151
- node.property.type === 'Identifier' &&
152
- refreshRuntimeWindowGlobals.some((globalName) => globalName === node.property.name)) {
153
- // `global` is the shared wx App heap used by the dev runtime and hook injection. Only
154
- // replacing the object range preserves the upstream runtime byte-for-byte otherwise
155
- // and prevents unrelated `window` expressions from being silently adapted.
156
- editor.overwrite(node.object.start, node.object.end, 'global');
157
- }
158
- };
159
- }
160
- /**
161
- * Removes the web-only `if (!window.$RefreshReg$) throw Error(...)` assertion from boundary modules.
162
- *
163
- * The assertion verifies that Vite's HTML preamble installed global registration helpers.
164
- * wx has no preamble and evaluating `window` itself fails. The assertion is unnecessary here:
165
- * @vitejs/plugin-react generates local `$RefreshReg$` and `$RefreshSig$` wrappers that delegate
166
- * directly to the imported refresh runtime. Removing the whole statement therefore removes
167
- * only an invalid platform check; component registration continues through those local wrappers.
168
- * If this edit is removed, every transformed refresh boundary crashes before its module body runs.
169
- */
170
- function createRefreshPreambleGuardVisitor(editor) {
171
- return function enter(node) {
172
- if (node.type !== 'IfStatement' ||
173
- node.test.type !== 'UnaryExpression' ||
174
- node.test.operator !== '!' ||
175
- node.test.argument.type !== 'MemberExpression' ||
176
- node.test.argument.computed ||
177
- node.test.argument.object.type !== 'Identifier' ||
178
- node.test.argument.object.name !== 'window' ||
179
- node.test.argument.property.type !== 'Identifier' ||
180
- node.test.argument.property.name !== '$RefreshReg$') {
181
- return;
182
- }
183
- // Matching the complete AST shape prevents an unrelated `$RefreshReg$` use from being
184
- // removed. Skipping descendants is required because their ranges disappear with the
185
- // parent and must not receive overlapping MagicString edits.
186
- editor.remove(node.start, node.end);
187
- this.skip();
188
- };
189
- }
190
- /** Makes renderer hook injection statically depend on the refresh runtime. */
191
- export function injectReactRefreshRendererDependency(code) {
192
- if (!/\bhook\.inject\(internals\)/.test(code)) {
193
- throw new Error('React Reconciler must inject its renderer into the DevTools hook');
194
- }
195
- return {
196
- code: `import '/@react-refresh'\n${code}`,
197
- map: null
198
- };
199
- }
200
- export function transformRefreshRuntime({ code, id }) {
201
- return transformWithOxcWalker({
202
- code,
203
- filename: id,
204
- sourcemap: false,
205
- createVisitor: createRefreshRuntimeVisitor
206
- });
207
- }
208
- export function transformReactDevtoolsHook({ code, id }) {
209
- return transformWithOxcWalker({
210
- code,
211
- filename: id,
212
- sourcemap: false,
213
- createVisitor: createReactDevtoolsHookVisitor
214
- });
215
- }
216
- export function removeRefreshPreambleGuard({ code, id }) {
217
- return transformWithOxcWalker({
218
- code,
219
- filename: id,
220
- sourcemap: false,
221
- createVisitor: createRefreshPreambleGuardVisitor
222
- });
223
- }
224
- /*
225
- * Each memoized transform owns a mutable cache keyed only by source bytes. The matching runtime/react-family modules are
226
- * immutable between complete generations, so reparsing them would repeat O(source bytes) Oxc work without observing new state.
227
- * Source keys still create a fresh result after a dependency upgrade or real module edit, unlike a once-only cache keyed by ID;
228
- * keeping separate caches prevents identical text in different transform domains from sharing the wrong adaptation.
229
- */
230
- const fixRefreshRuntime = memoize(transformRefreshRuntime, { getCacheKey: ({ code }) => code });
231
- const fixReactDevtoolsHook = memoize(transformReactDevtoolsHook, { getCacheKey: ({ code }) => code });
@@ -1,45 +0,0 @@
1
- import { buffer, debounceTime, filter, Subject } from 'rxjs';
2
- /**
3
- * Conflates runtime receipts without weakening their build identity or recovery semantics.
4
- *
5
- * Reports are metadata frontiers rather than executable deltas: for one build, the highest applied sequence subsumes lower and
6
- * duplicate acknowledgements. A rebuild does not subsume reports from a different build, because delayed Pages may still POST
7
- * after session rotation, but it dominates every acknowledgement for its own build. The host validates each retained build ID
8
- * against the physical publisher only when its serialized task executes, preserving rotation order.
9
- *
10
- * Completing the Subject flushes the active window synchronously so shutdown can include its host task before closing Rolldown.
11
- * Reduction is O(reports) time and O(distinct builds) retained space per quiet window.
12
- */
13
- export function createRuntimeReportsStream(settleMilliseconds, scheduler, publish) {
14
- /*
15
- * This Subject is the sole mutable HTTP admission edge. Requests append reports synchronously and finish their responses;
16
- * buffer then owns the short-lived window while debounceTime supplies only its quiet-edge signal. Reports are metadata rather
17
- * than executable deltas, so the window may be reduced before entering hostActions. Directly mutating PatchPublisher from the
18
- * request stack would race patch writes and build rotation; retaining every raw receipt beyond the window would grow with Page
19
- * count and duplicate acknowledgements. Completion flushes the final window during phased shutdown.
20
- */
21
- const reports = new Subject();
22
- reports
23
- .pipe(buffer(reports.pipe(debounceTime(settleMilliseconds, scheduler))), filter((window) => window.length > 0))
24
- .subscribe((window) => publish(reduceRuntimeReportWindow(window)));
25
- return reports;
26
- }
27
- export function reduceRuntimeReportWindow(window) {
28
- /*
29
- * This transaction-local mutable Map is bounded by distinct build IDs in one quiet window. Insertion order preserves causal
30
- * build order, while replacing a value conflates only that build's monotonic acknowledgement frontier; rebuild becomes its
31
- * terminal value. A single global latest report would let delayed Pages erase another build, and retaining the raw window
32
- * would make downstream work proportional to duplicate report volume. The Map is discarded immediately after reduction.
33
- */
34
- const reportsByBuild = new Map();
35
- for (const report of window) {
36
- const previous = reportsByBuild.get(report.buildId);
37
- if (previous?.kind === 'rebuild') {
38
- continue;
39
- }
40
- if (report.kind === 'rebuild' || previous === undefined || report.seq > previous.seq) {
41
- reportsByBuild.set(report.buildId, report);
42
- }
43
- }
44
- return [...reportsByBuild.values()];
45
- }
@@ -1,178 +0,0 @@
1
- import path from 'node:path';
2
- import { build } from 'rolldown';
3
- import { viteReporterPlugin } from 'rolldown/experimental';
4
- import { once } from '../../../utils/once.js';
5
- import { resolvePackageFile } from '../../../utils/packages.js';
6
- import { appShellFileName } from '../module/module.js';
7
- /**
8
- * Installs physical WX output and runtime conventions over Vite's browser-oriented bundled-development options.
9
- * Build completion deliberately remains outside this options adapter: DevEngine onOutput is the single lifecycle authority.
10
- */
11
- export function installWxDevOptions({ bundledDev, server, options }) {
12
- /*
13
- * Vite owns this mutable adapter method and calls it later when constructing DevEngine. Replacing that one seam preserves
14
- * Vite's resolved graph while applying WX physical-output conventions to every options generation. Capturing and mutating one
15
- * options object here would be stale on later complete builds; creating a second engine would duplicate watchers and graphs.
16
- * The bound original remains immutable and is invoked exactly once per delegated options request.
17
- */
18
- const original = bundledDev.getRolldownOptions.bind(bundledDev);
19
- bundledDev.getRolldownOptions = async () => {
20
- const rolldownOptions = await original();
21
- const output = ensureSingleOutput(rolldownOptions);
22
- const configuredOutput = server.config.build.rolldownOptions.output;
23
- if (Array.isArray(configuredOutput)) {
24
- throw new Error('wx development supports one configured Rolldown output.');
25
- }
26
- const configured = configuredOutput ?? {};
27
- // Every page entry must depend on hmr/patches.js: DevTools classifies a changed Page dependency as Page JavaScript
28
- // hot reload and re-executes live Pages, which is the only physical patch trigger that preserves the App heap. Although
29
- // Set provides O(1) membership, exposing it as ReadonlySet prevents mutation after this options generation is resolved.
30
- const pageFiles = new Set(options.pages.map((page) => `${page.path}.js`));
31
- /*
32
- * Rolldown passes this mutable output object onward by identity, and nested Vite plugins may already retain it. Mutating
33
- * that single object preserves their references while atomically replacing browser-oriented naming and format fields with
34
- * stable physical WX conventions. Cloning only our fields would leave retained references on stale hashed filenames;
35
- * mutating configuredOutput itself would leak development normalization back into the user's resolved Vite config.
36
- */
37
- Object.assign(output, configured, {
38
- // Development output is overwritten in place after every complete build. Strip hash placeholders from the
39
- // configured asset pattern so old files cannot accumulate and native JSON/WXML references remain stable.
40
- assetFileNames: createStableFileNames(configured.assetFileNames, 'assets/[name][extname]'),
41
- // Banners create physical CommonJS edges after graph analysis: App initializes the dev runtime and each Page
42
- // consumes the stable patch journal without allowing those host-only files into the application chunk graph.
43
- banner: createEntryBanner(pageFiles),
44
- // Preserve the configured directory/name shape while removing content hashes. Stable chunk paths let DevTools
45
- // overwrite executable files and let cumulative HMR patches address one persistent physical module identity.
46
- chunkFileNames: createStableFileNames(configured.chunkFileNames, 'assets/[name].js'),
47
- // Native entry paths are public Mini Program routes (`app.js`, `pages/.../index.js`); development must never hash
48
- // or relocate them because DevTools determines App/Page reload behavior from those exact filenames.
49
- entryFileNames: createStableFileNames(configured.entryFileNames, '[name]'),
50
- // Keep ESM until the existing WX renderChunk pipeline classifies each final chunk and converts capsules to
51
- // System.register data or native/amphibious entries to CommonJS. Choosing CommonJS here would erase that boundary.
52
- format: 'es',
53
- // Bundled development emits complete physical output repeatedly. Minifying bounds disk transfer and DevTools
54
- // compile work; source-level HMR diagnostics still come from Vite/Rolldown before this final output pass.
55
- minify: true,
56
- // DevTools executes physical WX files and HMR applies module factories rather than browser source maps. Disabling
57
- // maps avoids extra output files and prevents Vite's Oxc sourcemap transform from touching generated host code.
58
- sourcemap: false
59
- });
60
- /*
61
- * experimental belongs to this transaction-local Rolldown options generation. Materialize it only when absent, then
62
- * replace devMode with a new object so user fields survive without mutating a possibly shared configured sub-object.
63
- */
64
- rolldownOptions.experimental ??= {};
65
- const existingDevMode = rolldownOptions.experimental.devMode;
66
- rolldownOptions.experimental.devMode = {
67
- // Retain unknown user/forward-compatible devMode fields while the three explicit WX invariants below win.
68
- ...(typeof existingDevMode === 'object' ? existingDevMode : {}),
69
- // Install the WX-adapted self-contained Rolldown runtime. It consumes physical patch journals and reports
70
- // acknowledgements/rebuild requests through the host bridge instead of relying on browser globals or sockets.
71
- implement: await bundleRuntimeSource(),
72
- // Produce a complete output graph on the initial build. Lazy per-request compilation cannot establish the closed
73
- // App/Page graph, native companions, style sidecars, and build identity required before any patch is admitted.
74
- lazy: false,
75
- // Keep Rolldown's common runtime injection because generated application factories call its module registry and
76
- // HMR primitives. Skipping it would leave the custom implementation without the runtime surface it extends.
77
- skipCommonRuntimeInjection: false
78
- };
79
- /*
80
- * The plugin list is mutable configuration consumed once by this engine generation. Replace the top-level reference with
81
- * an ordered composite rather than pushing into Vite's potentially shared nested array; the reporter observes final output
82
- * without mutating Vite's retained input list.
83
- */
84
- rolldownOptions.plugins = [rolldownOptions.plugins, createViteReporter(server)];
85
- disableViteOxcSourcemap(rolldownOptions.plugins);
86
- return rolldownOptions;
87
- };
88
- }
89
- /** Returns the configured output after rejecting states unsupported by the physical WX engine. */
90
- export function requireSingleOutput(rolldownOptions) {
91
- if (!rolldownOptions.output || Array.isArray(rolldownOptions.output)) {
92
- throw new Error('wx development requires exactly one Rolldown output.');
93
- }
94
- return rolldownOptions.output;
95
- }
96
- /** Creates the one missing output object while rejecting a configured output array. */
97
- function ensureSingleOutput(rolldownOptions) {
98
- if (Array.isArray(rolldownOptions.output)) {
99
- throw new Error('wx development requires one configured Rolldown output.');
100
- }
101
- // Rolldown needs the created object attached to input options by identity; returning a detached fallback would be ignored.
102
- rolldownOptions.output ??= {};
103
- return rolldownOptions.output;
104
- }
105
- /**
106
- * Prepends entry banners after Rolldown's analysis so their native requires remain physical dependencies rather than chunk
107
- * graph edges. The App initializes the runtime identity, while every Page explicitly applies the watched patch data before its
108
- * native Page registration.
109
- */
110
- function createEntryBanner(pageFiles) {
111
- return (chunk) => {
112
- if (chunk.name === appShellFileName) {
113
- return "__rolldown_runtime__.initialize(require('./hmr/info.js'));\n";
114
- }
115
- if (pageFiles.has(chunk.name)) {
116
- const patchesPath = path.posix.relative(path.posix.dirname(chunk.fileName), 'hmr/patches.js');
117
- return `__rolldown_runtime__.applyPatches(require('${patchesPath}'));\n`;
118
- }
119
- return '';
120
- };
121
- }
122
- function createStableFileNames(addon, fallback) {
123
- if (typeof addon === 'function') {
124
- return (value) => toStableFileName(String(addon(value)));
125
- }
126
- return toStableFileName(typeof addon === 'string' ? addon : fallback);
127
- }
128
- function toStableFileName(fileName) {
129
- return fileName
130
- .replace(/(^|\/)\[hash(?::\d+)?\](?=\.|$)/g, '$1[name]')
131
- .replace(/[-_.]\[hash(?::\d+)?\]/g, '')
132
- .replace(/\[hash(?::\d+)?\]/g, '[name]');
133
- }
134
- function disableViteOxcSourcemap(pluginOption) {
135
- if (Array.isArray(pluginOption)) {
136
- pluginOption.forEach(disableViteOxcSourcemap);
137
- return;
138
- }
139
- if (!pluginOption || typeof pluginOption !== 'object')
140
- return;
141
- const plugin = pluginOption;
142
- if (plugin.name === 'builtin:vite-transform' && plugin._options?.transformOptions) {
143
- /*
144
- * Vite's private builtin retains this mutable transform options object and does not expose a public replacement hook.
145
- * Updating its one sourcemap flag prevents Oxc from allocating maps that final WX output always discards; cloning the
146
- * descriptor would not update the builtin closure that reads the original object during transforms.
147
- */
148
- plugin._options.transformOptions.sourcemap = false;
149
- }
150
- }
151
- function createViteReporter(server) {
152
- const { build, logger, root } = server.config;
153
- return viteReporterPlugin({
154
- assetsDir: path.join(build.assetsDir, '/'),
155
- chunkLimit: 2000,
156
- isLib: Boolean(build.lib),
157
- isTty: Boolean(process.stdout.isTTY && !process.env.CI),
158
- logInfo: (message) => logger.info(message),
159
- reportCompressedSize: false,
160
- root,
161
- warnLargeChunks: false
162
- });
163
- }
164
- /*
165
- * once owns a mutable cached Promise, justified because getRolldownOptions may run for multiple complete generations while the
166
- * runtime input and build options remain immutable for the process lifetime. Sharing the in-flight/result Promise prevents
167
- * concurrent options requests from launching duplicate nested builds; caching source instead of a Rolldown output object avoids
168
- * leaking mutable bundle metadata between engines.
169
- */
170
- const bundleRuntimeSource = once(async function bundleRuntimeSource() {
171
- // write: false keeps this nested helper build from creating a second dist directory in the application project.
172
- const result = await build({
173
- input: resolvePackageFile('dist/runtime/wx/dev/dev-runtime.js'),
174
- output: { format: 'iife', minify: true, sourcemap: false },
175
- write: false
176
- });
177
- return result.output[0].code;
178
- });
@@ -1,18 +0,0 @@
1
- import path from 'node:path';
2
- /** Physical directory in which Rolldown writes generated JavaScript chunks inside each native package. */
3
- export const generatedChunkDirectory = 'assets';
4
- /** Projects one Rolldown-owned physical candidate path into the package-neutral SystemJS identity. */
5
- export function toLogicalChunkId(physicalChunkId) {
6
- return path.posix.relative(generatedChunkDirectory, physicalChunkId);
7
- }
8
- /** Resolves one relative Rolldown-generated import to its preliminary physical chunk path. */
9
- export function resolvePhysicalChunkReference(importerChunkId, reference) {
10
- if (!reference.startsWith('./') && !reference.startsWith('../')) {
11
- throw new Error(`Expected a relative chunk reference in ${importerChunkId}: ${reference}`);
12
- }
13
- return path.posix.join(path.posix.dirname(importerChunkId), reference);
14
- }
15
- /** Projects one relative Rolldown-generated import into its package-neutral SystemJS identity. */
16
- export function resolveLogicalChunkReference(importerChunkId, reference) {
17
- return toLogicalChunkId(resolvePhysicalChunkReference(importerChunkId, reference));
18
- }