vite-plugin-taro 0.5.16 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.en.md +1 -1
  2. package/README.md +1 -1
  3. package/dist/node/plugins/client/client-taro.d.ts +2 -2
  4. package/dist/node/plugins/conditional/conditional-directives.d.ts +2 -2
  5. package/dist/node/plugins/h5/plugins.d.ts +2 -2
  6. package/dist/node/plugins/h5/resolver/module-resolver.d.ts +2 -2
  7. package/dist/node/plugins/h5/transform-app.d.ts +2 -2
  8. package/dist/node/plugins/h5/transform-app.js +2 -2
  9. package/dist/node/plugins/wx/chunk-path.d.ts +8 -0
  10. package/dist/node/plugins/wx/chunk-path.js +18 -0
  11. package/dist/node/plugins/wx/dev/dev-host.d.ts +2 -2
  12. package/dist/node/plugins/wx/dev/plugins.d.ts +2 -2
  13. package/dist/node/plugins/wx/dev/wx-dev-options.d.ts +2 -2
  14. package/dist/node/plugins/wx/dev/wx-dev-options.js +21 -0
  15. package/dist/node/plugins/wx/native/create-native-component-output.d.ts +3 -1
  16. package/dist/node/plugins/wx/native/create-native-component-output.js +3 -5
  17. package/dist/node/plugins/wx/output/files.d.ts +5 -4
  18. package/dist/node/plugins/wx/output/files.js +2 -2
  19. package/dist/node/plugins/wx/output/json.d.ts +4 -4
  20. package/dist/node/plugins/wx/output/json.js +2 -2
  21. package/dist/node/plugins/wx/output/templates.d.ts +2 -2
  22. package/dist/node/plugins/wx/placer/placement.d.ts +50 -0
  23. package/dist/node/plugins/wx/placer/placement.js +245 -0
  24. package/dist/node/plugins/wx/placer/placer.d.ts +60 -0
  25. package/dist/node/plugins/wx/placer/placer.js +123 -0
  26. package/dist/node/plugins/wx/plugins.d.ts +2 -2
  27. package/dist/node/plugins/wx/plugins.js +16 -16
  28. package/dist/node/plugins/wx/render/capsule-wrapper.js +3 -3
  29. package/dist/node/plugins/wx/render/native.js +5 -5
  30. package/dist/node/plugins/wx/render/transport.d.ts +7 -3
  31. package/dist/node/plugins/wx/render/transport.js +18 -9
  32. package/dist/node/plugins/wx/resolve/resolver.d.ts +2 -2
  33. package/dist/node/plugins/wx/resolve/specialize-bootstrap.d.ts +2 -2
  34. package/dist/node/plugins/wx/resolve/specialize-bootstrap.js +1 -1
  35. package/dist/node/plugins/wx/resolve/specialize-page-capsule.d.ts +2 -2
  36. package/dist/node/plugins/wx/resolve/specialize-page-capsule.js +2 -2
  37. package/dist/node/utils/modules.d.ts +0 -2
  38. package/dist/node/utils/modules.js +0 -7
  39. package/dist/node/utils/project-config.d.ts +2 -2
  40. package/dist/node/vpt.d.ts +4 -0
  41. package/dist/node/{vite-plugin.js → vpt.js} +1 -1
  42. package/dist/options.d.ts +65 -13
  43. package/dist/runtime/h5/app.js +2 -2
  44. package/dist/runtime/wx/amphibious/bootstrap.js +1 -1
  45. package/dist/runtime/wx/amphibious/transport.js +1 -1
  46. package/dist/runtime/wx/capsule/page.js +1 -1
  47. package/dist/vite.d.ts +2 -2
  48. package/dist/vite.js +1 -1
  49. package/package.json +3 -3
  50. package/src/node/plugins/client/client-taro.ts +3 -3
  51. package/src/node/plugins/conditional/conditional-directives.ts +3 -3
  52. package/src/node/plugins/h5/plugins.ts +3 -3
  53. package/src/node/plugins/h5/resolver/module-resolver.ts +2 -2
  54. package/src/node/plugins/h5/transform-app.ts +5 -5
  55. package/src/node/plugins/wx/chunk-path.ts +22 -0
  56. package/src/node/plugins/wx/dev/dev-host.ts +2 -2
  57. package/src/node/plugins/wx/dev/plugins.ts +2 -5
  58. package/src/node/plugins/wx/dev/wx-dev-options.ts +23 -2
  59. package/src/node/plugins/wx/native/create-native-component-output.ts +6 -5
  60. package/src/node/plugins/wx/output/files.ts +7 -5
  61. package/src/node/plugins/wx/output/json.ts +9 -10
  62. package/src/node/plugins/wx/output/templates.ts +3 -3
  63. package/src/node/plugins/wx/placer/placement.ts +364 -0
  64. package/src/node/plugins/wx/placer/placer.ts +154 -0
  65. package/src/node/plugins/wx/plugins.ts +20 -20
  66. package/src/node/plugins/wx/render/capsule-wrapper.ts +3 -3
  67. package/src/node/plugins/wx/render/native.ts +5 -5
  68. package/src/node/plugins/wx/render/transport.ts +24 -8
  69. package/src/node/plugins/wx/resolve/resolver.ts +5 -5
  70. package/src/node/plugins/wx/resolve/specialize-bootstrap.ts +3 -3
  71. package/src/node/plugins/wx/resolve/specialize-page-capsule.ts +4 -4
  72. package/src/node/utils/modules.ts +0 -8
  73. package/src/node/utils/project-config.ts +2 -2
  74. package/src/node/{vite-plugin.ts → vpt.ts} +2 -2
  75. package/src/options.ts +71 -13
  76. package/src/runtime/h5/app.ts +4 -4
  77. package/src/runtime/wx/amphibious/bootstrap.ts +2 -2
  78. package/src/runtime/wx/amphibious/transport.ts +2 -4
  79. package/src/runtime/wx/capsule/page.ts +3 -8
  80. package/src/vite.ts +2 -2
  81. package/dist/node/plugins/wx/placement/placer.d.ts +0 -78
  82. package/dist/node/plugins/wx/placement/placer.js +0 -158
  83. package/dist/node/plugins/wx/placement/plan.d.ts +0 -46
  84. package/dist/node/plugins/wx/placement/plan.js +0 -210
  85. package/dist/node/vite-plugin.d.ts +0 -4
  86. package/src/node/plugins/wx/placement/placer.ts +0 -187
  87. package/src/node/plugins/wx/placement/plan.ts +0 -306
