vite-plugin-taro 0.6.18 → 0.6.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client.d.ts +2 -3
- package/dist/index.js +213574 -0
- package/dist/node/plugins/wx/dev/react-refresh.d.ts +14 -13
- package/dist/node/utils/packages.d.ts +2 -0
- package/package.json +26 -26
- package/dist/node/plugins/client/client-taro.js +0 -59
- package/dist/node/plugins/client/constant.js +0 -4
- package/dist/node/plugins/client/inject-taro-framework-apis.js +0 -9
- package/dist/node/plugins/conditional/conditional-directives.js +0 -76
- package/dist/node/plugins/h5/constant.js +0 -3
- package/dist/node/plugins/h5/create-stencil-client-adapter.js +0 -94
- package/dist/node/plugins/h5/plugins.js +0 -179
- package/dist/node/plugins/h5/resolver/module-resolver.js +0 -20
- package/dist/node/plugins/h5/transform-app.js +0 -48
- package/dist/node/plugins/tailwind/tailwind-css.js +0 -3
- package/dist/node/plugins/wx/dev/create-hmr-results-stream.js +0 -57
- package/dist/node/plugins/wx/dev/dev-host.js +0 -361
- package/dist/node/plugins/wx/dev/hmr-files.js +0 -56
- package/dist/node/plugins/wx/dev/host-actions.js +0 -58
- package/dist/node/plugins/wx/dev/patch-publisher.js +0 -77
- package/dist/node/plugins/wx/dev/plugins.js +0 -164
- package/dist/node/plugins/wx/dev/react-refresh.js +0 -231
- package/dist/node/plugins/wx/dev/runtime-reports.js +0 -45
- package/dist/node/plugins/wx/dev/wx-dev-options.js +0 -178
- package/dist/node/plugins/wx/module/chunk-path.js +0 -18
- package/dist/node/plugins/wx/module/module.js +0 -79
- package/dist/node/plugins/wx/native/compile-native-component-interface.js +0 -30
- package/dist/node/plugins/wx/native/create-native-component-output.js +0 -39
- package/dist/node/plugins/wx/native/native-component-assets.js +0 -76
- package/dist/node/plugins/wx/native/native-component-interface.js +0 -203
- package/dist/node/plugins/wx/output/files.js +0 -21
- package/dist/node/plugins/wx/output/relative-root.js +0 -6
- package/dist/node/plugins/wx/output/templates.js +0 -358
- package/dist/node/plugins/wx/placer/placement.js +0 -245
- package/dist/node/plugins/wx/placer/placer.js +0 -147
- package/dist/node/plugins/wx/plugins.js +0 -152
- package/dist/node/plugins/wx/render/capsule.js +0 -54
- package/dist/node/plugins/wx/render/native.js +0 -543
- package/dist/node/plugins/wx/render/system-js/string-editor.js +0 -94
- package/dist/node/plugins/wx/render/system-js/system-js.js +0 -588
- package/dist/node/plugins/wx/render/transport.js +0 -103
- package/dist/node/plugins/wx/resolve/resolver.js +0 -102
- package/dist/node/plugins/wx/resolve/specialize-app-capsule.js +0 -9
- package/dist/node/plugins/wx/resolve/specialize-page-capsule.js +0 -11
- package/dist/node/plugins/wx/styles/plugins.js +0 -459
- package/dist/node/utils/constant.js +0 -1
- package/dist/node/utils/memoize.js +0 -86
- package/dist/node/utils/modules.js +0 -22
- package/dist/node/utils/once.js +0 -20
- package/dist/node/utils/oxc-transform.js +0 -57
- package/dist/node/utils/packages.js +0 -9
- package/dist/node/utils/project-config.js +0 -8
- package/dist/node/utils/transform.js +0 -32
- package/dist/node/utils/vite.js +0 -10
- package/dist/node/vpt.js +0 -15
- package/dist/options.js +0 -1
- package/dist/vite.js +0 -1
- package/src/node/plugins/client/client-taro.ts +0 -71
- package/src/node/plugins/client/constant.ts +0 -5
- package/src/node/plugins/client/inject-taro-framework-apis.ts +0 -11
- package/src/node/plugins/conditional/conditional-directives.ts +0 -94
- package/src/node/plugins/h5/constant.ts +0 -4
- package/src/node/plugins/h5/create-stencil-client-adapter.ts +0 -111
- package/src/node/plugins/h5/plugins.ts +0 -194
- package/src/node/plugins/h5/resolver/module-resolver.ts +0 -33
- package/src/node/plugins/h5/transform-app.ts +0 -90
- package/src/node/plugins/tailwind/tailwind-css.ts +0 -4
- package/src/node/plugins/wx/dev/create-hmr-results-stream.ts +0 -71
- package/src/node/plugins/wx/dev/dev-host.ts +0 -453
- package/src/node/plugins/wx/dev/hmr-files.ts +0 -80
- package/src/node/plugins/wx/dev/host-actions.ts +0 -88
- package/src/node/plugins/wx/dev/patch-publisher.ts +0 -92
- package/src/node/plugins/wx/dev/plugins.ts +0 -176
- package/src/node/plugins/wx/dev/react-refresh.ts +0 -253
- package/src/node/plugins/wx/dev/runtime-reports.ts +0 -70
- package/src/node/plugins/wx/dev/wx-dev-options.ts +0 -226
- package/src/node/plugins/wx/module/chunk-path.ts +0 -22
- package/src/node/plugins/wx/module/module.ts +0 -110
- package/src/node/plugins/wx/native/compile-native-component-interface.ts +0 -48
- package/src/node/plugins/wx/native/create-native-component-output.ts +0 -60
- package/src/node/plugins/wx/native/native-component-assets.ts +0 -113
- package/src/node/plugins/wx/native/native-component-interface.ts +0 -267
- package/src/node/plugins/wx/output/files.ts +0 -40
- package/src/node/plugins/wx/output/relative-root.ts +0 -7
- package/src/node/plugins/wx/output/templates.ts +0 -448
- package/src/node/plugins/wx/placer/placement.ts +0 -364
- package/src/node/plugins/wx/placer/placer.ts +0 -180
- package/src/node/plugins/wx/plugins.ts +0 -183
- package/src/node/plugins/wx/render/capsule.ts +0 -57
- package/src/node/plugins/wx/render/native.ts +0 -694
- package/src/node/plugins/wx/render/system-js/string-editor.ts +0 -116
- package/src/node/plugins/wx/render/system-js/system-js.ts +0 -821
- package/src/node/plugins/wx/render/transport.ts +0 -173
- package/src/node/plugins/wx/resolve/resolver.ts +0 -145
- package/src/node/plugins/wx/resolve/specialize-app-capsule.ts +0 -27
- package/src/node/plugins/wx/resolve/specialize-page-capsule.ts +0 -29
- package/src/node/plugins/wx/styles/plugins.ts +0 -595
- package/src/node/utils/constant.ts +0 -1
- package/src/node/utils/memoize.ts +0 -149
- package/src/node/utils/modules.ts +0 -37
- package/src/node/utils/once.ts +0 -21
- package/src/node/utils/oxc-transform.ts +0 -76
- package/src/node/utils/packages.ts +0 -11
- package/src/node/utils/project-config.ts +0 -10
- package/src/node/utils/transform.ts +0 -48
- package/src/node/utils/vite.ts +0 -22
- package/src/node/vpt.ts +0 -18
- package/src/options.ts +0 -82
- package/src/runtime/client/taro/api.ts +0 -11
- package/src/runtime/client/taro/component.ts +0 -1
- package/src/runtime/client/taro/define-native-component.ts +0 -15
- package/src/runtime/h5/app.ts +0 -25
- package/src/runtime/h5/taro-css.d.ts +0 -3
- package/src/runtime/h5/taro-runtime.ts +0 -7
- package/src/runtime/wx/amphibious/bootstrap.ts +0 -17
- package/src/runtime/wx/amphibious/transport.ts +0 -8
- package/src/runtime/wx/capsule/app.ts +0 -12
- package/src/runtime/wx/capsule/component.ts +0 -7
- package/src/runtime/wx/capsule/page.ts +0 -29
- package/src/runtime/wx/capsule/taro-runtime.ts +0 -8
- package/src/runtime/wx/dev/dev-runtime.ts +0 -464
- package/src/runtime/wx/native/app.ts +0 -4
- package/src/runtime/wx/native/component.ts +0 -4
- package/src/runtime/wx/native/custom-wrapper.ts +0 -4
- package/src/runtime/wx/native/page.ts +0 -6
- package/src/runtime/wx/systemjs/LICENSE +0 -10
- package/src/runtime/wx/systemjs/system-core.js +0 -370
- package/src/runtime/wx/systemjs/system.d.ts +0 -55
- package/src/runtime/wx/wechat.d.ts +0 -56
- package/src/vite.ts +0 -2
- /package/dist/{vite.d.ts → index.d.ts} +0 -0
- /package/dist/runtime/client/taro/{define-native-component.d.ts → native.d.ts} +0 -0
- /package/dist/runtime/client/taro/{define-native-component.js → native.js} +0 -0
|
@@ -1,358 +0,0 @@
|
|
|
1
|
-
import { recursiveMerge } from '@tarojs/helper';
|
|
2
|
-
import { Weapp as WxPlatform } from '@tarojs/plugin-platform-weapp';
|
|
3
|
-
import { normalizeModuleId } from '../../../utils/modules.js';
|
|
4
|
-
import { packageRequire } from '../../../utils/packages.js';
|
|
5
|
-
import { createAppConfig } from '../../../utils/project-config.js';
|
|
6
|
-
import { isGeneratedSubpackageFile } from '../placer/placement.js';
|
|
7
|
-
import { toRootRelativePath } from './relative-root.js';
|
|
8
|
-
const customWrapperName = 'custom-wrapper';
|
|
9
|
-
const taroComponentsModulePath = packageRequire.resolve('@tarojs/plugin-platform-weapp/dist/components-react');
|
|
10
|
-
/** Creates every JSON, WXML, WXS, and Page WXSS asset owned by Taro's native rendering boundary. */
|
|
11
|
-
export function createTemplateAssets({ bundle, options, subpackages, nativeComponents, isProduction }) {
|
|
12
|
-
const templateBuilder = createTemplateBuilder();
|
|
13
|
-
const componentConfig = collectTemplateComponentConfig(bundle, nativeComponents);
|
|
14
|
-
const nativeComponentConfig = createNativeComponentConfig(nativeComponents);
|
|
15
|
-
const recursiveComponentJson = createRecursiveComponentJson(nativeComponentConfig);
|
|
16
|
-
const jsonAsset = (fileName, value) => createJsonAsset(fileName, value, isProduction);
|
|
17
|
-
return [
|
|
18
|
-
jsonAsset('app.json', createAppJson({ options, subpackages })),
|
|
19
|
-
createAsset('base.wxml', templateBuilder.buildBaseTemplate(componentConfig)),
|
|
20
|
-
createAsset('utils.wxs', templateBuilder.buildXScript()),
|
|
21
|
-
createAsset('comp.wxml', templateBuilder.buildBaseComponentTemplate('.wxml')),
|
|
22
|
-
jsonAsset('comp.json', recursiveComponentJson),
|
|
23
|
-
createAsset('custom-wrapper.wxml', templateBuilder.buildCustomComponentTemplate('.wxml')),
|
|
24
|
-
jsonAsset('custom-wrapper.json', recursiveComponentJson),
|
|
25
|
-
...options.pages.flatMap((page) => [
|
|
26
|
-
jsonAsset(`${page.path}.json`, createPageJson(page, nativeComponentConfig)),
|
|
27
|
-
createAsset(`${page.path}.wxml`, templateBuilder.buildPageTemplate(toRootRelativePath(page.path, 'base.wxml'), {
|
|
28
|
-
content: page.config,
|
|
29
|
-
path: page.path
|
|
30
|
-
})),
|
|
31
|
-
createAsset(`${page.path}.wxss`, '')
|
|
32
|
-
]),
|
|
33
|
-
jsonAsset('project.config.json', options.projectConfigJson),
|
|
34
|
-
...(options.projectPrivateConfigJson
|
|
35
|
-
? [jsonAsset('project.private.config.json', options.projectPrivateConfigJson)]
|
|
36
|
-
: []),
|
|
37
|
-
...(options.sitemapJson ? [jsonAsset('sitemap.json', options.sitemapJson)] : [])
|
|
38
|
-
];
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Adapts Taro's stock template builder to the WXML half of WX App wrapping without changing its recursive renderer.
|
|
42
|
-
*
|
|
43
|
-
* End-to-end contract
|
|
44
|
-
* -------------------
|
|
45
|
-
* React and Taro retain one in-memory ownership tree:
|
|
46
|
-
*
|
|
47
|
-
* App React root
|
|
48
|
-
* -> App host records
|
|
49
|
-
* -> vpt_page_outlet host at App {children}
|
|
50
|
-
* -> independently scheduled Taro Page roots
|
|
51
|
-
*
|
|
52
|
-
* The patched WX document makes the singleton App host a TaroRootElement. App host mutations therefore batch under app.*
|
|
53
|
-
* and fan out to every mounted native Page. Each Page root remains its own TaroRootElement and emits only page.*. The React
|
|
54
|
-
* host renderer marks the outlet and its App ancestors with an ordinary compact `vo` prop after each commit, while patched
|
|
55
|
-
* hydrate() stops at vpt_page_outlet. Page roots remain attached for React Context, lifecycle, events, removal, refs, effects,
|
|
56
|
-
* and HMR without entering app data.
|
|
57
|
-
*
|
|
58
|
-
* Build-time output
|
|
59
|
-
* -----------------
|
|
60
|
-
* createTemplateAssets asks one builder for shared base.wxml, utils.wxs, comp.wxml, custom-wrapper.wxml, and each Page WXML.
|
|
61
|
-
* This adapter specializes the products that own the native join:
|
|
62
|
-
*
|
|
63
|
-
* - shared base.wxml receives branch-local slot forwarding at comp boundaries plus vpt_fragment and vpt_page_outlet
|
|
64
|
-
* template definitions;
|
|
65
|
-
* - each Page WXML replaces Taro's root:root entry with one generic comp bound to app and one caller-owned taro_tmpl bound
|
|
66
|
-
* to page as that component's default slot.
|
|
67
|
-
*
|
|
68
|
-
* utils.wxs remains Taro's normal compact-node dispatcher. comp.wxml and custom-wrapper.wxml retain Taro's generic compact
|
|
69
|
-
* rendering contracts; their JSON companions register recursive boundaries and native components, while runtime configs
|
|
70
|
-
* retain standard event dispatch. CustomWrapper keeps Taro's Page-local ownership model and is not made slot-transparent
|
|
71
|
-
* for App wrapping.
|
|
72
|
-
* There is one shared template namespace, no Page-specific base file, no App/Page mode property, and no Page object threaded
|
|
73
|
-
* through App template data.
|
|
74
|
-
*
|
|
75
|
-
* First native Page
|
|
76
|
-
* -----------------
|
|
77
|
-
* createPageConfig starts the native Page with:
|
|
78
|
-
*
|
|
79
|
-
* app = { nn: 'vpt_fragment', cn: [] }
|
|
80
|
-
* page = { cn: [] }
|
|
81
|
-
*
|
|
82
|
-
* nn lets unchanged comp dispatch one input object even though App JSX may produce one or many root hosts. The record
|
|
83
|
-
* is WXML-only rather than a Taro host, so it needs no sid. After React commits the Page root below the outlet, the framework
|
|
84
|
-
* queues a lazy hydrate(AppRoot).cn value beside the Page root's already-pending page.* payloads. Taro drains both through the
|
|
85
|
-
* native Page's existing first setData, making App wrapping and Page content appear atomically.
|
|
86
|
-
*
|
|
87
|
-
* Native WXML execution
|
|
88
|
-
* ---------------------
|
|
89
|
-
* Data/slot ownership and named-template ownership intentionally travel through different scopes:
|
|
90
|
-
*
|
|
91
|
-
* Page WXML (owns app, page, Page eh, and Page-content light DOM)
|
|
92
|
-
* -> <comp i="{{app}}"> (crosses into a virtual custom-component scope)
|
|
93
|
-
* -> comp.wxml (owns App eh, imports unchanged utils.wxs and shared base.wxml)
|
|
94
|
-
* -> tmpl_0_vpt_fragment (iterates the real App compact roots in app.cn)
|
|
95
|
-
* -> stock Taro templates (render App hosts and recurse through their cn arrays)
|
|
96
|
-
* -> native recursion boundary <comp ...>
|
|
97
|
-
* -> forwards <slot /> only when this compact subtree root has i.vo
|
|
98
|
-
* -> tmpl_0_vpt_page_outlet at React's exact {children} position
|
|
99
|
-
* -> <slot />
|
|
100
|
-
* -> caller-owned <template is="taro_tmpl" data="{{root:page}}" />
|
|
101
|
-
* -> stock Taro templates render this native Page's page.cn records
|
|
102
|
-
*
|
|
103
|
-
* The virtual comp and both private templates add no native layout node. `vo` is part of the existing compact node i, not a
|
|
104
|
-
* component property or template context. App events execute through comp.eh; slotted Page events retain the native Page's
|
|
105
|
-
* eh. Both resolve the original Taro sid through the same event source.
|
|
106
|
-
*
|
|
107
|
-
* Named-template scope
|
|
108
|
-
* --------------------
|
|
109
|
-
* Slots transfer caller-owned light DOM only. They do not transfer the caller's named-template table or WXS modules. App
|
|
110
|
-
* dispatch runs inside comp.wxml, so vpt_fragment and vpt_page_outlet must live in base.wxml imported by that component.
|
|
111
|
-
* Putting those definitions in buildPageTemplate produces Page WXML that compiles, but component runtime dispatch fails with
|
|
112
|
-
* `Template tmpl_0_vpt_fragment not found`. Shared base.wxml makes the names visible in the root and every recursive
|
|
113
|
-
* component scope and emits them once rather than once per Page.
|
|
114
|
-
*
|
|
115
|
-
* Projection-spine ownership
|
|
116
|
-
* --------------------------
|
|
117
|
-
* React's host renderer runs after the final commit tree exists and caches the outlet-to-root Taro host ancestor array. It
|
|
118
|
-
* skips the unchanged root-side suffix, gives old leaf-side nodes the ordinary host prop vo=false, and gives new ones vo=true.
|
|
119
|
-
* Taro's existing lazy structural hydration runs later and therefore serializes those props without projection-specific
|
|
120
|
-
* scheduler or hydrate behavior. If React replaces the outlet host while moving it, the renderer finds the unique new marker
|
|
121
|
-
* once and caches its new ancestor array. At each depth-reset comp boundary, i.vo makes forwarding an O(1) local decision;
|
|
122
|
-
* WXML never searches descendants, and Page trees instantiate no unnamed slot.
|
|
123
|
-
*
|
|
124
|
-
* Steady-state updates and navigation
|
|
125
|
-
* -----------------------------------
|
|
126
|
-
* A page.* setData updates only the caller-owned Page template inside the slot. app is not passed through that template and
|
|
127
|
-
* comp.i does not change, so Page updates cannot invalidate App recursion. Ordinary app.* payloads and outlet-spine marker
|
|
128
|
-
* changes remain in Taro's granular batch before it fans out to every retained native Page. Adding or removing a React Page
|
|
129
|
-
* root mutates the outlet only in memory, and the runtime suppresses that marker's native child update. A newly pushed Page
|
|
130
|
-
* receives the latest complete App snapshot in its initial batch, while existing and hidden Pages require no navigation
|
|
131
|
-
* synchronization.
|
|
132
|
-
*
|
|
133
|
-
* Method responsibilities
|
|
134
|
-
* -----------------------
|
|
135
|
-
* 1. buildBaseTemplate preserves stock host templates, makes each depth-reset comp boundary slot-transparent through i.vo,
|
|
136
|
-
* and adds the two private definitions to the shared namespace.
|
|
137
|
-
* 2. buildPageTemplate owns only the Page boundary: app binding, page binding, and the single Page-content slot.
|
|
138
|
-
* 3. buildXScript delegates unchanged because routing metadata already travels inside compact node i.
|
|
139
|
-
* 4. buildBaseComponentTemplate delegates unchanged so recursive comp remains generic and feature-independent.
|
|
140
|
-
* 5. buildCustomComponentTemplate delegates unchanged so CustomWrapper renders compact children in its own native scope.
|
|
141
|
-
*
|
|
142
|
-
* H5 never calls this WX output builder. Its App continues to receive ordinary Fragment children and none of these native
|
|
143
|
-
* data roots, templates, custom-component boundaries, or slot rules enter the browser build.
|
|
144
|
-
*/
|
|
145
|
-
/** Replaces one pinned Taro fragment and rejects absent or duplicated upstream contracts. */
|
|
146
|
-
export function replaceExactlyOnce(source, current, replacement, description) {
|
|
147
|
-
const firstIndex = source.indexOf(current);
|
|
148
|
-
const duplicateIndex = firstIndex === -1 ? -1 : source.indexOf(current, firstIndex + current.length);
|
|
149
|
-
if (firstIndex === -1 || duplicateIndex !== -1) {
|
|
150
|
-
throw new Error(`Expected one ${description}, found ${firstIndex === -1 ? 0 : 'multiple'}`);
|
|
151
|
-
}
|
|
152
|
-
return `${source.slice(0, firstIndex)}${replacement}${source.slice(firstIndex + current.length)}`;
|
|
153
|
-
}
|
|
154
|
-
function createTemplateBuilder() {
|
|
155
|
-
const platform = new WxPlatform({
|
|
156
|
-
helper: {
|
|
157
|
-
recursiveMerge
|
|
158
|
-
},
|
|
159
|
-
// c8 cannot observe callbacks Taro accepts but intentionally never invokes.
|
|
160
|
-
/* c8 ignore next */
|
|
161
|
-
modifyWebpackChain() { },
|
|
162
|
-
/* c8 ignore next */
|
|
163
|
-
registerPlatform() { }
|
|
164
|
-
}, {}, {});
|
|
165
|
-
platform.modifyTemplate({});
|
|
166
|
-
const taroTemplateBuilder = platform.template;
|
|
167
|
-
return {
|
|
168
|
-
buildBaseTemplate: (componentConfig) => {
|
|
169
|
-
const source = taroTemplateBuilder.buildTemplate(componentConfig);
|
|
170
|
-
/*
|
|
171
|
-
* Taro inserts recursive comp only when template depth resets. App {children} may be below any number of those
|
|
172
|
-
* boundaries, so each boundary reads the renderer-maintained vo marker on its compact subtree root before forwarding
|
|
173
|
-
* the caller's default slot. No App/Page mode or Page data is threaded through template scopes: Page recursion
|
|
174
|
-
* and unrelated App branches have no marker, while the outlet spine carries the one Page-owned slot.
|
|
175
|
-
*/
|
|
176
|
-
const slotTransparentRecursion = replaceExactlyOnce(source, '<comp i="{{i}}" l="{{l}}" />', `<comp i="{{i}}" l="{{l}}"><slot wx:if="{{i.vo}}" /></comp>`, 'recursive comp call');
|
|
177
|
-
/*
|
|
178
|
-
* These definitions belong in shared base.wxml rather than buildPageTemplate. Although native data is Page-owned,
|
|
179
|
-
* the dynamic calls that render App records execute after crossing into comp.wxml's component scope. WXML slots
|
|
180
|
-
* transfer caller-owned light DOM, not the caller's named-template table or WXS modules. comp.wxml can therefore
|
|
181
|
-
* resolve only its own definitions and those imported from base.wxml.
|
|
182
|
-
*
|
|
183
|
-
* Defining the two names in Page WXML is not merely redundant: WeChat accepts that Page file at compile time, then
|
|
184
|
-
* comp.wxml's runtime dispatch fails with `Template tmpl_0_vpt_fragment not found` because component template
|
|
185
|
-
* resolution never searches the caller Page. Shared base.wxml is already imported by comp.wxml, makes both names
|
|
186
|
-
* visible at every depth-reset component scope, and emits them once instead of once per generated Page.
|
|
187
|
-
*
|
|
188
|
-
* Page WXML can give generic comp one i object, whereas App output is a root collection. vpt_fragment bridges
|
|
189
|
-
* those contracts without becoming a native or Taro host: its nn is only a template discriminator and its
|
|
190
|
-
* template emits each real cn record directly. Keeping the collection behind one comp is important because that
|
|
191
|
-
* component owns exactly one Page slot regardless of whether App rendered zero, one, or many top-level hosts.
|
|
192
|
-
* The synthetic record itself is not keyed or event-addressable, so it deliberately has no sid. Its cn items are
|
|
193
|
-
* different: they are real hydrated Taro elements, text nodes, or the outlet, and every one has Taro's stable sid.
|
|
194
|
-
* wx:key="sid" matches Taro's stock root.cn loop so insertion/reordering preserves native-component instances,
|
|
195
|
-
* sibling identity, and event-source routing instead of reusing children only by array position.
|
|
196
|
-
*
|
|
197
|
-
* vpt_page_outlet is the matching terminal. The patched runtime retains Page roots below that marker in memory
|
|
198
|
-
* and serializes no children into app data, while React's host renderer marks its compact ancestor spine with vo.
|
|
199
|
-
* The slot inserts the parent Page's separate page data at the same visual position and adds no native layout
|
|
200
|
-
* wrapper.
|
|
201
|
-
*/
|
|
202
|
-
return `${slotTransparentRecursion}
|
|
203
|
-
<template name="tmpl_0_vpt_fragment">
|
|
204
|
-
<template
|
|
205
|
-
is="{{xs.a(0, item.nn, '')}}"
|
|
206
|
-
data="{{i:item,c:1,l:xs.f('',item.nn)}}"
|
|
207
|
-
wx:for="{{i.cn}}"
|
|
208
|
-
wx:key="sid"
|
|
209
|
-
/>
|
|
210
|
-
</template>
|
|
211
|
-
<template name="tmpl_0_vpt_page_outlet"><slot /></template>
|
|
212
|
-
`;
|
|
213
|
-
},
|
|
214
|
-
buildXScript: () => {
|
|
215
|
-
// Alias selection and compact paths are unchanged; both App and Page records use Taro's normal node vocabulary,
|
|
216
|
-
// and projection ownership already travels on the current i object as vo.
|
|
217
|
-
return taroTemplateBuilder.buildXScript();
|
|
218
|
-
},
|
|
219
|
-
buildBaseComponentTemplate: (ext) => {
|
|
220
|
-
/*
|
|
221
|
-
* Keep comp generic. i is the current compact node dispatched through i.nn. l is Taro's lineage of selected
|
|
222
|
-
* special/native aliases: xs.f records bounded/nestable ancestors and xs.a uses that history when choosing a
|
|
223
|
-
* generated template level on non-recursive WXML platforms. The current comp.wxml restarts its local lineage from
|
|
224
|
-
* i.nn, but l remains part of Taro's intentional depth-reset component contract and platform variants may consume
|
|
225
|
-
* it. Preserve that upstream binding; only the new Page-root comp starts with the property's empty default. Slot
|
|
226
|
-
* forwarding lives at this base.wxml call site, and vo already belongs to i, so comp still needs no App/Page mode,
|
|
227
|
-
* projection property, or Page data.
|
|
228
|
-
*/
|
|
229
|
-
return taroTemplateBuilder.buildBaseComponentTemplate(ext);
|
|
230
|
-
},
|
|
231
|
-
buildCustomComponentTemplate: (ext) => {
|
|
232
|
-
// CustomWrapper renders its compact children in its own native scope; imported base templates perform dispatch.
|
|
233
|
-
return taroTemplateBuilder.buildCustomComponentTemplate(ext);
|
|
234
|
-
},
|
|
235
|
-
buildPageTemplate: (baseTempPath, page) => {
|
|
236
|
-
const source = taroTemplateBuilder.buildPageTemplate(baseTempPath, page);
|
|
237
|
-
/*
|
|
238
|
-
* The native Page owns both data bindings. app is the transparent single-node adapter rendered by unchanged
|
|
239
|
-
* comp; the caller-owned taro_tmpl still reads only page and becomes comp's one default slot. A page.* update
|
|
240
|
-
* therefore cannot enter App template scopes or a component property, while App recursion can place the Page
|
|
241
|
-
* exactly at {children} by consuming the slot at vpt_page_outlet. The root call omits l because this native comp
|
|
242
|
-
* starts a fresh lineage scope and its generic property already defaults to the empty string. It also emits no id:
|
|
243
|
-
* no runtime lookup, event dispatch, ref, or selector addresses this virtual boundary.
|
|
244
|
-
*/
|
|
245
|
-
return replaceExactlyOnce(source, '<template is="taro_tmpl" data="{{root:root}}" />', `<comp i="{{app}}"><template is="taro_tmpl" data="{{root:page}}" /></comp>`, 'Page template entry');
|
|
246
|
-
}
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
/** Creates template metadata from reachable Taro hosts, the standard CustomWrapper boundary, and native JSX fields. */
|
|
250
|
-
function collectTemplateComponentConfig(bundle, nativeComponents) {
|
|
251
|
-
const components = findBundleModule(bundle, taroComponentsModulePath);
|
|
252
|
-
const renderedComponentNames = (components?.renderedExports ?? []).map(toDashed);
|
|
253
|
-
return {
|
|
254
|
-
includes: new Set([
|
|
255
|
-
'view',
|
|
256
|
-
'catch-view',
|
|
257
|
-
'static-view',
|
|
258
|
-
'pure-view',
|
|
259
|
-
'click-view',
|
|
260
|
-
'scroll-view',
|
|
261
|
-
'image',
|
|
262
|
-
'static-image',
|
|
263
|
-
'text',
|
|
264
|
-
'static-text',
|
|
265
|
-
...renderedComponentNames.filter((name) => name !== customWrapperName)
|
|
266
|
-
]),
|
|
267
|
-
exclude: new Set(),
|
|
268
|
-
thirdPartyComponents: new Map([
|
|
269
|
-
[customWrapperName, new Set()],
|
|
270
|
-
...nativeComponents.map((component) => [component.name, new Set(component.fields)])
|
|
271
|
-
]),
|
|
272
|
-
includeAll: false
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
/** Finds one module in the final chunk metadata. */
|
|
276
|
-
function findBundleModule(bundle, resolvedId) {
|
|
277
|
-
const normalizedResolvedId = normalizeModuleId(resolvedId);
|
|
278
|
-
for (const output of Object.values(bundle)) {
|
|
279
|
-
if (output.type !== 'chunk') {
|
|
280
|
-
continue;
|
|
281
|
-
}
|
|
282
|
-
const found = Object.entries(output.modules).find(([id]) => normalizeModuleId(id) === normalizedResolvedId);
|
|
283
|
-
if (found) {
|
|
284
|
-
return found[1];
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
/** Converts a React component export to Taro's dashed host-component name. */
|
|
289
|
-
function toDashed(value) {
|
|
290
|
-
return value.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
291
|
-
}
|
|
292
|
-
/** Creates App JSON with generated subpackages. */
|
|
293
|
-
function createAppJson({ options, subpackages }) {
|
|
294
|
-
return {
|
|
295
|
-
...createAppConfig(options),
|
|
296
|
-
...(subpackages.length > 0 ? { subPackages: subpackages } : {})
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
/** Creates native registrations for every WXML rendering scope that can instantiate their templates. */
|
|
300
|
-
function createNativeComponentConfig(nativeComponents) {
|
|
301
|
-
// Cross-package components require a placeholder while WeChat downloads their generated subpackage. Paths are
|
|
302
|
-
// root-absolute, so remove the leading slash before testing the output-relative subpackage prefix.
|
|
303
|
-
// https://developers.weixin.qq.com/miniprogram/dev/framework/subpackages/async.html
|
|
304
|
-
// https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/placeholder.html
|
|
305
|
-
return {
|
|
306
|
-
usingComponents: Object.fromEntries(nativeComponents.map(({ name, componentPath }) => [name, componentPath])),
|
|
307
|
-
componentPlaceholder: Object.fromEntries(nativeComponents.flatMap(({ name, componentPath }) => isGeneratedSubpackageFile(componentPath.slice(1)) ? [[name, 'view']] : []))
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
/** Preserves configured Page JSON and registers its recursive and native component entries. */
|
|
311
|
-
function createPageJson(page, nativeComponentConfig) {
|
|
312
|
-
const usingComponents = isJsonObject(page.config.usingComponents) ? page.config.usingComponents : {};
|
|
313
|
-
const componentPlaceholder = isJsonObject(page.config.componentPlaceholder) ? page.config.componentPlaceholder : {};
|
|
314
|
-
const hasNativeComponentPlaceholder = Object.keys(nativeComponentConfig.componentPlaceholder).length > 0;
|
|
315
|
-
return {
|
|
316
|
-
...page.config,
|
|
317
|
-
usingComponents: {
|
|
318
|
-
...usingComponents,
|
|
319
|
-
...nativeComponentConfig.usingComponents,
|
|
320
|
-
comp: toRootRelativePath(page.path, 'comp'),
|
|
321
|
-
[customWrapperName]: toRootRelativePath(page.path, customWrapperName)
|
|
322
|
-
},
|
|
323
|
-
...(hasNativeComponentPlaceholder
|
|
324
|
-
? {
|
|
325
|
-
componentPlaceholder: {
|
|
326
|
-
...componentPlaceholder,
|
|
327
|
-
...nativeComponentConfig.componentPlaceholder
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
: {})
|
|
331
|
-
};
|
|
332
|
-
}
|
|
333
|
-
/** Creates the shared recursive component configuration used by comp and CustomWrapper. */
|
|
334
|
-
function createRecursiveComponentJson(nativeComponentConfig) {
|
|
335
|
-
const hasNativeComponentPlaceholder = Object.keys(nativeComponentConfig.componentPlaceholder).length > 0;
|
|
336
|
-
return {
|
|
337
|
-
component: true,
|
|
338
|
-
styleIsolation: 'apply-shared',
|
|
339
|
-
usingComponents: {
|
|
340
|
-
...nativeComponentConfig.usingComponents,
|
|
341
|
-
comp: './comp',
|
|
342
|
-
[customWrapperName]: `./${customWrapperName}`
|
|
343
|
-
},
|
|
344
|
-
...(hasNativeComponentPlaceholder ? { componentPlaceholder: nativeComponentConfig.componentPlaceholder } : {})
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
/** Tests whether a configured JSON value can be merged as an object. */
|
|
348
|
-
function isJsonObject(value) {
|
|
349
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
350
|
-
}
|
|
351
|
-
/** Creates compact production JSON and readable development JSON. */
|
|
352
|
-
function createJsonAsset(fileName, value, isProduction) {
|
|
353
|
-
return createAsset(fileName, isProduction ? JSON.stringify(value) : `${JSON.stringify(value, null, 4)}\n`);
|
|
354
|
-
}
|
|
355
|
-
/** Creates one emitted text asset. */
|
|
356
|
-
function createAsset(fileName, source) {
|
|
357
|
-
return { type: 'asset', fileName: fileName, source: source };
|
|
358
|
-
}
|
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
2
|
-
// Leave headroom below WeChat's 2M subpackage limit for rendered wrappers and native assets.
|
|
3
|
-
export const subpackagePlanningBudget = 1_900_000;
|
|
4
|
-
const generatedSubpackageRootPrefix = 'sub/p_';
|
|
5
|
-
/** Shared main-package value used for every synchronously reachable chunk. */
|
|
6
|
-
const mainPackage = { kind: 'main' };
|
|
7
|
-
/**
|
|
8
|
-
* Applies Load-Transition Hypergraph Partitioning to Rolldown's final preliminary chunk graph:
|
|
9
|
-
*
|
|
10
|
-
* 1. Sort preliminary filenames to remove callback and object-enumeration order from every later decision.
|
|
11
|
-
* 2. Reserve every explicit entry and its complete static closure in main because native startup must load it synchronously.
|
|
12
|
-
* 3. Treat each dynamic-import edge as one load transition; the target's static closure is that transition's hyperedge.
|
|
13
|
-
* Nested dynamic edges remain separate transitions rather than being folded into the parent closure.
|
|
14
|
-
* 4. Index every lazy chunk by all transitions requiring it. Shared chunks therefore carry global demand rather than being
|
|
15
|
-
* assigned according to the first source module or dynamic root that happens to visit them.
|
|
16
|
-
* 5. Order chunks by transition demand, estimated emitted bytes, then preliminary filename. Place each chunk once into the
|
|
17
|
-
* fitting bin with maximum transition overlap, using best-fit remaining capacity only as a tie-breaker.
|
|
18
|
-
* 6. Hash each bin's sorted preliminary filenames into a deterministic physical package root and return unique ownership.
|
|
19
|
-
*
|
|
20
|
-
* Analysis costs the sum of transition static-closure traversals. Packing scans fitting bins and intersects sparse
|
|
21
|
-
* transition sets; its worst case is O(CBT), while practical graphs have few bins and sparse transition membership.
|
|
22
|
-
*/
|
|
23
|
-
export function createPlacement({ chunks, getAdditionalModuleBytes }) {
|
|
24
|
-
const chunkById = new Map(Object.entries(chunks).sort(([left], [right]) => left.localeCompare(right)));
|
|
25
|
-
const mainChunkIds = findMainChunkIds(chunkById);
|
|
26
|
-
const transitionsByChunk = collectTransitionsByChunk({ chunks: chunkById, mainChunkIds: mainChunkIds });
|
|
27
|
-
const placeableChunks = [...chunkById]
|
|
28
|
-
.filter(([chunkId]) => !mainChunkIds.has(chunkId))
|
|
29
|
-
.map(([chunkId, chunk]) => ({
|
|
30
|
-
chunkId: chunkId,
|
|
31
|
-
estimatedBytes: estimateChunkBytes(chunk) +
|
|
32
|
-
chunk.moduleIds.reduce((bytes, moduleId) => bytes + getAdditionalModuleBytes(moduleId), 0),
|
|
33
|
-
transitions: transitionsByChunk.get(chunkId) ?? new Set()
|
|
34
|
-
}));
|
|
35
|
-
const subpackages = packChunks({
|
|
36
|
-
chunks: placeableChunks,
|
|
37
|
-
planningBudgetBytes: subpackagePlanningBudget
|
|
38
|
-
}).map(createPackedSubpackage);
|
|
39
|
-
// This local map accumulates the immutable plan returned to output materialization.
|
|
40
|
-
const locationByChunk = new Map();
|
|
41
|
-
for (const chunkId of mainChunkIds) {
|
|
42
|
-
locationByChunk.set(chunkId, mainPackage);
|
|
43
|
-
}
|
|
44
|
-
for (const subpackage of subpackages) {
|
|
45
|
-
for (const chunkId of subpackage.chunkIds) {
|
|
46
|
-
locationByChunk.set(chunkId, subpackage);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
function getLocation(chunkId) {
|
|
50
|
-
const location = locationByChunk.get(chunkId);
|
|
51
|
-
if (!location) {
|
|
52
|
-
throw new Error(`wx placement is missing final chunk: ${chunkId}`);
|
|
53
|
-
}
|
|
54
|
-
return location;
|
|
55
|
-
}
|
|
56
|
-
/** Resolves typed ownership from Rolldown's preliminary physical filename before or after finalization. */
|
|
57
|
-
function getPackageLocation(chunk) {
|
|
58
|
-
return getLocation('preliminaryFileName' in chunk ? chunk.preliminaryFileName : chunk.fileName);
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
getPackageLocation: getPackageLocation,
|
|
62
|
-
/** Adds the planned package root to a physical preliminary path without changing the chunk's SystemJS identity. */
|
|
63
|
-
getPhysicalChunkId(chunk) {
|
|
64
|
-
const location = getPackageLocation(chunk);
|
|
65
|
-
return location.kind === 'main' ? chunk.fileName : `${location.root}/${chunk.fileName}`;
|
|
66
|
-
},
|
|
67
|
-
/** Selects the native loading API directly from typed package ownership. */
|
|
68
|
-
getLoadMode(chunk) {
|
|
69
|
-
return getPackageLocation(chunk).kind === 'subpackage' ? 'async' : 'sync';
|
|
70
|
-
},
|
|
71
|
-
/** Assigns each final chunk's Rolldown-owned physical filename and declares typed owners that survived output. */
|
|
72
|
-
finalize(bundle) {
|
|
73
|
-
const outputChunks = Object.values(bundle).filter((output) => output.type === 'chunk');
|
|
74
|
-
// This local mutable set deduplicates typed package owners that retain at least one final output chunk.
|
|
75
|
-
const roots = new Set();
|
|
76
|
-
for (const chunk of outputChunks) {
|
|
77
|
-
// OutputChunk.fileName contains the resolved content hash. preliminaryFileName preserves the exact physical
|
|
78
|
-
// candidate with placeholders that identified this chunk when placement was created during renderChunk.
|
|
79
|
-
const location = getLocation(chunk.preliminaryFileName);
|
|
80
|
-
if (location.kind !== 'subpackage') {
|
|
81
|
-
continue;
|
|
82
|
-
}
|
|
83
|
-
// OutputChunk is mutable in generateBundle. Assigning fileName makes Rolldown retain all chunk metadata and
|
|
84
|
-
// write that same chunk at its physical package path; deleting bundle keys or re-emitting would lose identity.
|
|
85
|
-
chunk.fileName = `${location.root}/${chunk.fileName}`;
|
|
86
|
-
roots.add(location.root);
|
|
87
|
-
}
|
|
88
|
-
return [...roots].sort().map((root) => ({
|
|
89
|
-
name: root.slice(root.lastIndexOf('/') + 1),
|
|
90
|
-
root: root,
|
|
91
|
-
pages: []
|
|
92
|
-
}));
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
/** Keeps every explicit output entry and its complete static chunk closure in main. */
|
|
97
|
-
function findMainChunkIds(chunks) {
|
|
98
|
-
const mainChunkIds = new Set();
|
|
99
|
-
// The worklist avoids recursion and visits every eager static edge once.
|
|
100
|
-
const pending = [...chunks].filter(([, chunk]) => chunk.isEntry).map(([chunkId]) => chunkId);
|
|
101
|
-
while (pending.length > 0) {
|
|
102
|
-
const chunkId = pending.pop();
|
|
103
|
-
if (!chunkId || mainChunkIds.has(chunkId)) {
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
const chunk = chunks.get(chunkId);
|
|
107
|
-
if (!chunk) {
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
mainChunkIds.add(chunkId);
|
|
111
|
-
pending.push(...chunk.imports);
|
|
112
|
-
}
|
|
113
|
-
return mainChunkIds;
|
|
114
|
-
}
|
|
115
|
-
/** Creates every load-transition hyperedge and indexes its static closure by chunk. */
|
|
116
|
-
function collectTransitionsByChunk({ chunks, mainChunkIds }) {
|
|
117
|
-
const transitionsByChunk = new Map();
|
|
118
|
-
let transitionId = 0;
|
|
119
|
-
for (const chunk of chunks.values()) {
|
|
120
|
-
for (const targetId of [...chunk.dynamicImports].sort()) {
|
|
121
|
-
if (!chunks.has(targetId) || mainChunkIds.has(targetId)) {
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
for (const chunkId of collectStaticClosure({
|
|
125
|
-
rootId: targetId,
|
|
126
|
-
chunks: chunks,
|
|
127
|
-
mainChunkIds: mainChunkIds
|
|
128
|
-
})) {
|
|
129
|
-
const transitions = transitionsByChunk.get(chunkId) ?? new Set();
|
|
130
|
-
transitions.add(transitionId);
|
|
131
|
-
transitionsByChunk.set(chunkId, transitions);
|
|
132
|
-
}
|
|
133
|
-
transitionId++;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return transitionsByChunk;
|
|
137
|
-
}
|
|
138
|
-
/** Collects one transition's static closure; nested dynamic imports remain independent transitions. */
|
|
139
|
-
function collectStaticClosure({ rootId, chunks, mainChunkIds }) {
|
|
140
|
-
const closure = new Set();
|
|
141
|
-
// The worklist follows static edges only; the visited set terminates cycles.
|
|
142
|
-
const pending = [rootId];
|
|
143
|
-
while (pending.length > 0) {
|
|
144
|
-
const chunkId = pending.pop();
|
|
145
|
-
if (!chunkId || closure.has(chunkId) || mainChunkIds.has(chunkId)) {
|
|
146
|
-
continue;
|
|
147
|
-
}
|
|
148
|
-
const chunk = chunks.get(chunkId);
|
|
149
|
-
if (!chunk) {
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
closure.add(chunkId);
|
|
153
|
-
pending.push(...chunk.imports);
|
|
154
|
-
}
|
|
155
|
-
return [...closure].sort();
|
|
156
|
-
}
|
|
157
|
-
/** Partitions final chunks by transition overlap before best-fit capacity. */
|
|
158
|
-
function packChunks({ chunks, planningBudgetBytes }) {
|
|
159
|
-
const bins = [];
|
|
160
|
-
const orderedChunks = [...chunks].sort(compareChunks);
|
|
161
|
-
for (const chunk of orderedChunks) {
|
|
162
|
-
const bin = chunk.estimatedBytes <= planningBudgetBytes
|
|
163
|
-
? (findBestBin({ bins: bins, chunk: chunk, planningBudgetBytes: planningBudgetBytes }) ??
|
|
164
|
-
createBin(bins))
|
|
165
|
-
: createBin(bins);
|
|
166
|
-
placeChunk(bin, chunk);
|
|
167
|
-
}
|
|
168
|
-
return bins;
|
|
169
|
-
}
|
|
170
|
-
/** Gives globally shared transition demand priority, then size and stable preliminary filename. */
|
|
171
|
-
function compareChunks(left, right) {
|
|
172
|
-
return (right.transitions.size - left.transitions.size ||
|
|
173
|
-
right.estimatedBytes - left.estimatedBytes ||
|
|
174
|
-
left.chunkId.localeCompare(right.chunkId));
|
|
175
|
-
}
|
|
176
|
-
/** Chooses maximum transition overlap, then the fullest fitting package and stable creation order. */
|
|
177
|
-
function findBestBin({ bins, chunk, planningBudgetBytes }) {
|
|
178
|
-
let best;
|
|
179
|
-
for (const bin of bins) {
|
|
180
|
-
if (bin.estimatedBytes + chunk.estimatedBytes > planningBudgetBytes) {
|
|
181
|
-
continue;
|
|
182
|
-
}
|
|
183
|
-
const candidate = {
|
|
184
|
-
bin: bin,
|
|
185
|
-
overlap: countOverlap(bin.transitions, chunk.transitions),
|
|
186
|
-
remainingBytes: planningBudgetBytes - bin.estimatedBytes - chunk.estimatedBytes
|
|
187
|
-
};
|
|
188
|
-
if (!best ||
|
|
189
|
-
candidate.overlap > best.overlap ||
|
|
190
|
-
(candidate.overlap === best.overlap && candidate.remainingBytes < best.remainingBytes)) {
|
|
191
|
-
best = candidate;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return best?.bin;
|
|
195
|
-
}
|
|
196
|
-
/** Counts transition-package incidences removed by one candidate placement. */
|
|
197
|
-
function countOverlap(left, right) {
|
|
198
|
-
const [smaller, larger] = left.size <= right.size ? [left, right] : [right, left];
|
|
199
|
-
let overlap = 0;
|
|
200
|
-
for (const transition of smaller) {
|
|
201
|
-
if (larger.has(transition)) {
|
|
202
|
-
overlap++;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return overlap;
|
|
206
|
-
}
|
|
207
|
-
/** Creates one planner-local mutable package. */
|
|
208
|
-
function createBin(bins) {
|
|
209
|
-
const bin = {
|
|
210
|
-
chunkIds: [],
|
|
211
|
-
estimatedBytes: 0,
|
|
212
|
-
transitions: new Set()
|
|
213
|
-
};
|
|
214
|
-
bins.push(bin);
|
|
215
|
-
return bin;
|
|
216
|
-
}
|
|
217
|
-
/** Applies one irreversible, non-duplicating final chunk assignment. */
|
|
218
|
-
function placeChunk(bin, chunk) {
|
|
219
|
-
bin.chunkIds.push(chunk.chunkId);
|
|
220
|
-
bin.estimatedBytes += chunk.estimatedBytes;
|
|
221
|
-
for (const transition of chunk.transitions) {
|
|
222
|
-
bin.transitions.add(transition);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
/** Estimates final output bytes from tree-shaken modules plus a bounded generated-chunk allowance. */
|
|
226
|
-
function estimateChunkBytes(chunk) {
|
|
227
|
-
const renderedModuleBytes = Object.values(chunk.modules).reduce((bytes, module) => bytes + (module.code ? Buffer.byteLength(module.code, 'utf8') : 0), 0);
|
|
228
|
-
const moduleWrapperBytes = chunk.moduleIds.length * 64;
|
|
229
|
-
const referenceBytes = (chunk.imports.length + chunk.dynamicImports.length) * 32;
|
|
230
|
-
return renderedModuleBytes + moduleWrapperBytes + referenceBytes + 64;
|
|
231
|
-
}
|
|
232
|
-
/** Freezes membership and derives a stable root from sorted preliminary filenames. */
|
|
233
|
-
function createPackedSubpackage(bin) {
|
|
234
|
-
const chunkIds = [...bin.chunkIds].sort();
|
|
235
|
-
const hash = createHash('sha256').update(chunkIds.join('\0')).digest('hex').slice(0, 8);
|
|
236
|
-
return {
|
|
237
|
-
kind: 'subpackage',
|
|
238
|
-
root: `${generatedSubpackageRootPrefix}${hash}`,
|
|
239
|
-
chunkIds: chunkIds
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
/** Tests the plugin-owned output prefix that physically identifies every generated subpackage. */
|
|
243
|
-
export function isGeneratedSubpackageFile(fileName) {
|
|
244
|
-
return fileName.startsWith(generatedSubpackageRootPrefix);
|
|
245
|
-
}
|