vite-plugin-taro 0.3.2 → 0.4.0

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 (260) hide show
  1. package/README.en.md +44 -0
  2. package/README.md +22 -497
  3. package/client.d.ts +9 -0
  4. package/dist/node/plugins/client/client-taro.d.ts +4 -0
  5. package/dist/node/plugins/client/client-taro.js +19 -0
  6. package/dist/node/plugins/client/constant.d.ts +4 -0
  7. package/dist/node/plugins/client/constant.js +4 -0
  8. package/dist/node/plugins/conditional/conditional-directives.d.ts +4 -0
  9. package/dist/node/plugins/{conditional-directives.js → conditional/conditional-directives.js} +27 -11
  10. package/dist/node/plugins/css/plugins.d.ts +4 -0
  11. package/dist/node/plugins/css/plugins.js +84 -0
  12. package/dist/node/plugins/h5/constant.d.ts +2 -0
  13. package/dist/node/plugins/h5/constant.js +3 -0
  14. package/dist/node/plugins/h5/plugins.d.ts +4 -0
  15. package/dist/node/plugins/h5/plugins.js +161 -0
  16. package/dist/node/plugins/h5/resolver/module-resolver.d.ts +14 -0
  17. package/dist/node/plugins/h5/resolver/module-resolver.js +19 -0
  18. package/dist/node/plugins/h5/transform-app.d.ts +10 -0
  19. package/dist/node/plugins/h5/transform-app.js +48 -0
  20. package/dist/node/plugins/wx/dev/dev-host.d.ts +15 -0
  21. package/dist/node/plugins/wx/dev/dev-host.js +352 -0
  22. package/dist/node/plugins/wx/dev/hmr-files.d.ts +28 -0
  23. package/dist/node/plugins/wx/dev/hmr-files.js +34 -0
  24. package/dist/node/plugins/wx/dev/patch-publisher.d.ts +22 -0
  25. package/dist/node/plugins/wx/dev/patch-publisher.js +40 -0
  26. package/dist/node/plugins/wx/dev/plugin.d.ts +7 -0
  27. package/dist/node/plugins/wx/dev/plugin.js +73 -0
  28. package/dist/node/plugins/wx/dev/react-refresh.d.ts +20 -0
  29. package/dist/node/plugins/wx/dev/react-refresh.js +198 -0
  30. package/dist/node/plugins/wx/module.d.ts +45 -0
  31. package/dist/node/plugins/wx/module.js +66 -0
  32. package/dist/node/plugins/wx/native/compile-native-component-interface.d.ts +21 -0
  33. package/dist/node/plugins/wx/native/compile-native-component-interface.js +29 -0
  34. package/dist/node/plugins/wx/native/create-native-component-output.d.ts +15 -0
  35. package/dist/node/plugins/wx/native/create-native-component-output.js +39 -0
  36. package/dist/node/plugins/wx/native/native-component-assets.d.ts +26 -0
  37. package/dist/node/plugins/wx/native/native-component-assets.js +76 -0
  38. package/dist/node/plugins/wx/native/native-component-interface.d.ts +12 -0
  39. package/dist/node/plugins/wx/native/native-component-interface.js +201 -0
  40. package/dist/node/plugins/wx/output/files.d.ts +12 -0
  41. package/dist/node/plugins/wx/output/files.js +12 -0
  42. package/dist/node/plugins/wx/output/json.d.ts +14 -0
  43. package/dist/node/plugins/wx/output/json.js +52 -0
  44. package/dist/node/plugins/wx/output/relative-root.d.ts +2 -0
  45. package/dist/node/plugins/wx/output/relative-root.js +6 -0
  46. package/dist/node/plugins/wx/output/templates.d.ts +7 -0
  47. package/dist/node/plugins/wx/output/templates.js +100 -0
  48. package/dist/node/plugins/wx/placement/placer.d.ts +78 -0
  49. package/dist/node/plugins/wx/placement/placer.js +145 -0
  50. package/dist/node/plugins/wx/placement/plan.d.ts +46 -0
  51. package/dist/node/plugins/wx/placement/plan.js +210 -0
  52. package/dist/node/plugins/wx/plugins.d.ts +4 -0
  53. package/dist/node/plugins/wx/plugins.js +137 -0
  54. package/dist/node/plugins/wx/render/capsule-wrapper.d.ts +3 -0
  55. package/dist/node/plugins/wx/render/capsule-wrapper.js +64 -0
  56. package/dist/node/plugins/wx/render/capsule.d.ts +4 -0
  57. package/dist/node/plugins/wx/render/capsule.js +13 -0
  58. package/dist/node/plugins/wx/render/native.d.ts +9 -0
  59. package/dist/node/plugins/wx/render/native.js +45 -0
  60. package/dist/node/plugins/wx/render/transport.d.ts +17 -0
  61. package/dist/node/plugins/wx/render/transport.js +94 -0
  62. package/dist/node/plugins/wx/resolve/resolver.d.ts +7 -0
  63. package/dist/node/plugins/wx/resolve/resolver.js +86 -0
  64. package/dist/node/plugins/wx/resolve/specialize-bootstrap.d.ts +9 -0
  65. package/dist/node/plugins/wx/resolve/specialize-bootstrap.js +9 -0
  66. package/dist/node/plugins/wx/resolve/specialize-page-capsule.d.ts +9 -0
  67. package/dist/node/plugins/wx/resolve/specialize-page-capsule.js +11 -0
  68. package/dist/node/utils/constant.d.ts +1 -0
  69. package/dist/node/utils/constant.js +1 -0
  70. package/dist/node/utils/memoize.d.ts +122 -0
  71. package/dist/node/utils/memoize.js +86 -0
  72. package/dist/node/utils/modules.d.ts +20 -24
  73. package/dist/node/utils/modules.js +21 -34
  74. package/dist/node/utils/once.d.ts +10 -0
  75. package/dist/node/utils/once.js +20 -0
  76. package/dist/node/utils/packages.d.ts +1 -0
  77. package/dist/node/utils/packages.js +1 -1
  78. package/dist/node/utils/project-config.d.ts +3 -0
  79. package/dist/node/utils/project-config.js +8 -0
  80. package/dist/node/utils/serialized-task-queue.d.ts +9 -0
  81. package/dist/node/utils/serialized-task-queue.js +17 -0
  82. package/dist/node/utils/transform.d.ts +11 -0
  83. package/dist/node/utils/transform.js +58 -0
  84. package/dist/node/vite-plugin.d.ts +1 -1
  85. package/dist/node/vite-plugin.js +11 -27
  86. package/dist/options.d.ts +3 -4
  87. package/dist/runtime/{taro → client/taro}/api.d.ts +0 -1
  88. package/dist/runtime/client/taro/api.js +9 -0
  89. package/dist/runtime/client/taro/component.d.ts +1 -0
  90. package/dist/runtime/client/taro/component.js +1 -0
  91. package/dist/runtime/client/taro/define-native-component.d.ts +7 -0
  92. package/dist/runtime/client/taro/define-native-component.js +4 -0
  93. package/dist/runtime/h5/app.d.ts +2 -0
  94. package/dist/runtime/h5/app.js +15 -0
  95. package/dist/runtime/h5/taro-runtime.d.ts +1 -1
  96. package/dist/runtime/h5/taro-runtime.js +1 -4
  97. package/dist/runtime/wx/amphibious/bootstrap.d.ts +4 -0
  98. package/dist/runtime/wx/amphibious/bootstrap.js +16 -0
  99. package/dist/runtime/wx/amphibious/transport.d.ts +2 -0
  100. package/dist/runtime/wx/amphibious/transport.js +4 -0
  101. package/dist/runtime/wx/capsule/app.d.ts +2 -0
  102. package/dist/runtime/wx/capsule/app.js +7 -0
  103. package/dist/runtime/wx/capsule/component.d.ts +3 -0
  104. package/dist/runtime/wx/capsule/component.js +4 -0
  105. package/dist/runtime/wx/capsule/page.d.ts +3 -0
  106. package/dist/runtime/wx/capsule/page.js +68 -0
  107. package/dist/runtime/wx/capsule/taro-runtime.d.ts +6 -0
  108. package/dist/runtime/wx/capsule/taro-runtime.js +6 -0
  109. package/dist/runtime/wx/dev/dev-runtime.d.ts +1 -0
  110. package/dist/runtime/wx/dev/dev-runtime.js +246 -0
  111. package/dist/runtime/wx/native/app.d.ts +1 -0
  112. package/dist/runtime/wx/native/app.js +3 -0
  113. package/dist/runtime/wx/native/component.d.ts +1 -0
  114. package/dist/runtime/wx/native/component.js +3 -0
  115. package/dist/runtime/wx/native/page.d.ts +1 -0
  116. package/dist/runtime/wx/native/page.js +4 -0
  117. package/dist/runtime/wx/systemjs/system-core.d.ts +4 -0
  118. package/dist/runtime/wx/systemjs/system-core.js +331 -0
  119. package/package.json +21 -14
  120. package/src/node/plugins/client/client-taro.ts +23 -0
  121. package/src/node/plugins/client/constant.ts +5 -0
  122. package/src/node/plugins/{conditional-directives.ts → conditional/conditional-directives.ts} +33 -13
  123. package/src/node/plugins/css/plugins.ts +96 -0
  124. package/src/node/plugins/h5/constant.ts +4 -0
  125. package/src/node/plugins/h5/plugins.ts +197 -0
  126. package/src/node/plugins/h5/resolver/module-resolver.ts +32 -0
  127. package/src/node/plugins/h5/transform-app.ts +90 -0
  128. package/src/node/plugins/wx/dev/dev-host.ts +448 -0
  129. package/src/node/plugins/wx/dev/hmr-files.ts +55 -0
  130. package/src/node/plugins/wx/dev/patch-publisher.ts +49 -0
  131. package/src/node/plugins/wx/dev/plugin.ts +82 -0
  132. package/src/node/plugins/wx/dev/react-refresh.ts +227 -0
  133. package/src/node/plugins/wx/module.ts +97 -0
  134. package/src/node/plugins/wx/native/compile-native-component-interface.ts +47 -0
  135. package/src/node/plugins/wx/native/create-native-component-output.ts +57 -0
  136. package/src/node/plugins/wx/native/native-component-assets.ts +114 -0
  137. package/src/node/plugins/wx/native/native-component-interface.ts +265 -0
  138. package/src/node/plugins/wx/output/files.ts +27 -0
  139. package/src/node/plugins/wx/output/json.ts +79 -0
  140. package/src/node/plugins/wx/output/relative-root.ts +7 -0
  141. package/src/node/plugins/wx/output/templates.ts +141 -0
  142. package/src/node/plugins/wx/placement/placer.ts +172 -0
  143. package/src/node/plugins/wx/placement/plan.ts +306 -0
  144. package/src/node/plugins/wx/plugins.ts +165 -0
  145. package/src/node/plugins/wx/render/capsule-wrapper.ts +86 -0
  146. package/src/node/plugins/wx/render/capsule.ts +21 -0
  147. package/src/node/plugins/wx/render/native.ts +84 -0
  148. package/src/node/plugins/wx/render/transport.ts +157 -0
  149. package/src/node/plugins/wx/resolve/resolver.ts +125 -0
  150. package/src/node/plugins/wx/resolve/specialize-bootstrap.ts +27 -0
  151. package/src/node/plugins/wx/resolve/specialize-page-capsule.ts +29 -0
  152. package/src/node/utils/constant.ts +1 -0
  153. package/src/node/utils/memoize.ts +149 -0
  154. package/src/node/utils/modules.ts +36 -38
  155. package/src/node/utils/once.ts +21 -0
  156. package/src/node/utils/packages.ts +1 -1
  157. package/src/node/utils/project-config.ts +10 -0
  158. package/src/node/utils/serialized-task-queue.ts +20 -0
  159. package/src/node/utils/transform.ts +82 -0
  160. package/src/node/vite-plugin.ts +12 -32
  161. package/src/options.ts +3 -4
  162. package/src/runtime/client/taro/api.ts +11 -0
  163. package/src/runtime/client/taro/component.ts +1 -0
  164. package/src/runtime/client/taro/define-native-component.ts +15 -0
  165. package/src/runtime/h5/app.ts +25 -0
  166. package/src/runtime/h5/taro-runtime.ts +1 -4
  167. package/src/runtime/wx/amphibious/bootstrap.ts +22 -0
  168. package/src/runtime/wx/amphibious/transport.ts +10 -0
  169. package/src/runtime/wx/capsule/app.ts +9 -0
  170. package/src/runtime/wx/capsule/component.ts +6 -0
  171. package/src/runtime/wx/capsule/page.ts +96 -0
  172. package/src/runtime/wx/capsule/taro-runtime.ts +14 -0
  173. package/src/runtime/wx/dev/dev-runtime.ts +317 -0
  174. package/src/runtime/wx/native/app.ts +4 -0
  175. package/src/runtime/wx/native/component.ts +4 -0
  176. package/src/runtime/wx/native/page.ts +6 -0
  177. package/src/runtime/wx/systemjs/LICENSE +10 -0
  178. package/src/runtime/wx/systemjs/system-core.js +370 -0
  179. package/src/runtime/wx/systemjs/system.d.ts +55 -0
  180. package/src/runtime/wx/wechat.d.ts +52 -0
  181. package/README.zh.md +0 -521
  182. package/dist/node/build-context.d.ts +0 -25
  183. package/dist/node/build-context.js +0 -47
  184. package/dist/node/css/css-pipeline.d.ts +0 -35
  185. package/dist/node/css/css-pipeline.js +0 -154
  186. package/dist/node/plugins/conditional-directives.d.ts +0 -3
  187. package/dist/node/plugins/taro-runtime.d.ts +0 -5
  188. package/dist/node/plugins/taro-runtime.js +0 -18
  189. package/dist/node/targets/h5/plugin.d.ts +0 -6
  190. package/dist/node/targets/h5/plugin.js +0 -117
  191. package/dist/node/targets/h5/virtual-modules.d.ts +0 -5
  192. package/dist/node/targets/h5/virtual-modules.js +0 -60
  193. package/dist/node/targets/wx/companion-assets.d.ts +0 -19
  194. package/dist/node/targets/wx/companion-assets.js +0 -129
  195. package/dist/node/targets/wx/dev-server/development-session.d.ts +0 -32
  196. package/dist/node/targets/wx/dev-server/development-session.js +0 -215
  197. package/dist/node/targets/wx/dev-server/full-build-scheduler.d.ts +0 -14
  198. package/dist/node/targets/wx/dev-server/full-build-scheduler.js +0 -60
  199. package/dist/node/targets/wx/dev-server/js-utils.d.ts +0 -5
  200. package/dist/node/targets/wx/dev-server/js-utils.js +0 -28
  201. package/dist/node/targets/wx/dev-server/output.d.ts +0 -19
  202. package/dist/node/targets/wx/dev-server/output.js +0 -44
  203. package/dist/node/targets/wx/dev-server/rolldown-runtime-source.d.ts +0 -8
  204. package/dist/node/targets/wx/dev-server/rolldown-runtime-source.js +0 -95
  205. package/dist/node/targets/wx/dev-server/update-server-state.d.ts +0 -65
  206. package/dist/node/targets/wx/dev-server/update-server-state.js +0 -116
  207. package/dist/node/targets/wx/dev-server/update-transport.d.ts +0 -28
  208. package/dist/node/targets/wx/dev-server/update-transport.js +0 -212
  209. package/dist/node/targets/wx/dev-server/vite-bundled-dev-adapter.d.ts +0 -44
  210. package/dist/node/targets/wx/dev-server/vite-bundled-dev-adapter.js +0 -145
  211. package/dist/node/targets/wx/development-files.d.ts +0 -8
  212. package/dist/node/targets/wx/development-files.js +0 -8
  213. package/dist/node/targets/wx/plugin.d.ts +0 -6
  214. package/dist/node/targets/wx/plugin.js +0 -144
  215. package/dist/node/targets/wx/react-refresh.d.ts +0 -4
  216. package/dist/node/targets/wx/react-refresh.js +0 -38
  217. package/dist/node/targets/wx/virtual-modules.d.ts +0 -16
  218. package/dist/node/targets/wx/virtual-modules.js +0 -120
  219. package/dist/node/utils/async.d.ts +0 -8
  220. package/dist/node/utils/async.js +0 -16
  221. package/dist/node/utils/filesystem.d.ts +0 -13
  222. package/dist/node/utils/filesystem.js +0 -43
  223. package/dist/runtime/taro/api.js +0 -11
  224. package/dist/runtime/taro/components.d.ts +0 -2
  225. package/dist/runtime/taro/components.js +0 -2
  226. package/dist/runtime/wx/page-update.d.ts +0 -6
  227. package/dist/runtime/wx/page-update.js +0 -157
  228. package/dist/runtime/wx/taro-runtime.d.ts +0 -5
  229. package/dist/runtime/wx/taro-runtime.js +0 -6
  230. package/dist/runtime/wx/update-client-state.d.ts +0 -68
  231. package/dist/runtime/wx/update-client-state.js +0 -84
  232. package/dist/runtime/wx/update-client.d.ts +0 -1
  233. package/dist/runtime/wx/update-client.js +0 -171
  234. package/src/node/build-context.ts +0 -62
  235. package/src/node/css/css-pipeline.ts +0 -171
  236. package/src/node/plugins/taro-runtime.ts +0 -22
  237. package/src/node/targets/h5/plugin.ts +0 -135
  238. package/src/node/targets/h5/virtual-modules.ts +0 -71
  239. package/src/node/targets/wx/companion-assets.ts +0 -174
  240. package/src/node/targets/wx/dev-server/development-session.ts +0 -271
  241. package/src/node/targets/wx/dev-server/full-build-scheduler.ts +0 -62
  242. package/src/node/targets/wx/dev-server/js-utils.ts +0 -33
  243. package/src/node/targets/wx/dev-server/output.ts +0 -56
  244. package/src/node/targets/wx/dev-server/rolldown-runtime-source.ts +0 -95
  245. package/src/node/targets/wx/dev-server/update-server-state.ts +0 -183
  246. package/src/node/targets/wx/dev-server/update-transport.ts +0 -261
  247. package/src/node/targets/wx/dev-server/vite-bundled-dev-adapter.ts +0 -203
  248. package/src/node/targets/wx/development-files.ts +0 -11
  249. package/src/node/targets/wx/plugin.ts +0 -164
  250. package/src/node/targets/wx/react-refresh.ts +0 -51
  251. package/src/node/targets/wx/virtual-modules.ts +0 -152
  252. package/src/node/utils/async.ts +0 -19
  253. package/src/node/utils/filesystem.ts +0 -45
  254. package/src/runtime/taro/api.ts +0 -13
  255. package/src/runtime/taro/components.ts +0 -2
  256. package/src/runtime/wx/page-update.ts +0 -230
  257. package/src/runtime/wx/react-refresh.d.ts +0 -20
  258. package/src/runtime/wx/taro-runtime.ts +0 -7
  259. package/src/runtime/wx/update-client-state.ts +0 -138
  260. package/src/runtime/wx/update-client.ts +0 -223
