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
@@ -0,0 +1,86 @@
1
+ import { type PluginObject, types } from '@babel/core'
2
+ import { resolveChunkReference } from '../../../utils/modules.ts'
3
+
4
+ /** Wraps System.register as an inert CommonJS capsule tuple with canonical final dependency IDs. */
5
+ export function wrapCapsulePlugin(fileName: string): PluginObject {
6
+ return {
7
+ name: 'vpt:wrap-capsule',
8
+ visitor: {},
9
+
10
+ post(file) {
11
+ const program = file.ast.program
12
+ const [statement] = program.body
13
+ const registration = statement && types.isExpressionStatement(statement) ? statement.expression : undefined
14
+
15
+ if (
16
+ program.body.length !== 1 ||
17
+ !types.isCallExpression(registration) ||
18
+ !types.isMemberExpression(registration.callee) ||
19
+ registration.callee.computed ||
20
+ !types.isIdentifier(registration.callee.object, { name: 'System' }) ||
21
+ !types.isIdentifier(registration.callee.property, { name: 'register' })
22
+ ) {
23
+ throw new Error(`Expected one anonymous System.register call in ${fileName}`)
24
+ }
25
+
26
+ const [dependencies, declaration] = registration.arguments
27
+ if (
28
+ registration.arguments.length !== 2 ||
29
+ !types.isArrayExpression(dependencies) ||
30
+ !types.isFunctionExpression(declaration)
31
+ ) {
32
+ throw new Error(`Expected System.register(dependencies, declaration) in ${fileName}`)
33
+ }
34
+
35
+ dependencies.elements.forEach((dependency) => {
36
+ canonicalizeStaticReference(dependency, fileName)
37
+ })
38
+
39
+ const context = declaration.params[1]
40
+ if (types.isIdentifier(context)) {
41
+ file.path.traverse({
42
+ CallExpression(callPath) {
43
+ const callee = callPath.node.callee
44
+ if (
45
+ !types.isMemberExpression(callee) ||
46
+ callee.computed ||
47
+ !types.isIdentifier(callee.object, { name: context.name }) ||
48
+ !types.isIdentifier(callee.property, { name: 'import' })
49
+ ) {
50
+ return
51
+ }
52
+
53
+ const [dependency] = callPath.node.arguments
54
+ canonicalizeDynamicReference(dependency, fileName)
55
+ }
56
+ })
57
+ }
58
+
59
+ program.directives = []
60
+ program.body = [
61
+ types.expressionStatement(
62
+ types.assignmentExpression(
63
+ '=',
64
+ types.memberExpression(types.identifier('module'), types.identifier('exports')),
65
+ types.arrayExpression([dependencies, declaration])
66
+ )
67
+ )
68
+ ]
69
+ }
70
+ }
71
+ }
72
+
73
+ /** Resolves one generated static reference while the final importing chunk filename is known. */
74
+ function canonicalizeStaticReference(reference: types.Node | null | undefined, fileName: string): void {
75
+ if (!types.isStringLiteral(reference)) {
76
+ throw new Error(`Expected a literal System.register dependency in ${fileName}`)
77
+ }
78
+ reference.value = resolveChunkReference(fileName, reference.value)
79
+ }
80
+
81
+ /** Resolves application literals while preserving runtime-computed IDs injected by the development runtime. */
82
+ function canonicalizeDynamicReference(reference: types.Node | null | undefined, fileName: string): void {
83
+ if (types.isStringLiteral(reference) && (reference.value.startsWith('./') || reference.value.startsWith('../'))) {
84
+ reference.value = resolveChunkReference(fileName, reference.value)
85
+ }
86
+ }
@@ -0,0 +1,21 @@
1
+ import type { PluginTarget } from '@babel/core'
2
+ import transformDynamicImport from '@babel/plugin-transform-dynamic-import'
3
+ import transformModulesSystemjs from '@babel/plugin-transform-modules-systemjs'
4
+ import type { Rolldown } from 'vite'
5
+ import { type AstTransformResult, transformWithBabel } from '../../../utils/transform.ts'
6
+ import { wrapCapsulePlugin } from './capsule-wrapper.ts'
7
+
8
+ /** Renders one ESM chunk as an inert SystemJS capsule. */
9
+ export function renderCapsule(code: string, chunk: Rolldown.RenderedChunk, sourcemap = true): AstTransformResult {
10
+ return transformWithBabel(
11
+ code,
12
+ chunk.fileName,
13
+ [
14
+ transformDynamicImport,
15
+ // Erase Babel's internal plugin pass type.
16
+ transformModulesSystemjs as PluginTarget,
17
+ wrapCapsulePlugin(chunk.fileName) as PluginTarget
18
+ ],
19
+ sourcemap
20
+ )
21
+ }
@@ -0,0 +1,84 @@
1
+ import { type PluginObject, type PluginTarget, types } from '@babel/core'
2
+ import transformModulesCommonjs from '@babel/plugin-transform-modules-commonjs'
3
+ import type { Rolldown } from 'vite'
4
+ import { resolveChunkReference } from '../../../utils/modules.ts'
5
+ import { type AstTransformResult, transformWithBabel } from '../../../utils/transform.ts'
6
+ import { getWxEntryRole } from '../module.ts'
7
+
8
+ /** Renders a native module while activating its statically imported capsules through SystemJS. */
9
+ export function renderNative({
10
+ code,
11
+ chunk,
12
+ chunks,
13
+ sourcemap
14
+ }: {
15
+ code: string
16
+ chunk: Rolldown.RenderedChunk
17
+ chunks: Readonly<Record<string, Rolldown.RenderedChunk>>
18
+ sourcemap: boolean
19
+ }): AstTransformResult {
20
+ return transformWithBabel(
21
+ code,
22
+ chunk.fileName,
23
+ [connectNativeCapsulesPlugin(chunk.fileName, chunks) as PluginTarget, transformModulesCommonjs as PluginTarget],
24
+ sourcemap
25
+ )
26
+ }
27
+
28
+ /** Converts only cross-runtime static imports; ordinary native dependencies remain CommonJS imports. */
29
+ function connectNativeCapsulesPlugin(
30
+ fileName: string,
31
+ chunks: Readonly<Record<string, Rolldown.RenderedChunk>>
32
+ ): PluginObject {
33
+ return {
34
+ name: 'vpt:connect-native-capsules',
35
+ visitor: {
36
+ ImportDeclaration(importPath) {
37
+ const reference = importPath.node.source.value
38
+ if (!reference.startsWith('./') && !reference.startsWith('../')) {
39
+ return
40
+ }
41
+
42
+ const chunkId = resolveChunkReference(fileName, reference)
43
+ const importedChunk = chunks[chunkId]
44
+ if (!importedChunk || getWxEntryRole(importedChunk) !== 'capsule') {
45
+ return
46
+ }
47
+
48
+ const [specifier] = importPath.node.specifiers
49
+ if (
50
+ importPath.node.specifiers.length !== 1 ||
51
+ !specifier ||
52
+ types.isImportNamespaceSpecifier(specifier)
53
+ ) {
54
+ throw new Error(`Expected one capsule value import from ${chunkId} in ${fileName}`)
55
+ }
56
+
57
+ const imported = types.isImportDefaultSpecifier(specifier)
58
+ ? types.identifier('default')
59
+ : specifier.imported
60
+ const importedConfig = types.memberExpression(
61
+ createSyncImport(chunkId),
62
+ types.cloneNode(imported),
63
+ types.isStringLiteral(imported)
64
+ )
65
+ importPath.replaceWith(
66
+ types.variableDeclaration('const', [
67
+ types.variableDeclarator(types.cloneNode(specifier.local), importedConfig)
68
+ ])
69
+ )
70
+ }
71
+ }
72
+ }
73
+ }
74
+
75
+ /** Creates one synchronous lookup through the canonical output chunk ID. */
76
+ function createSyncImport(chunkId: string): types.CallExpression {
77
+ return types.callExpression(
78
+ types.memberExpression(
79
+ types.memberExpression(types.identifier('global'), types.identifier('System')),
80
+ types.identifier('importSync')
81
+ ),
82
+ [types.stringLiteral(chunkId)]
83
+ )
84
+ }
@@ -0,0 +1,157 @@
1
+ import path from 'node:path'
2
+ import { types } from '@babel/core'
3
+ import type { Rolldown } from 'vite'
4
+ import { type AstTransformResult, replaceWithAst } from '../../../utils/transform.ts'
5
+ import { getWxExecutionKind } from '../module.ts'
6
+
7
+ const transportPlaceholder = '__VITE_PLUGIN_TARO_TRANSPORT__'
8
+ const moduleIdParameter = 'moduleId'
9
+ const exportBindingParameter = 'exportBinding'
10
+
11
+ type TransportedChunk = {
12
+ chunk: Rolldown.RenderedChunk
13
+ kind: 'capsule' | 'amphibious'
14
+ }
15
+
16
+ /**
17
+ * Materializes transport while Rolldown's preliminary hash placeholders are still active, so every injected physical
18
+ * reference participates in final hash calculation instead of changing code after its filename has been fixed.
19
+ *
20
+ * This intentionally creates broad hash invalidation: changing one capsule can rename transport, then bootstrap, then
21
+ * chunks that import bootstrap. A Mini Program ships one application package rather than independently cached HTTP
22
+ * chunks, so honest content hashes and automatic graph linking are more valuable than minimizing that hash fan-out.
23
+ */
24
+ export async function materializeTransport({
25
+ code,
26
+ transportChunk,
27
+ chunks,
28
+ getLoadMode,
29
+ sourcemap = true
30
+ }: {
31
+ code: string
32
+ transportChunk: Rolldown.RenderedChunk
33
+ chunks: Readonly<Record<string, Rolldown.RenderedChunk>>
34
+ getLoadMode(chunk: Rolldown.RenderedChunk): 'sync' | 'async'
35
+ sourcemap?: boolean
36
+ }): Promise<AstTransformResult> {
37
+ // Babel constructs and safely serializes an expression shaped like:
38
+ // (moduleId) => {
39
+ // switch (moduleId) {
40
+ // case 'assets/app.js': return require('./app.js')
41
+ // case 'sub/p_account/page.js': return require.async('../sub/p_account/page.js')
42
+ // case 'assets/bootstrap.js':
43
+ // return [[], (exportBinding) => ({ execute() { exportBinding(require('./bootstrap.js')) } })]
44
+ // default: throw new Error(`Unknown System module: ${moduleId}`)
45
+ // }
46
+ // }
47
+ const cases = getTransportedChunks(chunks)
48
+ .sort((left, right) => left.chunk.fileName.localeCompare(right.chunk.fileName))
49
+ .map(({ chunk, kind }) => {
50
+ const loadMode = getLoadMode(chunk)
51
+ if (kind === 'amphibious' && loadMode !== 'sync') {
52
+ throw new Error(`Amphibious wx module must be in the main package: ${chunk.fileName}`)
53
+ }
54
+
55
+ return createTransportCase({
56
+ chunkId: chunk.fileName,
57
+ transportFileName: transportChunk.fileName,
58
+ loadMode,
59
+ kind
60
+ })
61
+ })
62
+
63
+ return await replaceWithAst(
64
+ code,
65
+ transportChunk.fileName,
66
+ {
67
+ [transportPlaceholder]: types.arrowFunctionExpression(
68
+ [types.identifier(moduleIdParameter)],
69
+ types.blockStatement([
70
+ types.switchStatement(types.identifier(moduleIdParameter), [
71
+ ...cases,
72
+ createUnknownModuleCase(moduleIdParameter)
73
+ ])
74
+ ])
75
+ )
76
+ },
77
+ sourcemap
78
+ )
79
+ }
80
+
81
+ /** Keeps only capsule and amphibious chunks and carries their narrowed kind into source generation. */
82
+ function getTransportedChunks(chunks: Readonly<Record<string, Rolldown.RenderedChunk>>): TransportedChunk[] {
83
+ const transportedChunks: TransportedChunk[] = []
84
+
85
+ for (const chunk of Object.values(chunks)) {
86
+ const kind = getWxExecutionKind(chunk)
87
+ if (kind !== 'native') {
88
+ transportedChunks.push({ chunk, kind })
89
+ }
90
+ }
91
+
92
+ return transportedChunks
93
+ }
94
+
95
+ /** Creates one canonical-ID switch case while keeping its native require argument literal. */
96
+ function createTransportCase({
97
+ chunkId,
98
+ transportFileName,
99
+ loadMode,
100
+ kind
101
+ }: {
102
+ chunkId: string
103
+ transportFileName: string
104
+ loadMode: 'sync' | 'async'
105
+ kind: 'capsule' | 'amphibious'
106
+ }): ReturnType<typeof types.switchCase> {
107
+ const requirePath = toNativeRequirePath(transportFileName, chunkId)
108
+
109
+ const requireCallee =
110
+ loadMode === 'sync'
111
+ ? types.identifier('require')
112
+ : types.memberExpression(types.identifier('require'), types.identifier('async'))
113
+
114
+ const loadedModule = types.callExpression(requireCallee, [types.stringLiteral(requirePath)])
115
+ const registration = kind === 'capsule' ? loadedModule : createAmphibiousRegistrationExpression(loadedModule)
116
+
117
+ return types.switchCase(types.stringLiteral(chunkId), [types.returnStatement(registration)])
118
+ }
119
+
120
+ /** Creates a registration that loads and publishes an amphibious CommonJS namespace only when executed. */
121
+ function createAmphibiousRegistrationExpression(namespace: types.Expression): ReturnType<typeof types.arrayExpression> {
122
+ return types.arrayExpression([
123
+ types.arrayExpression([]),
124
+ types.arrowFunctionExpression(
125
+ [types.identifier(exportBindingParameter)],
126
+ types.objectExpression([
127
+ types.objectMethod(
128
+ 'method',
129
+ types.identifier('execute'),
130
+ [],
131
+ types.blockStatement([
132
+ types.expressionStatement(
133
+ types.callExpression(types.identifier(exportBindingParameter), [namespace])
134
+ )
135
+ ])
136
+ )
137
+ ])
138
+ )
139
+ ])
140
+ }
141
+
142
+ /** Rejects module IDs absent from the closed output graph. */
143
+ function createUnknownModuleCase(moduleId: string): ReturnType<typeof types.switchCase> {
144
+ return types.switchCase(null, [
145
+ types.throwStatement(
146
+ types.newExpression(types.identifier('Error'), [
147
+ types.binaryExpression('+', types.stringLiteral('Unknown System module: '), types.identifier(moduleId))
148
+ ])
149
+ )
150
+ ])
151
+ }
152
+
153
+ /** Converts one preliminary output path to a literal require path relative to transport. */
154
+ function toNativeRequirePath(fromFileName: string, toFileName: string): string {
155
+ const relativePath = path.posix.relative(path.posix.dirname(fromFileName), toFileName)
156
+ return relativePath.startsWith('.') ? relativePath : `./${relativePath}`
157
+ }
@@ -0,0 +1,125 @@
1
+ import type { VitePluginTaroOptions, VitePluginTaroPageOption } from '../../../../options.ts'
2
+ import { normalizeModuleId, resolveAppComponentPath, resolvePageComponentPath } from '../../../utils/modules.ts'
3
+ import { createAppConfig } from '../../../utils/project-config.ts'
4
+ import { appComponentId } from '../../client/constant.ts'
5
+ import {
6
+ appCapsulePath,
7
+ appShellFileName,
8
+ appShellPath,
9
+ bootstrapPath,
10
+ componentCapsulePath,
11
+ componentShellFileName,
12
+ componentShellPath,
13
+ pageCapsuleId,
14
+ pageCapsulePath,
15
+ pageComponentId,
16
+ pageShellPath,
17
+ transportPath,
18
+ vitePreloadId
19
+ } from '../module.ts'
20
+ import { specializeBootstrap } from './specialize-bootstrap.ts'
21
+ import { specializePageCapsule } from './specialize-page-capsule.ts'
22
+
23
+ /** Resolves one exact plugin-private ID using its importer and configured project root. */
24
+ type PrivateIdResolver = (importer: string | undefined, projectRoot: string) => string
25
+
26
+ /** Creates the resolver and source specializer for the wx module graph. */
27
+ export function createResolver(options: VitePluginTaroOptions) {
28
+ const normalizedBootstrapPath = normalizeModuleId(bootstrapPath)
29
+ const normalizedPageCapsulePath = normalizeModuleId(pageCapsulePath)
30
+
31
+ // Provide constant-time route validation and access to each configured Page JSON object.
32
+ const pageByPath = new Map(options.pages.map((page) => [page.path, page]))
33
+
34
+ const privateIdResolvers = new Map<string, PrivateIdResolver>([
35
+ // Share bootstrap's preload identity through native require and its amphibious SystemJS registration.
36
+ [vitePreloadId, () => bootstrapPath],
37
+ // Keep the configured App component behind one stable private import in the App capsule.
38
+ [appComponentId, (_importer, projectRoot) => resolveAppComponentPath({ appPath: options.app, projectRoot })],
39
+ [
40
+ pageComponentId,
41
+ (importer, projectRoot) => {
42
+ const page = requireConfiguredPage({ moduleId: importer, pageByPath })
43
+
44
+ return resolvePageComponentPath({ pagePath: page.path, projectRoot })
45
+ }
46
+ ],
47
+ [
48
+ pageCapsuleId,
49
+ (importer) => {
50
+ // Query-qualify the capsule source so every Page retains a distinct graph identity.
51
+ const page = requireConfiguredPage({ moduleId: importer, pageByPath })
52
+
53
+ return createRouteModuleId({ moduleId: pageCapsulePath, pagePath: page.path })
54
+ }
55
+ ]
56
+ ])
57
+
58
+ return {
59
+ input: createInput(options.pages),
60
+
61
+ resolveId(id: string, importer: string | undefined, projectRoot: string): string | undefined {
62
+ // Unknown IDs fall through so Vite and other plugins retain normal resolution.
63
+ return privateIdResolvers.get(id)?.(importer, projectRoot)
64
+ },
65
+
66
+ specialize(code: string, id: string, sourcemap = true) {
67
+ const normalizedId = normalizeModuleId(id)
68
+
69
+ if (normalizedId === normalizedBootstrapPath) {
70
+ return specializeBootstrap({ code, id, appConfig: createAppConfig(options), sourcemap })
71
+ }
72
+
73
+ if (normalizedId === normalizedPageCapsulePath) {
74
+ return specializePageCapsule({
75
+ code,
76
+ id,
77
+ page: requireConfiguredPage({ moduleId: id, pageByPath }),
78
+ sourcemap
79
+ })
80
+ }
81
+ }
82
+ }
83
+ }
84
+
85
+ /** Declares native shells, infrastructure, and capsules as independent output entries. */
86
+ function createInput(pages: readonly VitePluginTaroPageOption[]): Record<string, string> {
87
+ return Object.fromEntries([
88
+ ['bootstrap', bootstrapPath],
89
+ ['transport', transportPath],
90
+ [appShellFileName, appShellPath],
91
+ ['app-capsule', appCapsulePath],
92
+ [componentShellFileName, componentShellPath],
93
+ ['component-capsule', componentCapsulePath],
94
+ ...pages.flatMap((page) => {
95
+ return [
96
+ [`${page.path}.js`, createRouteModuleId({ moduleId: pageShellPath, pagePath: page.path })],
97
+ [`${page.path}-capsule`, createRouteModuleId({ moduleId: pageCapsulePath, pagePath: page.path })]
98
+ ]
99
+ })
100
+ ])
101
+ }
102
+
103
+ /** Creates one route-qualified module ID. */
104
+ function createRouteModuleId({ moduleId, pagePath }: { moduleId: string; pagePath: string }): string {
105
+ return `${moduleId}?route=${encodeURIComponent(pagePath)}`
106
+ }
107
+
108
+ /** Returns the configured Page identified by a route-qualified capsule ID. */
109
+ function requireConfiguredPage({
110
+ moduleId,
111
+ pageByPath
112
+ }: {
113
+ moduleId: string | undefined
114
+ pageByPath: ReadonlyMap<string, VitePluginTaroPageOption>
115
+ }): VitePluginTaroPageOption {
116
+ const queryIndex = moduleId?.indexOf('?') ?? -1
117
+ const pagePath = queryIndex === -1 ? undefined : new URLSearchParams(moduleId?.slice(queryIndex + 1)).get('route')
118
+ const page = pagePath ? pageByPath.get(pagePath) : undefined
119
+ if (!page) {
120
+ throw new Error(
121
+ pagePath ? `Unknown Page capsule: ${pagePath}` : 'Page capsule import must originate from a route module'
122
+ )
123
+ }
124
+ return page
125
+ }
@@ -0,0 +1,27 @@
1
+ import { types } from '@babel/core'
2
+ import type { JsonObject } from '../../../../options.ts'
3
+ import { type AstTransformResult, replaceWithAst } from '../../../utils/transform.ts'
4
+
5
+ const appConfigPlaceholder = '__VITE_PLUGIN_TARO_APP_CONFIG__'
6
+
7
+ /** Specializes the amphibious bootstrap with the shared App configuration. */
8
+ export function specializeBootstrap({
9
+ code,
10
+ id,
11
+ appConfig,
12
+ sourcemap = true
13
+ }: {
14
+ code: string
15
+ id: string
16
+ appConfig: JsonObject
17
+ sourcemap?: boolean
18
+ }): Promise<AstTransformResult> {
19
+ return replaceWithAst(
20
+ code,
21
+ id,
22
+ {
23
+ [appConfigPlaceholder]: types.valueToNode(appConfig)
24
+ },
25
+ sourcemap
26
+ )
27
+ }
@@ -0,0 +1,29 @@
1
+ import { types } from '@babel/core'
2
+ import type { VitePluginTaroPageOption } from '../../../../options.ts'
3
+ import { type AstTransformResult, replaceWithAst } from '../../../utils/transform.ts'
4
+
5
+ const pagePathPlaceholder = '__VITE_PLUGIN_TARO_PAGE_PATH__'
6
+ const pageConfigPlaceholder = '__VITE_PLUGIN_TARO_PAGE_CONFIG__'
7
+
8
+ /** Specializes the Page capsule for one configured route. */
9
+ export function specializePageCapsule({
10
+ code,
11
+ id,
12
+ page,
13
+ sourcemap = true
14
+ }: {
15
+ code: string
16
+ id: string
17
+ page: VitePluginTaroPageOption
18
+ sourcemap?: boolean
19
+ }): Promise<AstTransformResult> {
20
+ return replaceWithAst(
21
+ code,
22
+ id,
23
+ {
24
+ [pagePathPlaceholder]: types.stringLiteral(page.path),
25
+ [pageConfigPlaceholder]: types.valueToNode(page.config)
26
+ },
27
+ sourcemap
28
+ )
29
+ }
@@ -0,0 +1 @@
1
+ export const esTarget = 'es2018'
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Creates a memoized version of the provided function. The memoized function caches
3
+ * results based on the argument it receives, so if the same argument is passed again,
4
+ * it returns the cached result instead of recomputing it.
5
+ *
6
+ * This function works with functions that take zero or just one argument. If your function
7
+ * originally takes multiple arguments, you should refactor it to take a single object or array
8
+ * that combines those arguments.
9
+ *
10
+ * If the argument is not primitive (e.g., arrays or objects), provide a
11
+ * `getCacheKey` function to generate a unique cache key for proper caching.
12
+ *
13
+ * @template F - The type of the function to be memoized.
14
+ * @param fn - The function to be memoized. It should accept a single argument and return a value.
15
+ * @param [options={}] - Optional configuration for the memoization.
16
+ * @param [options.cache] - The cache object used to store results. Defaults to a new `Map`.
17
+ * @param [options.getCacheKey] - An optional function to generate a unique cache key for each argument.
18
+ *
19
+ * @returns The memoized function with an additional `cache` property that exposes the internal cache.
20
+ *
21
+ * @example
22
+ * // Example using the default cache
23
+ * const add = (x: number) => x + 10;
24
+ * const memoizedAdd = memoize(add);
25
+ *
26
+ * console.log(memoizedAdd(5)); // 15
27
+ * console.log(memoizedAdd(5)); // 15 (cached result)
28
+ * console.log(memoizedAdd.cache.size); // 1
29
+ *
30
+ * @example
31
+ * // Example using a custom resolver
32
+ * const sum = (arr: number[]) => arr.reduce((x, y) => x + y, 0);
33
+ * const memoizedSum = memoize(sum, { getCacheKey: (arr: number[]) => arr.join(',') });
34
+ * console.log(memoizedSum([1, 2])); // 3
35
+ * console.log(memoizedSum([1, 2])); // 3 (cached result)
36
+ * console.log(memoizedSum.cache.size); // 1
37
+ *
38
+ * @example
39
+ * // Example using a custom cache implementation
40
+ * class CustomCache<K, T> implements MemoizeCache<K, T> {
41
+ * private cache = new Map<K, T>();
42
+ *
43
+ * set(key: K, value: T): void {
44
+ * this.cache.set(key, value);
45
+ * }
46
+ *
47
+ * get(key: K): T | undefined {
48
+ * return this.cache.get(key);
49
+ * }
50
+ *
51
+ * has(key: K): boolean {
52
+ * return this.cache.has(key);
53
+ * }
54
+ *
55
+ * delete(key: K): boolean {
56
+ * return this.cache.delete(key);
57
+ * }
58
+ *
59
+ * clear(): void {
60
+ * this.cache.clear();
61
+ * }
62
+ *
63
+ * get size(): number {
64
+ * return this.cache.size;
65
+ * }
66
+ * }
67
+ * const customCache = new CustomCache<string, number>();
68
+ * const memoizedSumWithCustomCache = memoize(sum, { cache: customCache });
69
+ * console.log(memoizedSumWithCustomCache([1, 2])); // 3
70
+ * console.log(memoizedSumWithCustomCache([1, 2])); // 3 (cached result)
71
+ * console.log(memoizedSumWithCustomCache.cache.size); // 1
72
+ */
73
+ export function memoize<F extends (arg: never) => unknown>(
74
+ fn: F,
75
+ options: {
76
+ cache?: MemoizeCache<unknown, ReturnType<F>>
77
+ getCacheKey?: (arg: Parameters<F>[0]) => unknown
78
+ } = {}
79
+ ): F & { cache: MemoizeCache<unknown, ReturnType<F>> } {
80
+ const { cache = new Map<unknown, ReturnType<F>>(), getCacheKey } = options
81
+
82
+ const memoizedFn = function (this: unknown, arg: Parameters<F>[0]): ReturnType<F> {
83
+ const key = getCacheKey ? getCacheKey(arg) : arg
84
+
85
+ if (cache.has(key)) {
86
+ return cache.get(key)!
87
+ }
88
+
89
+ const result = fn.call(this, arg) as ReturnType<F>
90
+
91
+ cache.set(key, result)
92
+
93
+ return result
94
+ }
95
+
96
+ memoizedFn.cache = cache
97
+
98
+ return memoizedFn as F & { cache: MemoizeCache<unknown, ReturnType<F>> }
99
+ }
100
+
101
+ /**
102
+ * Represents a cache for memoization, allowing storage and retrieval of computed values.
103
+ *
104
+ * @template K - The type of keys used to store values in the cache.
105
+ * @template V - The type of values stored in the cache.
106
+ */
107
+ export interface MemoizeCache<K, V> {
108
+ /**
109
+ * Stores a value in the cache with the specified key.
110
+ *
111
+ * @param key - The key to associate with the value.
112
+ * @param value - The value to store in the cache.
113
+ */
114
+ set(key: K, value: V): void
115
+
116
+ /**
117
+ * Retrieves a value from the cache by its key.
118
+ *
119
+ * @param key - The key of the value to retrieve.
120
+ * @returns The value associated with the key, or undefined if the key does not exist.
121
+ */
122
+ get(key: K): V | undefined
123
+
124
+ /**
125
+ * Checks if a value exists in the cache for the specified key.
126
+ *
127
+ * @param key - The key to check for existence in the cache.
128
+ * @returns True if the cache contains the key, false otherwise.
129
+ */
130
+ has(key: K): boolean
131
+
132
+ /**
133
+ * Deletes a value from the cache by its key.
134
+ *
135
+ * @param key - The key of the value to delete.
136
+ * @returns True if the value was successfully deleted, false otherwise.
137
+ */
138
+ delete(key: K): boolean
139
+
140
+ /**
141
+ * Clears all values from the cache.
142
+ */
143
+ clear(): void
144
+
145
+ /**
146
+ * The number of entries in the cache.
147
+ */
148
+ size: number
149
+ }