@@ -1,46 +0,0 @@
1
- import type { Rolldown } from 'vite';
2
- /** Identifies one generated code-only subpackage by its physical output root. */
3
- export type SubpackageLocation = {
4
- /** Discriminates generated subpackages from main. */
5
- kind: 'subpackage';
6
- /** Native subpackage root relative to the Mini Program output directory. */
7
- root: string;
8
- };
9
- /** Physical package ownership for one transformed module. */
10
- export type PackageLocation = {
11
- kind: 'main';
12
- } | SubpackageLocation;
13
- /** Immutable module-to-package ownership produced before Rolldown creates chunks. */
14
- export type PlacementPlan = ReadonlyMap<string, PackageLocation>;
15
- /** Minimal Rolldown graph interface consumed by the subpackage planner. */
16
- export type ModuleGraph = {
17
- /** Every transformed module known after graph construction. */
18
- moduleIds: Iterable<string>;
19
- /** Reads static edges, dynamic edges, transformed code, and entry ownership. */
20
- getModuleInfo(moduleId: string): Rolldown.ModuleInfo | null;
21
- /** Adds non-JavaScript output owned by a transformed module to its package weight. */
22
- getAdditionalModuleBytes?: (info: Rolldown.ModuleInfo) => number;
23
- };
24
- /** Shared main-package value used for every eager or output-generated module. */
25
- export declare const mainPackage: {
26
- readonly kind: 'main';
27
- };
28
- /**
29
- * Creates one deterministic subpackage placement plan:
30
- *
31
- * 1. Snapshot Rolldown's transformed module graph.
32
- * 2. Reserve every explicit shell and capsule entry together with its static closure in main.
33
- * 3. Treat dynamic imports as asynchronous roots, then annotate their modules with affinity.
34
- * 4. Pack those lazy modules independently under the planning budget.
35
- * 5. Return only module ownership; chunks and native manifests are reconciled later.
36
- *
37
- * Static cycles are deliberately not atomic only after a genuine nested dynamic boundary. System.import() may obtain their
38
- * registrations from several packages and await top-level execution while preserving the original static ESM graph.
39
- */
40
- export declare function createPlacementPlan({ moduleIds, getModuleInfo, getAdditionalModuleBytes, planningBudgetBytes }: ModuleGraph & {
41
- planningBudgetBytes?: number;
42
- }): PlacementPlan;
43
- /** Uses the generated root directory itself as the native subpackage alias. */
44
- export declare function getSubpackageName(root: string): string;
45
- /** Tests the plugin-owned output prefix that physically identifies every generated subpackage. */
46
- export declare function isGeneratedSubpackageFile(fileName: string): boolean;
@@ -1,210 +0,0 @@
1
- import { createHash } from 'node:crypto';
2
- // Leave headroom below WeChat's 2M subpackage limit for capsule wrappers and bundler-generated code.
3
- const subpackagePlanningBudget = 1_900_000;
4
- const generatedSubpackageRootPrefix = 'sub/p_';
5
- /** Shared main-package value used for every eager or output-generated module. */
6
- export const mainPackage = { kind: 'main' };
7
- /**
8
- * Creates one deterministic subpackage placement plan:
9
- *
10
- * 1. Snapshot Rolldown's transformed module graph.
11
- * 2. Reserve every explicit shell and capsule entry together with its static closure in main.
12
- * 3. Treat dynamic imports as asynchronous roots, then annotate their modules with affinity.
13
- * 4. Pack those lazy modules independently under the planning budget.
14
- * 5. Return only module ownership; chunks and native manifests are reconciled later.
15
- *
16
- * Static cycles are deliberately not atomic only after a genuine nested dynamic boundary. System.import() may obtain their
17
- * registrations from several packages and await top-level execution while preserving the original static ESM graph.
18
- */
19
- export function createPlacementPlan({ moduleIds, getModuleInfo, getAdditionalModuleBytes, planningBudgetBytes = subpackagePlanningBudget }) {
20
- // Materialize the iterable once because every later phase needs stable random access by module ID.
21
- const infos = new Map();
22
- for (const moduleId of moduleIds) {
23
- const info = getModuleInfo(moduleId);
24
- if (info) {
25
- infos.set(moduleId, info);
26
- }
27
- }
28
- // Eager ownership is a hard constraint; consumer and neighbor sets below are soft packing preferences only.
29
- const eagerModules = findEagerModules(infos);
30
- const consumersByModule = findLazyConsumers({ infos, eagerModules });
31
- const neighborsByModule = findLazyNeighbors({ infos, eagerModules });
32
- const placeableModules = [...infos.entries()]
33
- .filter(([moduleId]) => !eagerModules.has(moduleId))
34
- .map(([moduleId, info]) => ({
35
- moduleId,
36
- estimatedBytes: Buffer.byteLength(info.code ?? '', 'utf8') + (getAdditionalModuleBytes?.(info) ?? 0),
37
- consumers: consumersByModule.get(moduleId) ?? new Set([moduleId]),
38
- neighbors: neighborsByModule.get(moduleId) ?? new Set()
39
- }));
40
- // Packing operates at module granularity, so a large lazy closure or cycle may span several subpackages.
41
- const subpackages = packSubpackages({ modules: placeableModules, planningBudgetBytes }).map(createPackedSubpackage);
42
- const locationByModule = new Map();
43
- for (const moduleId of eagerModules) {
44
- locationByModule.set(moduleId, mainPackage);
45
- }
46
- for (const subpackage of subpackages) {
47
- for (const moduleId of subpackage.moduleIds) {
48
- locationByModule.set(moduleId, subpackage);
49
- }
50
- }
51
- return locationByModule;
52
- }
53
- /**
54
- * Finds modules that must remain in main. Native shells and capsules are explicit entries, and static traversal keeps their
55
- * complete eager closures synchronous. Every dynamic import is therefore a genuine lazy boundary whose graph may use
56
- * subpackages and top-level await.
57
- */
58
- function findEagerModules(infos) {
59
- const eagerModules = new Set();
60
- const pending = [...infos.values()].filter((info) => info.isEntry).map((info) => info.id);
61
- while (pending.length > 0) {
62
- const moduleId = pending.pop();
63
- if (!moduleId || eagerModules.has(moduleId)) {
64
- continue;
65
- }
66
- const info = infos.get(moduleId);
67
- if (!info) {
68
- continue;
69
- }
70
- eagerModules.add(moduleId);
71
- pending.push(...info.importedIds);
72
- }
73
- return eagerModules;
74
- }
75
- /**
76
- * Records demand after the eager importSync closure has been removed. Every remaining dynamic target starts one lazy root
77
- * traversal; that traversal follows static edges only and stops before another dynamic boundary. A shared module records
78
- * every root that can request it. These consumer sets improve co-location but never prevent subpackage splitting.
79
- */
80
- function findLazyConsumers({ infos, eagerModules }) {
81
- const dynamicRoots = new Set();
82
- for (const info of infos.values()) {
83
- for (const importedId of info.dynamicallyImportedIds) {
84
- if (infos.has(importedId) && !eagerModules.has(importedId)) {
85
- dynamicRoots.add(importedId);
86
- }
87
- }
88
- }
89
- const consumersByModule = new Map();
90
- for (const dynamicRoot of [...dynamicRoots].sort()) {
91
- const visited = new Set();
92
- const pending = [dynamicRoot];
93
- while (pending.length > 0) {
94
- const moduleId = pending.pop();
95
- if (!moduleId || visited.has(moduleId) || eagerModules.has(moduleId)) {
96
- continue;
97
- }
98
- const info = infos.get(moduleId);
99
- if (!info) {
100
- continue;
101
- }
102
- visited.add(moduleId);
103
- const consumers = consumersByModule.get(moduleId) ?? new Set();
104
- consumers.add(dynamicRoot);
105
- consumersByModule.set(moduleId, consumers);
106
- pending.push(...info.importedIds);
107
- }
108
- }
109
- return consumersByModule;
110
- }
111
- /**
112
- * Converts each lazy static edge into an undirected affinity. Direction is irrelevant for co-location scoring, while the
113
- * original directed dependency remains in Rolldown and later in SystemJS. Cycles are therefore preferences, not atoms.
114
- */
115
- function findLazyNeighbors({ infos, eagerModules }) {
116
- const neighborsByModule = new Map();
117
- for (const [moduleId, info] of infos) {
118
- if (eagerModules.has(moduleId)) {
119
- continue;
120
- }
121
- for (const importedId of info.importedIds) {
122
- if (!infos.has(importedId) || eagerModules.has(importedId)) {
123
- continue;
124
- }
125
- addNeighbor(neighborsByModule, moduleId, importedId);
126
- addNeighbor(neighborsByModule, importedId, moduleId);
127
- }
128
- }
129
- return neighborsByModule;
130
- }
131
- /** Adds one side of an undirected lazy-module affinity edge. */
132
- function addNeighbor(neighborsByModule, moduleId, neighborId) {
133
- const neighbors = neighborsByModule.get(moduleId) ?? new Set();
134
- neighbors.add(neighborId);
135
- neighborsByModule.set(moduleId, neighbors);
136
- }
137
- /**
138
- * Packs lazy modules with deterministic best-fit decreasing:
139
- *
140
- * 1. Visit larger transformed modules first, with module ID as the stable tie-breaker.
141
- * 2. Consider only existing bins that stay within the planning budget.
142
- * 3. Prefer the bin with the least remaining space, minimizing subpackage count in the usual best-fit heuristic.
143
- * 4. When remaining space ties, prefer shared dynamic consumers and then static neighbors.
144
- * 5. Create a new bin when no existing bin fits; an individually oversized module receives its own bin.
145
- */
146
- function packSubpackages({ modules, planningBudgetBytes }) {
147
- const bins = [];
148
- const sortedModules = [...modules].sort((left, right) => {
149
- return right.estimatedBytes - left.estimatedBytes || left.moduleId.localeCompare(right.moduleId);
150
- });
151
- for (const module of sortedModules) {
152
- const candidate = bins
153
- .filter((bin) => bin.estimatedBytes + module.estimatedBytes <= planningBudgetBytes)
154
- .map((bin) => ({
155
- bin,
156
- remainingBytes: planningBudgetBytes - bin.estimatedBytes - module.estimatedBytes,
157
- affinity: getAffinity(bin, module)
158
- }))
159
- .sort((left, right) => {
160
- return left.remainingBytes - right.remainingBytes || right.affinity - left.affinity;
161
- })[0]?.bin;
162
- const bin = candidate ?? {
163
- moduleIds: [],
164
- estimatedBytes: 0,
165
- consumers: new Set()
166
- };
167
- if (!candidate) {
168
- bins.push(bin);
169
- }
170
- bin.moduleIds.push(module.moduleId);
171
- bin.estimatedBytes += module.estimatedBytes;
172
- for (const consumer of module.consumers) {
173
- bin.consumers.add(consumer);
174
- }
175
- }
176
- return bins;
177
- }
178
- /** Scores dynamic-root overlap above direct static adjacency when equally full bins compete. */
179
- function getAffinity(bin, module) {
180
- let affinity = 0;
181
- for (const consumer of module.consumers) {
182
- if (bin.consumers.has(consumer)) {
183
- affinity += 2;
184
- }
185
- }
186
- for (const neighbor of module.neighbors) {
187
- if (bin.moduleIds.includes(neighbor)) {
188
- affinity += 1;
189
- }
190
- }
191
- return affinity;
192
- }
193
- /** Freezes bin membership and derives a stable subpackage root from sorted module IDs. */
194
- function createPackedSubpackage(bin) {
195
- const moduleIds = [...bin.moduleIds].sort();
196
- const hash = createHash('sha256').update(moduleIds.join('\0')).digest('hex').slice(0, 8);
197
- return {
198
- kind: 'subpackage',
199
- root: `${generatedSubpackageRootPrefix}${hash}`,
200
- moduleIds
201
- };
202
- }
203
- /** Uses the generated root directory itself as the native subpackage alias. */
204
- export function getSubpackageName(root) {
205
- return root.slice(root.lastIndexOf('/') + 1);
206
- }
207
- /** Tests the plugin-owned output prefix that physically identifies every generated subpackage. */
208
- export function isGeneratedSubpackageFile(fileName) {
209
- return fileName.startsWith(generatedSubpackageRootPrefix);
210
- }
@@ -1,4 +0,0 @@
1
- import type { PluginOption } from 'vite';
2
- import type { VitePluginTaroOptions } from '../options.ts';
3
- /** Creates the Vite plugins for one Taro target. */
4
- export default function vitePluginTaro(options: VitePluginTaroOptions): PluginOption[];
@@ -1,187 +0,0 @@
1
- import path from 'node:path'
2
- import type { Rolldown } from 'vite'
3
- import { getWxExecutionKind, isTransportModule } from '../module.ts'
4
- import {
5
- createPlacementPlan,
6
- getSubpackageName,
7
- isGeneratedSubpackageFile,
8
- type ModuleGraph,
9
- mainPackage,
10
- type PackageLocation,
11
- type PlacementPlan
12
- } from './plan.ts'
13
-
14
- /** Native app.json declaration for one generated code-only subpackage. */
15
- export type GeneratedSubpackage = {
16
- /** Stable native alias derived from the generated root hash. */
17
- name: string
18
- /** Physical directory containing this subpackage's emitted capsules. */
19
- root: string
20
- /** Marks this as a code-only subpackage with no native Page routes. */
21
- pages: readonly []
22
- }
23
-
24
- /**
25
- * Creates the stateful adapter between graph planning and Rolldown's output lifecycle:
26
- *
27
- * - renderStart analyzes transformed modules before chunking.
28
- * - codeSplitting prevents modules assigned to different packages from being merged.
29
- * - filename callbacks materialize planned subpackage roots.
30
- * - renderChunk derives native loading mode from those physical paths.
31
- * - generateBundle reconciles the plan with chunks that survived tree shaking.
32
- */
33
- export function createPlacer() {
34
- // Filename and output callbacks run after analyze and read this immutable plan through their shared closure.
35
- let plan: PlacementPlan = new Map()
36
-
37
- /**
38
- * Reduces module ownership to one package for filename generation. Unknown Rolldown-generated modules default to
39
- * main, empty chunks default to main, and a chunk containing multiple known owners is rejected before paths diverge.
40
- */
41
- function getChunkLocation(chunk: Rolldown.PreRenderedChunk): PackageLocation {
42
- let location: PackageLocation | undefined
43
- for (const moduleId of chunk.moduleIds) {
44
- const moduleLocation = plan.get(moduleId) ?? mainPackage
45
- if (!location) {
46
- location = moduleLocation
47
- continue
48
- }
49
- if (!hasSameLocation(location, moduleLocation)) {
50
- throw new Error(`wx chunk mixes package owners: ${chunk.moduleIds.join(', ')}`)
51
- }
52
- }
53
- return location ?? mainPackage
54
- }
55
-
56
- return {
57
- /** Assigns every transformed module to main or one generated, size-bounded subpackage. */
58
- analyze(graph: ModuleGraph): void {
59
- plan = createPlacementPlan(graph)
60
- },
61
-
62
- /**
63
- * Complete Rolldown fragment required to preserve package placement and native entry semantics.
64
- *
65
- * ```text
66
- * native App/Page/Component shell entry
67
- * └─ static import / runtime importSync() ─▶ explicit capsule entry + static closure [main, no TLA]
68
- * └─ System.import() ─▶ lazy-a [package A, TLA allowed]
69
- * └─ static import ─▶ lazy-b [package B]
70
- *
71
- * name() assigns lazy-a and lazy-b to their planned package groups
72
- * includeDependenciesRecursively false: does not pull lazy-b back into package A
73
- * preserveEntrySignatures allows cross-chunk bindings without weakening native entry exports
74
- *
75
- * package A capsule
76
- * └─ SystemJS dependency ─▶ package B capsule
77
- * ▲
78
- * └─ main transport obtains registration with require.async()
79
- * ```
80
- *
81
- * Explicit entries preserve the shell/capsule rendering boundary while their static edge executes synchronously
82
- * from main. Once a dynamic boundary is crossed, physical fetches may be asynchronous and modules may use
83
- * top-level await. SystemJS still links that complete static lazy graph before execution, even across packages.
84
- */
85
- rolldownOptions: {
86
- output: {
87
- /**
88
- * Gives every generated subpackage a distinct Rolldown chunk group. Recursive dependency capture must
89
- * stay disabled: lazy static dependencies may belong to other subpackages and SystemJS links them
90
- * asynchronously.
91
- */
92
- codeSplitting: {
93
- groups: [
94
- {
95
- name(moduleId: string): string | null {
96
- const location = plan.get(moduleId)
97
- return location?.kind === 'subpackage' ? getSubpackageName(location.root) : null
98
- },
99
- // Do not let Rolldown pull a lazy group's static closure into one chunk. Past the nested dynamic
100
- // boundary, transport may obtain registrations from several packages asynchronously before
101
- // SystemJS links and executes the original graph, including cycles and top-level await.
102
- includeDependenciesRecursively: false
103
- }
104
- ]
105
- },
106
- // strictExecutionOrder deliberately has no plugin default. When an application enables it through normal
107
- // Rolldown output options, the generated helper runtime becomes amphibious: CommonJS evaluates it once and
108
- // transport publishes that cached namespace to SystemJS.
109
- /** Preserves exact native shell paths while hashing transport and explicit capsule entries. */
110
- entryFileNames(chunk: Rolldown.PreRenderedChunk): string {
111
- return getWxExecutionKind(chunk) === 'native' && !isTransportModule(chunk)
112
- ? '[name]'
113
- : 'assets/[name]-[hash].js'
114
- },
115
- /** Converts the planned owner into its physical main or generated subpackage filename template. */
116
- chunkFileNames(chunk: Rolldown.PreRenderedChunk): string {
117
- const location = getChunkLocation(chunk)
118
- if (location.kind === 'main') {
119
- return 'assets/[name]-[hash].js'
120
- }
121
- // The package group replaces Rolldown's [name], so recover the first bundled source file's name from
122
- // the final chunk module list instead of leaking the generated package hash into the filename.
123
- return `${location.root}/assets/${getFirstModuleName(chunk)}-[hash].js`
124
- },
125
- // Keep generic assets independent of native output identities assigned after bundling.
126
- assetFileNames: 'assets/[name]-[hash][extname]'
127
- },
128
- // Rolldown rejects strict entry signatures when code-splitting groups disable recursive dependency capture.
129
- // allow-extension retains required native-entry exports while permitting the extra cross-chunk bindings used
130
- // to split lazy static closures across physical packages.
131
- preserveEntrySignatures: 'allow-extension' as const
132
- },
133
-
134
- /**
135
- * Selects loading mode from physical output rather than graph intent. Transport executes in main, so main files
136
- * use require() and every generated subpackage file uses require.async().
137
- */
138
- getLoadMode(chunk: Rolldown.RenderedChunk): 'sync' | 'async' {
139
- return isGeneratedSubpackageFile(chunk.fileName) ? 'async' : 'sync'
140
- },
141
-
142
- /**
143
- * Reconciles planned ownership with final chunks through module IDs. Tree-shaken subpackages disappear naturally,
144
- * while roots are deduplicated and sorted before becoming deterministic app.json declarations.
145
- */
146
- getSubpackages(bundle: Rolldown.OutputBundle): GeneratedSubpackage[] {
147
- const emittedSubpackageRoots = new Set<string>()
148
- for (const output of Object.values(bundle)) {
149
- if (output.type !== 'chunk') {
150
- continue
151
- }
152
- for (const moduleId of output.moduleIds) {
153
- const location = plan.get(moduleId)
154
- if (location?.kind === 'subpackage') {
155
- emittedSubpackageRoots.add(location.root)
156
- }
157
- }
158
- }
159
-
160
- return [...emittedSubpackageRoots].sort().map((root) => ({
161
- name: getSubpackageName(root),
162
- root,
163
- pages: []
164
- }))
165
- }
166
- }
167
- }
168
-
169
- /** Uses the first bundled source filename as the readable identity of a generated subpackage chunk. */
170
- function getFirstModuleName(chunk: Rolldown.PreRenderedChunk): string {
171
- const firstModuleId = chunk.moduleIds[0]
172
- if (!firstModuleId) {
173
- throw new Error('wx subpackage chunk has no source modules')
174
- }
175
-
176
- const normalizedId = firstModuleId.replaceAll('\\', '/')
177
- const suffixIndex = normalizedId.search(/[?#]/)
178
- const cleanId = suffixIndex === -1 ? normalizedId : normalizedId.slice(0, suffixIndex)
179
- const fileName = path.posix.basename(cleanId)
180
- const extension = path.posix.extname(fileName)
181
- return extension ? fileName.slice(0, -extension.length) : fileName
182
- }
183
-
184
- /** Compares main by discriminant and generated subpackages by their unique physical root. */
185
- function hasSameLocation(left: PackageLocation, right: PackageLocation): boolean {
186
- return left.kind === 'main' ? right.kind === 'main' : right.kind === 'subpackage' && left.root === right.root
187
- }