@@ -1,62 +0,0 @@
1
- /** Full-build scheduling owned by one WX development session. */
2
-
3
- type FullBuildPhase = 'idle' | 'scheduled' | 'building' | 'building-with-pending-request' | 'closed'
4
-
5
- /** Coalesces trailing-edge requests while guaranteeing one full build at a time. */
6
- export class FullBuildScheduler {
7
- private readonly delay: number
8
- private readonly runBuild: () => Promise<void>
9
- private readonly reportError: (error: unknown) => void
10
- private phase: FullBuildPhase = 'idle'
11
- private timer: NodeJS.Timeout | undefined
12
- private work: Promise<void> | undefined
13
-
14
- constructor(delay: number, runBuild: () => Promise<void>, reportError: (error: unknown) => void) {
15
- this.delay = delay
16
- this.runBuild = runBuild
17
- this.reportError = reportError
18
- }
19
-
20
- request(): void {
21
- switch (this.phase) {
22
- case 'closed':
23
- return
24
- case 'building':
25
- this.phase = 'building-with-pending-request'
26
- return
27
- case 'building-with-pending-request':
28
- return
29
- case 'idle':
30
- case 'scheduled':
31
- if (this.timer) clearTimeout(this.timer)
32
- this.phase = 'scheduled'
33
- this.timer = setTimeout(() => this.start(), this.delay)
34
- }
35
- }
36
-
37
- async close(): Promise<void> {
38
- if (this.phase === 'closed') {
39
- await this.work
40
- return
41
- }
42
- this.phase = 'closed'
43
- if (this.timer) clearTimeout(this.timer)
44
- this.timer = undefined
45
- await this.work
46
- }
47
-
48
- private start(): void {
49
- if (this.phase !== 'scheduled') return
50
- this.timer = undefined
51
- this.phase = 'building'
52
- this.work = this.runBuild()
53
- .catch(this.reportError)
54
- .finally(() => {
55
- this.work = undefined
56
- if (this.phase === 'closed') return
57
- const repeat = this.phase === 'building-with-pending-request'
58
- this.phase = 'idle'
59
- if (repeat) this.request()
60
- })
61
- }
62
- }
@@ -1,33 +0,0 @@
1
- import { transformWithOxc } from 'vite'
2
- import type { WxOutputFile } from './output.ts'
3
-
4
- const wxJavaScriptTarget = 'es2018'
5
-
6
- /** Lowers generated JavaScript syntax that WeChat's upload parser does not accept. */
7
- export async function transformWxCompatibleJavaScript(code: string, filename: string): Promise<string> {
8
- const result = await transformWithOxc(code, filename, {
9
- lang: 'js',
10
- target: wxJavaScriptTarget,
11
- sourcemap: false,
12
- assumptions: {
13
- // Avoid external Oxc helpers when lowering public class fields in already-bundled chunks.
14
- setPublicClassFields: true
15
- }
16
- })
17
- return result.code
18
- }
19
-
20
- /** Applies the compatibility transform to every JavaScript chunk in a DevEngine output batch. */
21
- export async function transformWxOutputChunks(output: WxOutputFile[]): Promise<void> {
22
- await Promise.all(
23
- output.map(async (item, index) => {
24
- if (item.type !== 'chunk') return
25
- output[index] = {
26
- type: 'chunk',
27
- fileName: item.fileName,
28
- modules: item.modules,
29
- code: await transformWxCompatibleJavaScript(item.code, item.fileName)
30
- }
31
- })
32
- )
33
- }
@@ -1,56 +0,0 @@
1
- /**
2
- * Normalizes private DevEngine output before the development session writes it to the fixed WX project directory.
3
- * DevEngine rebuilds may be partial, so these helpers mutate only files present in the current output.
4
- */
5
-
6
- /** File shape emitted by Vite's private bundled-development engine. */
7
- export type WxOutputFile =
8
- | {
9
- type: 'chunk'
10
- fileName: string
11
- code: string
12
- modules?: Record<string, unknown>
13
- }
14
- | {
15
- type: 'asset'
16
- fileName: string
17
- source: string | Uint8Array
18
- }
19
-
20
- /** Extracts Vite's development CSS payloads and materializes them as app.wxss. */
21
- export function normalizeWxBundleStyles(output: WxOutputFile[]): string | undefined {
22
- const styles: string[] = []
23
- for (let index = output.length - 1; index >= 0; index--) {
24
- const item = output[index]
25
- if (!item) continue
26
- if (item.type === 'asset' && item.fileName.endsWith('.css')) {
27
- styles.unshift(typeof item.source === 'string' ? item.source : new TextDecoder().decode(item.source))
28
- output.splice(index, 1)
29
- } else if (item.type === 'chunk') {
30
- styles.push(...collectEmbeddedStyles(item.code))
31
- }
32
- }
33
- if (styles.length === 0) return
34
- const source = styles.join('\n')
35
- setWxAppStyles(output, source)
36
- return source
37
- }
38
-
39
- export function setWxAppStyles(output: WxOutputFile[], source: string): void {
40
- const index = output.findIndex((item) => item.type === 'asset' && item.fileName === 'app.wxss')
41
- const appStyle: WxOutputFile = { type: 'asset', fileName: 'app.wxss', source }
42
- if (index >= 0) output[index] = appStyle
43
- else output.push(appStyle)
44
- }
45
-
46
- export function isWxFullBuildOutput(output: WxOutputFile[]): boolean {
47
- return output.some((item) => item.fileName === 'app.js')
48
- }
49
-
50
- function collectEmbeddedStyles(code: string): string[] {
51
- const styles: string[] = []
52
- for (const match of code.matchAll(/__vite__css(?:\$\d+)?\s*=\s*("(?:\\.|[^"\\])*");/g)) {
53
- if (match[1]) styles.push(JSON.parse(match[1]) as string)
54
- }
55
- return styles
56
- }
@@ -1,95 +0,0 @@
1
- /**
2
- * Self-contained source injected into Rolldown's DevEngine as the WX module bootstrap runtime.
3
- *
4
- * This TypeScript module runs in Node and only exports source text. The exported JavaScript becomes
5
- * `runtime.js`, executes before every application module, and therefore cannot import Taro, React,
6
- * or any module that depends on the runtime it is creating.
7
- */
8
- export const wxRolldownRuntimeSource = `
9
- var BaseDevRuntime = DevRuntime;
10
- class WxHotContext {
11
- callbacks = [];
12
- data = {};
13
- _internal = { updateStyle() {}, removeStyle() {} };
14
- constructor(moduleId) { this.moduleId = moduleId; }
15
- accept(...args) {
16
- if (args.length === 0) {
17
- this.callbacks.push({ deps: this.moduleId, callback: undefined });
18
- } else if (args.length === 1 && typeof args[0] === 'function') {
19
- this.callbacks.push({ deps: this.moduleId, callback: args[0] });
20
- } else if (args.length === 1) {
21
- this.callbacks.push({ deps: args[0], callback: undefined });
22
- } else {
23
- this.callbacks.push({ deps: args[0], callback: args[1] });
24
- }
25
- }
26
- acceptExports(_exports, callback) { this.accept(callback); }
27
- dispose() {}
28
- prune() {}
29
- invalidate() {}
30
- on() {}
31
- off() {}
32
- send() {}
33
- }
34
- class WxRolldownRuntime extends BaseDevRuntime {
35
- contexts = new Map();
36
- patchedModules = new Set();
37
- applyingPatch = false;
38
-
39
- createEsmInitializer = (id, initialize, _deduplicate, result) => () => {
40
- if (!initialize) return result;
41
- if (!this.applyingPatch && this.patchedModules.has(id)) {
42
- initialize = undefined;
43
- return result;
44
- }
45
- const callback = initialize;
46
- initialize = undefined;
47
- result = callback(id);
48
- if (this.applyingPatch) this.patchedModules.add(id);
49
- return result;
50
- };
51
-
52
- createCjsInitializer = (id, initialize, _deduplicate, module) => () => {
53
- if (module) return module.exports;
54
- if (!this.applyingPatch && this.patchedModules.has(id)) return this.loadExports(id);
55
- module = { exports: {} };
56
- initialize(module.exports, module, id);
57
- if (this.applyingPatch) this.patchedModules.add(id);
58
- return module.exports;
59
- };
60
-
61
- createModuleHotContext(moduleId) {
62
- const previous = this.contexts.get(moduleId);
63
- const context = new WxHotContext(moduleId);
64
- if (previous) {
65
- context.callbacks = previous.callbacks;
66
- context.data = previous.data;
67
- }
68
- this.contexts.set(moduleId, context);
69
- return context;
70
- }
71
-
72
- beginPatch() { this.applyingPatch = true; }
73
- endPatch() { this.applyingPatch = false; }
74
-
75
- applyUpdates(boundaries) {
76
- for (const [boundary, acceptedVia] of boundaries) {
77
- const context = this.contexts.get(boundary);
78
- if (!context) continue;
79
- const callbacks = [...context.callbacks];
80
- if (boundary === acceptedVia) context.callbacks = [];
81
- for (const { deps, callback } of callbacks) {
82
- if (!callback) continue;
83
- if (Array.isArray(deps)) {
84
- if (deps.includes(acceptedVia)) callback(deps.map((id) => this.loadExports(id)));
85
- } else if (deps === acceptedVia) {
86
- callback(this.loadExports(acceptedVia));
87
- }
88
- }
89
- }
90
- }
91
- }
92
- // A full DevEngine runtime starts a new page-update generation before any application chunk executes.
93
- globalThis.__VITE_PLUGIN_TARO_WX_PAGE_UPDATE__ = { ready: false };
94
- globalThis.__rolldown_runtime__ = new WxRolldownRuntime(undefined, 'vite-plugin-taro-wx');
95
- `
@@ -1,183 +0,0 @@
1
- /**
2
- * Pure host-side stop-and-wait protocol state machine.
3
- *
4
- * It retains versioned Rolldown deltas and selects one missing range for the active App Service. HTTP and filesystem
5
- * effects are represented as commands and handled by update-transport.ts.
6
- */
7
- type WxUpdateDelta = {
8
- version: number
9
- code: string
10
- }
11
-
12
- export type WxUpdateBatch = {
13
- buildId: string
14
- sessionId: string
15
- fromVersion: number
16
- targetVersion: number
17
- deltas: WxUpdateDelta[]
18
- }
19
-
20
- type WxUpdateServerState = {
21
- buildId: string
22
- hostVersion: number
23
- retainedDeltaBytes: number
24
- deltas: WxUpdateDelta[]
25
- activeSessionId?: string
26
- retiredSessionIds: string[]
27
- inFlight?: Pick<WxUpdateBatch, 'sessionId' | 'fromVersion' | 'targetVersion'>
28
- }
29
-
30
- type WxUpdateServerEvent =
31
- | { type: 'delta-added'; code: string; bytes?: number }
32
- | { type: 'client-registered'; buildId: string; sessionId: string; version: number }
33
- | { type: 'client-reported'; buildId: string; sessionId: string; version: number }
34
- | { type: 'batch-publish-failed'; sessionId: string; targetVersion: number }
35
- | { type: 'full-build-committed'; buildId: string }
36
-
37
- export type WxUpdateServerCommand =
38
- | { type: 'publish-batch'; batch: WxUpdateBatch }
39
- | { type: 'request-full-build'; reason: 'client-version-ahead' | 'invalid-client-version' }
40
- | { type: 'ignore-client'; reason: 'stale-build' | 'retired-session' | 'unknown-session' }
41
-
42
- type WxUpdateServerTransition = {
43
- state: WxUpdateServerState
44
- commands: WxUpdateServerCommand[]
45
- }
46
-
47
- export function createWxUpdateServerState(buildId: string): WxUpdateServerState {
48
- return {
49
- buildId,
50
- hostVersion: 0,
51
- retainedDeltaBytes: 0,
52
- deltas: [],
53
- retiredSessionIds: []
54
- }
55
- }
56
-
57
- export function transitionWxUpdateServer(
58
- state: WxUpdateServerState,
59
- event: WxUpdateServerEvent
60
- ): WxUpdateServerTransition {
61
- switch (event.type) {
62
- case 'delta-added': {
63
- const version = state.hostVersion + 1
64
- return transition({
65
- ...state,
66
- hostVersion: version,
67
- retainedDeltaBytes: state.retainedDeltaBytes + (event.bytes ?? event.code.length),
68
- deltas: [...state.deltas, { version, code: event.code }]
69
- })
70
- }
71
- case 'client-registered':
72
- return registerClient(state, event)
73
- case 'client-reported':
74
- return reportClient(state, event)
75
- case 'batch-publish-failed':
76
- if (state.inFlight?.sessionId !== event.sessionId || state.inFlight.targetVersion !== event.targetVersion) {
77
- return transition(state)
78
- }
79
- return transition({ ...state, inFlight: undefined })
80
- case 'full-build-committed':
81
- return transition(createWxUpdateServerState(event.buildId))
82
- }
83
- }
84
-
85
- function registerClient(
86
- state: WxUpdateServerState,
87
- client: { buildId: string; sessionId: string; version: number }
88
- ): WxUpdateServerTransition {
89
- const rejected = rejectClient(state, client)
90
- if (rejected) return rejected
91
- if (state.retiredSessionIds.includes(client.sessionId)) {
92
- return command(state, { type: 'ignore-client', reason: 'retired-session' })
93
- }
94
- if (state.activeSessionId === client.sessionId) return transition(state)
95
-
96
- const retiredSessionIds = state.activeSessionId
97
- ? [...new Set([...state.retiredSessionIds, state.activeSessionId])]
98
- : state.retiredSessionIds
99
- const registered = {
100
- ...state,
101
- activeSessionId: client.sessionId,
102
- retiredSessionIds,
103
- inFlight: undefined
104
- }
105
- return transition(registered)
106
- }
107
-
108
- function reportClient(
109
- state: WxUpdateServerState,
110
- client: { buildId: string; sessionId: string; version: number }
111
- ): WxUpdateServerTransition {
112
- const rejected = rejectClient(state, client)
113
- if (rejected) return rejected
114
- if (state.retiredSessionIds.includes(client.sessionId)) {
115
- return command(state, { type: 'ignore-client', reason: 'retired-session' })
116
- }
117
- if (client.sessionId !== state.activeSessionId) {
118
- return command(state, { type: 'ignore-client', reason: 'unknown-session' })
119
- }
120
- return synchronizeClient(state, client.version)
121
- }
122
-
123
- function rejectClient(
124
- state: WxUpdateServerState,
125
- client: { buildId: string; version: number }
126
- ): WxUpdateServerTransition | undefined {
127
- if (client.buildId !== state.buildId) {
128
- return command(state, { type: 'ignore-client', reason: 'stale-build' })
129
- }
130
- if (!Number.isInteger(client.version) || client.version < 0) {
131
- return command(state, { type: 'request-full-build', reason: 'invalid-client-version' })
132
- }
133
- if (client.version > state.hostVersion) {
134
- return command(state, { type: 'request-full-build', reason: 'client-version-ahead' })
135
- }
136
- }
137
-
138
- function synchronizeClient(state: WxUpdateServerState, clientVersion: number): WxUpdateServerTransition {
139
- let synchronized = state
140
- const inFlight = state.inFlight
141
- if (inFlight) {
142
- if (clientVersion === inFlight.fromVersion) {
143
- const batch = createBatch(state, clientVersion, inFlight.targetVersion)
144
- return command(state, { type: 'publish-batch', batch })
145
- }
146
- if (clientVersion !== inFlight.targetVersion) {
147
- return command(state, { type: 'request-full-build', reason: 'invalid-client-version' })
148
- }
149
- synchronized = { ...state, inFlight: undefined }
150
- }
151
- if (clientVersion >= synchronized.hostVersion) return transition(synchronized)
152
-
153
- const batch = createBatch(synchronized, clientVersion, synchronized.hostVersion)
154
- return command(
155
- {
156
- ...synchronized,
157
- inFlight: {
158
- sessionId: batch.sessionId,
159
- fromVersion: batch.fromVersion,
160
- targetVersion: batch.targetVersion
161
- }
162
- },
163
- { type: 'publish-batch', batch }
164
- )
165
- }
166
-
167
- function createBatch(state: WxUpdateServerState, fromVersion: number, targetVersion: number): WxUpdateBatch {
168
- return {
169
- buildId: state.buildId,
170
- sessionId: state.activeSessionId!,
171
- fromVersion,
172
- targetVersion,
173
- deltas: state.deltas.filter((delta) => delta.version > fromVersion && delta.version <= targetVersion)
174
- }
175
- }
176
-
177
- function transition(state: WxUpdateServerState): WxUpdateServerTransition {
178
- return { state, commands: [] }
179
- }
180
-
181
- function command(state: WxUpdateServerState, value: WxUpdateServerCommand): WxUpdateServerTransition {
182
- return { state, commands: [value] }
183
- }
@@ -1,261 +0,0 @@
1
- /**
2
- * Adapts the pure server protocol to Vite HTTP middleware and literal update-file publication.
3
- * HTTP messages contain metadata only; executable JavaScript reaches DevTools through the injected file writer.
4
- */
5
- import { randomBytes } from 'node:crypto'
6
- import type { IncomingMessage, ServerResponse } from 'node:http'
7
- import type { ViteDevServer } from 'vite'
8
- import {
9
- createWxUpdateServerState,
10
- transitionWxUpdateServer,
11
- type WxUpdateBatch,
12
- type WxUpdateServerCommand
13
- } from './update-server-state.ts'
14
-
15
- const endpointPath = '/__vite_plugin_taro_wx_update__'
16
- // Keep the host response below update-client.ts's 30-second wx.request timeout.
17
- const pollTimeout = 25_000
18
-
19
- type PendingPoll = {
20
- response: ServerResponse
21
- timeout: NodeJS.Timeout
22
- }
23
-
24
- type UpdateRequest = {
25
- token?: unknown
26
- action?: unknown
27
- buildId?: unknown
28
- sessionId?: unknown
29
- version?: unknown
30
- }
31
-
32
- export class WxUpdateTransport {
33
- private state = createWxUpdateServerState(createId())
34
- private readonly token = createId()
35
- private readonly pendingPolls = new Map<string, PendingPoll>()
36
- private closed = false
37
-
38
- constructor(
39
- private readonly server: ViteDevServer,
40
- private readonly requestFullBuild: () => void,
41
- private readonly writeUpdateFile: (buildId: string, source: string) => Promise<void>
42
- ) {}
43
-
44
- get retainedDeltaCount(): number {
45
- return this.state.hostVersion
46
- }
47
-
48
- get retainedDeltaBytes(): number {
49
- return this.state.retainedDeltaBytes
50
- }
51
-
52
- install(): void {
53
- this.server.middlewares.use(endpointPath, this.handleRequest)
54
- }
55
-
56
- close(): void {
57
- this.closed = true
58
- this.respondToAll({ type: 'rebuilding' })
59
- }
60
-
61
- addDelta(code: string): void {
62
- this.apply({ type: 'delta-added', code, bytes: Buffer.byteLength(code) })
63
- this.respondToAll({ type: 'changed' })
64
- }
65
-
66
- createBuildId(): string {
67
- return createId()
68
- }
69
-
70
- isCurrentBuild(buildId: string): boolean {
71
- return this.state.buildId === buildId
72
- }
73
-
74
- commitFullBuild(buildId: string): void {
75
- this.apply({ type: 'full-build-committed', buildId })
76
- this.respondToAll({ type: 'rebuilding' })
77
- }
78
-
79
- /** Generates late-bound App metadata after Vite has selected its actual listening port. */
80
- createControlSource(buildId = this.state.buildId): string {
81
- const address = this.server.httpServer?.address()
82
- const port = address && typeof address !== 'string' ? address.port : this.server.config.server.port
83
- return `globalThis.__VITE_PLUGIN_TARO_WX_CONTROL__ = ${JSON.stringify({
84
- url: `http://localhost:${port}${endpointPath}`,
85
- token: this.token,
86
- buildId
87
- })};\n`
88
- }
89
-
90
- private readonly handleRequest = async (request: IncomingMessage, response: ServerResponse): Promise<void> => {
91
- if (this.closed || request.method !== 'POST') {
92
- respond(response, 404, { type: 'not-found' })
93
- return
94
- }
95
-
96
- let body: UpdateRequest
97
- try {
98
- body = JSON.parse(await readBody(request)) as UpdateRequest
99
- } catch {
100
- respond(response, 400, { type: 'invalid-request' })
101
- return
102
- }
103
- if (body.token !== this.token || !isClientReport(body)) {
104
- respond(response, 403, { type: 'forbidden' })
105
- return
106
- }
107
-
108
- if (body.action === 'rebuild') {
109
- this.requestFullBuild()
110
- respond(response, 202, { type: 'rebuilding' })
111
- return
112
- }
113
- if (body.action === 'register') {
114
- const transition = this.apply({
115
- type: 'client-registered',
116
- buildId: body.buildId,
117
- sessionId: body.sessionId,
118
- version: body.version
119
- })
120
- if (transition.some((command) => command.type === 'request-full-build')) this.requestFullBuild()
121
- respond(response, 200, { type: 'registered' })
122
- return
123
- }
124
- if (body.action !== 'poll') {
125
- respond(response, 400, { type: 'invalid-request' })
126
- return
127
- }
128
-
129
- const commands = this.apply({
130
- type: 'client-reported',
131
- buildId: body.buildId,
132
- sessionId: body.sessionId,
133
- version: body.version
134
- })
135
- await this.executePollCommands(body.sessionId, commands, response)
136
- }
137
-
138
- private async executePollCommands(
139
- sessionId: string,
140
- commands: WxUpdateServerCommand[],
141
- response: ServerResponse
142
- ): Promise<void> {
143
- const publish = commands.find((command) => command.type === 'publish-batch')
144
- if (publish?.type === 'publish-batch') {
145
- try {
146
- await this.writeBatch(publish.batch)
147
- respond(response, 200, { type: 'batch-published', targetVersion: publish.batch.targetVersion })
148
- } catch {
149
- this.apply({
150
- type: 'batch-publish-failed',
151
- sessionId: publish.batch.sessionId,
152
- targetVersion: publish.batch.targetVersion
153
- })
154
- respond(response, 500, { type: 'publish-failed' })
155
- }
156
- return
157
- }
158
- if (commands.some((command) => command.type === 'request-full-build')) {
159
- this.requestFullBuild()
160
- respond(response, 202, { type: 'rebuilding' })
161
- return
162
- }
163
- if (commands.some((command) => command.type === 'ignore-client')) {
164
- respond(response, 409, { type: 'rebuilding' })
165
- return
166
- }
167
- this.holdPoll(sessionId, response)
168
- }
169
-
170
- private holdPoll(sessionId: string, response: ServerResponse): void {
171
- const previous = this.pendingPolls.get(sessionId)
172
- if (previous) this.finishPoll(sessionId, previous, { type: 'changed' })
173
-
174
- let pending: PendingPoll
175
- pending = {
176
- response,
177
- timeout: setTimeout(() => this.finishPoll(sessionId, pending, { type: 'idle' }), pollTimeout)
178
- }
179
- this.pendingPolls.set(sessionId, pending)
180
- response.on('close', () => this.finishPoll(sessionId, pending))
181
- }
182
-
183
- private respondToAll(value: { type: string }): void {
184
- for (const [sessionId, pending] of this.pendingPolls) this.finishPoll(sessionId, pending, value)
185
- }
186
-
187
- private finishPoll(sessionId: string, pending: PendingPoll, value?: { type: string }): void {
188
- if (this.pendingPolls.get(sessionId) !== pending) return
189
- clearTimeout(pending.timeout)
190
- this.pendingPolls.delete(sessionId)
191
- if (value) respond(pending.response, 200, value)
192
- }
193
-
194
- private apply(event: Parameters<typeof transitionWxUpdateServer>[1]): WxUpdateServerCommand[] {
195
- const transition = transitionWxUpdateServer(this.state, event)
196
- this.state = transition.state
197
- return transition.commands
198
- }
199
-
200
- private async writeBatch(batch: WxUpdateBatch): Promise<void> {
201
- await this.writeUpdateFile(batch.buildId, renderBatch(batch, createId()))
202
- }
203
- }
204
-
205
- /** Renders executable code for update.js; this source is never included in an HTTP response. */
206
- function renderBatch(batch: WxUpdateBatch, nonce: string): string {
207
- return `// ${nonce}\nglobalThis.__VITE_PLUGIN_TARO_WX_UPDATE_CLIENT__.receiveBatch(${JSON.stringify({
208
- buildId: batch.buildId,
209
- fromVersion: batch.fromVersion,
210
- targetVersion: batch.targetVersion
211
- })}, () => {
212
- ${indent(batch.deltas.map((delta) => delta.code).join('\n'), 4)}
213
- });\n`
214
- }
215
-
216
- function indent(value: string, spaces: number): string {
217
- const prefix = ' '.repeat(spaces)
218
- return value
219
- .split('\n')
220
- .map((line) => `${prefix}${line}`)
221
- .join('\n')
222
- }
223
-
224
- function isClientReport(value: UpdateRequest): value is {
225
- token: string
226
- action: 'register' | 'poll' | 'rebuild'
227
- buildId: string
228
- sessionId: string
229
- version: number
230
- } {
231
- return (
232
- typeof value.token === 'string' &&
233
- typeof value.action === 'string' &&
234
- typeof value.buildId === 'string' &&
235
- typeof value.sessionId === 'string' &&
236
- typeof value.version === 'number'
237
- )
238
- }
239
-
240
- async function readBody(request: IncomingMessage): Promise<string> {
241
- const chunks: Buffer[] = []
242
- let size = 0
243
- for await (const chunk of request) {
244
- const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)
245
- size += buffer.length
246
- if (size > 64 * 1024) throw new Error('WX update request body is too large.')
247
- chunks.push(buffer)
248
- }
249
- return Buffer.concat(chunks).toString('utf8')
250
- }
251
-
252
- function respond(response: ServerResponse, status: number, body: unknown): void {
253
- if (response.writableEnded) return
254
- response.statusCode = status
255
- response.setHeader('content-type', 'application/json')
256
- response.end(JSON.stringify(body))
257
- }
258
-
259
- function createId(): string {
260
- return randomBytes(16).toString('hex')
261
- }