@meethive/vite 0.0.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.
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2118 -0
- package/dist/index.mjs +2096 -0
- package/dist/src/federation/src/dev/expose-development.d.ts +5 -0
- package/dist/src/federation/src/dev/expose-development.d.ts.map +1 -0
- package/dist/src/federation/src/dev/remote-development.d.ts +5 -0
- package/dist/src/federation/src/dev/remote-development.d.ts.map +1 -0
- package/dist/src/federation/src/dev/shared-development.d.ts +5 -0
- package/dist/src/federation/src/dev/shared-development.d.ts.map +1 -0
- package/dist/src/federation/src/index.d.ts +7 -0
- package/dist/src/federation/src/index.d.ts.map +1 -0
- package/dist/src/federation/src/prod/expose-production.d.ts +5 -0
- package/dist/src/federation/src/prod/expose-production.d.ts.map +1 -0
- package/dist/src/federation/src/prod/remote-production.d.ts +7 -0
- package/dist/src/federation/src/prod/remote-production.d.ts.map +1 -0
- package/dist/src/federation/src/prod/shared-production.d.ts +5 -0
- package/dist/src/federation/src/prod/shared-production.d.ts.map +1 -0
- package/dist/src/federation/src/public.d.ts +40 -0
- package/dist/src/federation/src/public.d.ts.map +1 -0
- package/dist/src/federation/src/runtime/dynamic-remote.d.ts +79 -0
- package/dist/src/federation/src/runtime/dynamic-remote.d.ts.map +1 -0
- package/dist/src/federation/src/utils/html.d.ts +12 -0
- package/dist/src/federation/src/utils/html.d.ts.map +1 -0
- package/dist/src/federation/src/utils/index.d.ts +29 -0
- package/dist/src/federation/src/utils/index.d.ts.map +1 -0
- package/dist/src/federation/src/utils/semver/compare.d.ts +10 -0
- package/dist/src/federation/src/utils/semver/compare.d.ts.map +1 -0
- package/dist/src/federation/src/utils/semver/constants.d.ts +11 -0
- package/dist/src/federation/src/utils/semver/constants.d.ts.map +1 -0
- package/dist/src/federation/src/utils/semver/parser.d.ts +10 -0
- package/dist/src/federation/src/utils/semver/parser.d.ts.map +1 -0
- package/dist/src/federation/src/utils/semver/satisfy.d.ts +2 -0
- package/dist/src/federation/src/utils/semver/satisfy.d.ts.map +1 -0
- package/dist/src/federation/src/utils/semver/utils.d.ts +12 -0
- package/dist/src/federation/src/utils/semver/utils.d.ts.map +1 -0
- package/dist/src/monaco-editor/index.d.ts +35 -0
- package/dist/src/monaco-editor/index.d.ts.map +1 -0
- package/dist/src/monaco-editor/languageWork.d.ts +10 -0
- package/dist/src/monaco-editor/languageWork.d.ts.map +1 -0
- package/dist/src/monaco-editor/workerMiddleware.d.ts +9 -0
- package/dist/src/monaco-editor/workerMiddleware.d.ts.map +1 -0
- package/dist/src/sharp/index.d.ts +12 -0
- package/dist/src/sharp/index.d.ts.map +1 -0
- package/index.ts +3 -0
- package/package.json +48 -0
- package/src/federation/src/dev/expose-development.ts +29 -0
- package/src/federation/src/dev/remote-development.ts +435 -0
- package/src/federation/src/dev/shared-development.ts +29 -0
- package/src/federation/src/index.ts +242 -0
- package/src/federation/src/prod/expose-production.ts +333 -0
- package/src/federation/src/prod/federation_fn_import.js +75 -0
- package/src/federation/src/prod/remote-production.ts +658 -0
- package/src/federation/src/prod/shared-production.ts +268 -0
- package/src/federation/src/public.ts +54 -0
- package/src/federation/src/runtime/dynamic-remote.ts +247 -0
- package/src/federation/src/utils/html.ts +165 -0
- package/src/federation/src/utils/index.ts +255 -0
- package/src/federation/src/utils/semver/compare.ts +131 -0
- package/src/federation/src/utils/semver/constants.ts +46 -0
- package/src/federation/src/utils/semver/parser.ts +253 -0
- package/src/federation/src/utils/semver/satisfy.ts +151 -0
- package/src/federation/src/utils/semver/utils.ts +93 -0
- package/src/federation/types/dynamic-remote.d.ts +105 -0
- package/src/federation/types/index.d.ts +344 -0
- package/src/federation/types/pluginHooks.d.ts +4 -0
- package/src/federation/types/virtual-modules.d.ts +48 -0
- package/src/federation/types/viteDevServer.d.ts +22 -0
- package/src/monaco-editor/index.ts +205 -0
- package/src/monaco-editor/languageWork.ts +36 -0
- package/src/monaco-editor/workerMiddleware.ts +78 -0
- package/src/sharp/index.ts +93 -0
|
@@ -0,0 +1,658 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2022 Origin.js and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are licensed under Mulan PSL v2.
|
|
5
|
+
// You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
6
|
+
// You may obtain a copy of Mulan PSL v2 at:
|
|
7
|
+
// http://license.coscl.org.cn/MulanPSL2
|
|
8
|
+
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
9
|
+
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
10
|
+
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
11
|
+
// See the Mulan PSL v2 for more details.
|
|
12
|
+
//
|
|
13
|
+
// SPDX-License-Identifier: MulanPSL-2.0
|
|
14
|
+
// *****************************************************************************
|
|
15
|
+
|
|
16
|
+
import { walk } from 'estree-walker'
|
|
17
|
+
import MagicString from 'magic-string'
|
|
18
|
+
import path from 'node:path'
|
|
19
|
+
import type {
|
|
20
|
+
TransformPluginContext,
|
|
21
|
+
OutputAsset,
|
|
22
|
+
OutputChunk
|
|
23
|
+
} from 'rollup'
|
|
24
|
+
import type { ConfigTypeSet, VitePluginFederationOptions } from '../../types'
|
|
25
|
+
import type { PluginHooks } from '../../types/pluginHooks'
|
|
26
|
+
import {
|
|
27
|
+
builderInfo,
|
|
28
|
+
EXPOSES_KEY_MAP,
|
|
29
|
+
parsedOptions,
|
|
30
|
+
prodRemotes
|
|
31
|
+
} from '../public'
|
|
32
|
+
import {
|
|
33
|
+
createRemotesMap,
|
|
34
|
+
getModuleMarker,
|
|
35
|
+
parseRemoteOptions,
|
|
36
|
+
REMOTE_FROM_PARAMETER,
|
|
37
|
+
injectToHead,
|
|
38
|
+
toPreloadTag
|
|
39
|
+
} from '../utils'
|
|
40
|
+
import { ResolvedConfig } from 'vite'
|
|
41
|
+
|
|
42
|
+
const sharedFileName2Prop: Map<string, ConfigTypeSet> = new Map<
|
|
43
|
+
string,
|
|
44
|
+
ConfigTypeSet
|
|
45
|
+
>()
|
|
46
|
+
|
|
47
|
+
function joinUrlSegments(a: string, b: string): string {
|
|
48
|
+
if (!a || !b) {
|
|
49
|
+
return a || b || ''
|
|
50
|
+
}
|
|
51
|
+
if (a[a.length - 1] === '/') {
|
|
52
|
+
a = a.substring(0, a.length - 1)
|
|
53
|
+
}
|
|
54
|
+
if (b[0] !== '/') {
|
|
55
|
+
b = '/' + b
|
|
56
|
+
}
|
|
57
|
+
return a + b
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function toOutputFilePathWithoutRuntime(
|
|
61
|
+
filename: string,
|
|
62
|
+
type: 'asset' | 'public',
|
|
63
|
+
hostId: string,
|
|
64
|
+
hostType: 'js' | 'css' | 'html',
|
|
65
|
+
config: ResolvedConfig,
|
|
66
|
+
toRelative: (filename: string, hostId: string) => string
|
|
67
|
+
): string {
|
|
68
|
+
const { renderBuiltUrl } = config.experimental
|
|
69
|
+
let relative = config.base === '' || config.base === './'
|
|
70
|
+
if (renderBuiltUrl) {
|
|
71
|
+
const result = renderBuiltUrl(filename, {
|
|
72
|
+
hostId,
|
|
73
|
+
hostType,
|
|
74
|
+
type,
|
|
75
|
+
ssr: !!config.build.ssr
|
|
76
|
+
})
|
|
77
|
+
if (typeof result === 'object') {
|
|
78
|
+
if (result.runtime) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`{ runtime: "${result.runtime}" } is not supported for assets in ${hostType} files: ${filename}`
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
if (typeof result.relative === 'boolean') {
|
|
84
|
+
relative = result.relative
|
|
85
|
+
}
|
|
86
|
+
} else if (result) {
|
|
87
|
+
return result
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (relative && !config.build.ssr) {
|
|
91
|
+
return toRelative(filename, hostId)
|
|
92
|
+
} else {
|
|
93
|
+
return joinUrlSegments(config.base, filename)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function prodRemotePlugin(
|
|
98
|
+
options: VitePluginFederationOptions
|
|
99
|
+
): PluginHooks {
|
|
100
|
+
parsedOptions.prodRemote = parseRemoteOptions(options)
|
|
101
|
+
// const remotes: Remote[] = []
|
|
102
|
+
for (const item of parsedOptions.prodRemote) {
|
|
103
|
+
prodRemotes.push({
|
|
104
|
+
id: item[0],
|
|
105
|
+
regexp: new RegExp(`^${item[0]}/.+?`),
|
|
106
|
+
config: item[1]
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const shareScope = options.shareScope || 'default'
|
|
111
|
+
let resolvedConfig: ResolvedConfig
|
|
112
|
+
return {
|
|
113
|
+
name: 'originjs:remote-production',
|
|
114
|
+
virtualFile: options.remotes || options.enableDynamicRemotes
|
|
115
|
+
? {
|
|
116
|
+
// language=JS
|
|
117
|
+
__federation__: `
|
|
118
|
+
${createRemotesMap(prodRemotes)}
|
|
119
|
+
const currentImports = {}
|
|
120
|
+
const loadJS = async (url, fn) => {
|
|
121
|
+
const resolvedUrl = typeof url === 'function' ? await url() : url;
|
|
122
|
+
const script = document.createElement('script')
|
|
123
|
+
script.type = 'text/javascript';
|
|
124
|
+
script.onload = fn;
|
|
125
|
+
script.src = resolvedUrl;
|
|
126
|
+
document.getElementsByTagName('head')[0].appendChild(script);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function get(name, ${REMOTE_FROM_PARAMETER}) {
|
|
130
|
+
return __federation_import(name).then(module => () => {
|
|
131
|
+
if (${REMOTE_FROM_PARAMETER} === 'webpack') {
|
|
132
|
+
return Object.prototype.toString.call(module).indexOf('Module') > -1 && module.default ? module.default : module
|
|
133
|
+
}
|
|
134
|
+
return module
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function merge(obj1, obj2) {
|
|
139
|
+
const mergedObj = Object.assign(obj1, obj2);
|
|
140
|
+
for (const key of Object.keys(mergedObj)) {
|
|
141
|
+
if (typeof mergedObj[key] === 'object' && typeof obj2[key] === 'object') {
|
|
142
|
+
mergedObj[key] = merge(mergedObj[key], obj2[key]);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return mergedObj;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const wrapShareModule = ${REMOTE_FROM_PARAMETER} => {
|
|
149
|
+
return merge({
|
|
150
|
+
${getModuleMarker('shareScope')}
|
|
151
|
+
}, (globalThis.__federation_shared__ || {})['${shareScope}'] || {});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function __federation_import(name) {
|
|
155
|
+
currentImports[name] ??= import(name)
|
|
156
|
+
return currentImports[name]
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const initMap = Object.create(null);
|
|
160
|
+
|
|
161
|
+
async function __federation_method_ensure(remoteId) {
|
|
162
|
+
const remote = remotesMap[remoteId];
|
|
163
|
+
if (!remote.inited) {
|
|
164
|
+
if ('var' === remote.format) {
|
|
165
|
+
// loading js with script tag
|
|
166
|
+
return new Promise(resolve => {
|
|
167
|
+
const callback = () => {
|
|
168
|
+
if (!remote.inited) {
|
|
169
|
+
remote.lib = window[remoteId];
|
|
170
|
+
remote.lib.init(wrapShareModule(remote.from))
|
|
171
|
+
remote.inited = true;
|
|
172
|
+
}
|
|
173
|
+
resolve(remote.lib);
|
|
174
|
+
}
|
|
175
|
+
return loadJS(remote.url, callback);
|
|
176
|
+
});
|
|
177
|
+
} else if (['esm', 'systemjs'].includes(remote.format)) {
|
|
178
|
+
// loading js with import(...)
|
|
179
|
+
return new Promise((resolve, reject) => {
|
|
180
|
+
const getUrl = typeof remote.url === 'function' ? remote.url : () => Promise.resolve(remote.url);
|
|
181
|
+
getUrl().then(url => {
|
|
182
|
+
import(/* @vite-ignore */ url).then(lib => {
|
|
183
|
+
if (!remote.inited) {
|
|
184
|
+
const shareScope = wrapShareModule(remote.from);
|
|
185
|
+
lib.init(shareScope);
|
|
186
|
+
remote.lib = lib;
|
|
187
|
+
remote.lib.init(shareScope);
|
|
188
|
+
remote.inited = true;
|
|
189
|
+
}
|
|
190
|
+
resolve(remote.lib);
|
|
191
|
+
}).catch(reject)
|
|
192
|
+
})
|
|
193
|
+
})
|
|
194
|
+
}
|
|
195
|
+
} else {
|
|
196
|
+
return remote.lib;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function __federation_method_unwrapDefault(module) {
|
|
201
|
+
return (module?.__esModule || module?.[Symbol.toStringTag] === 'Module') ? module.default : module
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function __federation_method_wrapDefault(module, need) {
|
|
205
|
+
if (!module?.default && need) {
|
|
206
|
+
let obj = Object.create(null);
|
|
207
|
+
obj.default = module;
|
|
208
|
+
obj.__esModule = true;
|
|
209
|
+
return obj;
|
|
210
|
+
}
|
|
211
|
+
return module;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function __federation_method_getRemote(remoteName, componentName) {
|
|
215
|
+
return __federation_method_ensure(remoteName).then((remote) => remote.get(componentName).then(factory => factory()));
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function __federation_method_setRemote(remoteName, remoteConfig) {
|
|
219
|
+
remotesMap[remoteName] = remoteConfig;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async function __federation_method_add_origin_setRemote(remoteName, remoteUrl, options) {
|
|
223
|
+
const _options = options || {}
|
|
224
|
+
const _item = {
|
|
225
|
+
external: Array.isArray(_options.external) ? _options.external : [_options.external],
|
|
226
|
+
shareScope: _options.shareScope || 'default',
|
|
227
|
+
format: _options.format || 'esm',
|
|
228
|
+
from: _options.from ?? 'vite',
|
|
229
|
+
externalType: _options.externalType || 'url'
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
__federation_method_setRemote(remoteName, {
|
|
233
|
+
url: remoteUrl,
|
|
234
|
+
format: _item.format,
|
|
235
|
+
from: _item.from
|
|
236
|
+
})
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export {
|
|
240
|
+
__federation_method_ensure,
|
|
241
|
+
__federation_method_getRemote,
|
|
242
|
+
__federation_method_setRemote,
|
|
243
|
+
__federation_method_add_origin_setRemote,
|
|
244
|
+
__federation_method_unwrapDefault,
|
|
245
|
+
__federation_method_wrapDefault
|
|
246
|
+
}
|
|
247
|
+
`
|
|
248
|
+
}
|
|
249
|
+
: { __federation__: '' },
|
|
250
|
+
configResolved(config) {
|
|
251
|
+
resolvedConfig = config
|
|
252
|
+
},
|
|
253
|
+
|
|
254
|
+
async transform(this: TransformPluginContext, code: string, id: string) {
|
|
255
|
+
if (builderInfo.isShared) {
|
|
256
|
+
for (const sharedInfo of parsedOptions.prodShared) {
|
|
257
|
+
if (!sharedInfo[1].emitFile) {
|
|
258
|
+
sharedInfo[1].emitFile = this.emitFile({
|
|
259
|
+
type: 'chunk',
|
|
260
|
+
id: sharedInfo[1].id ?? sharedInfo[1].packagePath,
|
|
261
|
+
preserveSignature: 'strict',
|
|
262
|
+
name: `__federation_shared_${sharedInfo[0]}`
|
|
263
|
+
})
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (id === '\0virtual:__federation_fn_import') {
|
|
268
|
+
const moduleMapCode = parsedOptions.prodShared
|
|
269
|
+
.filter((shareInfo) => shareInfo[1].generate)
|
|
270
|
+
.map(
|
|
271
|
+
(sharedInfo) =>
|
|
272
|
+
`'${
|
|
273
|
+
sharedInfo[0]
|
|
274
|
+
}':{get:()=>()=>__federation_import(import.meta.ROLLUP_FILE_URL_${
|
|
275
|
+
sharedInfo[1].emitFile
|
|
276
|
+
}),import:${sharedInfo[1].import}${
|
|
277
|
+
sharedInfo[1].requiredVersion
|
|
278
|
+
? `,requiredVersion:'${sharedInfo[1].requiredVersion}'`
|
|
279
|
+
: ''
|
|
280
|
+
}}`
|
|
281
|
+
)
|
|
282
|
+
.join(',')
|
|
283
|
+
return code.replace(
|
|
284
|
+
getModuleMarker('moduleMap', 'var'),
|
|
285
|
+
`{${moduleMapCode}}`
|
|
286
|
+
)
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (builderInfo.isRemote) { // 远程组件
|
|
291
|
+
for (const expose of parsedOptions.prodExpose) {
|
|
292
|
+
if (!expose[1].emitFile) {
|
|
293
|
+
expose[1].emitFile = this.emitFile({
|
|
294
|
+
type: 'chunk',
|
|
295
|
+
id: expose[1].id ?? expose[1].import,
|
|
296
|
+
name: EXPOSES_KEY_MAP.get(expose[0]),
|
|
297
|
+
preserveSignature: 'allow-extension'
|
|
298
|
+
})
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (builderInfo.isHost) { // 主机
|
|
304
|
+
if (id === '\0virtual:__federation__') {
|
|
305
|
+
const res: string[] = []
|
|
306
|
+
parsedOptions.prodShared.forEach((arr) => {
|
|
307
|
+
const obj = arr[1]
|
|
308
|
+
let str = ''
|
|
309
|
+
if (typeof obj === 'object') {
|
|
310
|
+
const fileUrl = `import.meta.ROLLUP_FILE_URL_${obj.emitFile}`
|
|
311
|
+
str += `get:()=>get(${fileUrl}, ${REMOTE_FROM_PARAMETER}), loaded:1`
|
|
312
|
+
res.push(`'${arr[0]}':{'${obj.version}':{${str}}}`)
|
|
313
|
+
}
|
|
314
|
+
})
|
|
315
|
+
return code.replace(getModuleMarker('shareScope'), res.join(','))
|
|
316
|
+
}
|
|
317
|
+
} else { // 远程
|
|
318
|
+
if (id === '\0virtual:__federation__') {
|
|
319
|
+
return code.replace(getModuleMarker('shareScope'), '')
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (builderInfo.isHost || builderInfo.isShared) {
|
|
324
|
+
let ast: any | null = null
|
|
325
|
+
try {
|
|
326
|
+
ast = this.parse(code)
|
|
327
|
+
} catch (err) {
|
|
328
|
+
console.error(err)
|
|
329
|
+
}
|
|
330
|
+
if (!ast) {
|
|
331
|
+
return null
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const magicString = new MagicString(code)
|
|
335
|
+
const hasStaticImported = new Map<string, string>()
|
|
336
|
+
let requiresRuntime = false
|
|
337
|
+
let hasImportShared = false
|
|
338
|
+
let modify = false
|
|
339
|
+
let manualRequired: any = null // set static import if exists
|
|
340
|
+
|
|
341
|
+
walk(ast, {
|
|
342
|
+
enter(node: any) {
|
|
343
|
+
// handle share, eg. replace import {a} from b -> const a = importShared('b')
|
|
344
|
+
if (node.type === 'ImportDeclaration') {
|
|
345
|
+
const moduleName = node.source.value
|
|
346
|
+
if (
|
|
347
|
+
parsedOptions.prodShared.some(
|
|
348
|
+
(sharedInfo) => sharedInfo[0] === moduleName
|
|
349
|
+
)
|
|
350
|
+
) {
|
|
351
|
+
const namedImportDeclaration: (string | never)[] = []
|
|
352
|
+
let defaultImportDeclaration: string | null = null
|
|
353
|
+
if (!node.specifiers?.length) {
|
|
354
|
+
// invalid import , like import './__federation_shared_lib.js' , and remove it
|
|
355
|
+
magicString.remove(node.start, node.end)
|
|
356
|
+
modify = true
|
|
357
|
+
} else {
|
|
358
|
+
node.specifiers.forEach((specify) => {
|
|
359
|
+
if (specify.imported?.name) {
|
|
360
|
+
namedImportDeclaration.push(
|
|
361
|
+
`${
|
|
362
|
+
specify.imported.name === specify.local.name
|
|
363
|
+
? specify.imported.name
|
|
364
|
+
: `${specify.imported.name}:${specify.local.name}`
|
|
365
|
+
}`
|
|
366
|
+
)
|
|
367
|
+
} else {
|
|
368
|
+
defaultImportDeclaration = specify.local.name
|
|
369
|
+
}
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
hasImportShared = true
|
|
373
|
+
|
|
374
|
+
if (
|
|
375
|
+
defaultImportDeclaration &&
|
|
376
|
+
namedImportDeclaration.length
|
|
377
|
+
) {
|
|
378
|
+
// import a, {b} from 'c' -> const a = await importShared('c'); const {b} = a;
|
|
379
|
+
const imports = namedImportDeclaration.join(',')
|
|
380
|
+
const line = `const ${defaultImportDeclaration} = await importShared('${moduleName}');\nconst {${imports}} = ${defaultImportDeclaration};\n`
|
|
381
|
+
magicString.overwrite(node.start, node.end, line)
|
|
382
|
+
} else if (defaultImportDeclaration) {
|
|
383
|
+
magicString.overwrite(
|
|
384
|
+
node.start,
|
|
385
|
+
node.end,
|
|
386
|
+
`const ${defaultImportDeclaration} = await importShared('${moduleName}');\n`
|
|
387
|
+
)
|
|
388
|
+
} else if (namedImportDeclaration.length) {
|
|
389
|
+
magicString.overwrite(
|
|
390
|
+
node.start,
|
|
391
|
+
node.end,
|
|
392
|
+
`const {${namedImportDeclaration.join(
|
|
393
|
+
','
|
|
394
|
+
)}} = await importShared('${moduleName}');\n`
|
|
395
|
+
)
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
if (
|
|
402
|
+
node.type === 'ImportDeclaration' &&
|
|
403
|
+
node.source?.value === 'virtual:__federation__'
|
|
404
|
+
) {
|
|
405
|
+
manualRequired = node
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// handle remote import , eg replace import {a} from 'remote/b' to dynamic import
|
|
409
|
+
if (
|
|
410
|
+
(node.type === 'ImportExpression' ||
|
|
411
|
+
node.type === 'ImportDeclaration' ||
|
|
412
|
+
node.type === 'ExportNamedDeclaration') &&
|
|
413
|
+
node.source?.value?.indexOf('/') > -1
|
|
414
|
+
) {
|
|
415
|
+
const moduleId = node.source.value
|
|
416
|
+
const remote = prodRemotes.find((r) => r.regexp.test(moduleId))
|
|
417
|
+
const needWrap = remote?.config.from === 'vite'
|
|
418
|
+
if (remote) {
|
|
419
|
+
requiresRuntime = true
|
|
420
|
+
const modName = `.${moduleId.slice(remote.id.length)}`
|
|
421
|
+
switch (node.type) {
|
|
422
|
+
case 'ImportExpression': {
|
|
423
|
+
magicString.overwrite(
|
|
424
|
+
node.start,
|
|
425
|
+
node.end,
|
|
426
|
+
`__federation_method_getRemote(${JSON.stringify(
|
|
427
|
+
remote.id
|
|
428
|
+
)} , ${JSON.stringify(
|
|
429
|
+
modName
|
|
430
|
+
)}).then(module=>__federation_method_wrapDefault(module, ${needWrap}))`
|
|
431
|
+
)
|
|
432
|
+
break
|
|
433
|
+
}
|
|
434
|
+
case 'ImportDeclaration': {
|
|
435
|
+
if (node.specifiers?.length) {
|
|
436
|
+
const afterImportName = `__federation_var_${moduleId.replace(
|
|
437
|
+
/[@/\\.-]/g,
|
|
438
|
+
''
|
|
439
|
+
)}`
|
|
440
|
+
if (!hasStaticImported.has(moduleId)) {
|
|
441
|
+
hasStaticImported.set(moduleId, afterImportName)
|
|
442
|
+
magicString.overwrite(
|
|
443
|
+
node.start,
|
|
444
|
+
node.end,
|
|
445
|
+
`const ${afterImportName} = await __federation_method_getRemote(${JSON.stringify(
|
|
446
|
+
remote.id
|
|
447
|
+
)} , ${JSON.stringify(modName)});`
|
|
448
|
+
)
|
|
449
|
+
}
|
|
450
|
+
let deconstructStr = ''
|
|
451
|
+
node.specifiers.forEach((spec) => {
|
|
452
|
+
// default import , like import a from 'lib'
|
|
453
|
+
if (spec.type === 'ImportDefaultSpecifier') {
|
|
454
|
+
magicString.appendRight(
|
|
455
|
+
node.end,
|
|
456
|
+
`\n let ${spec.local.name} = __federation_method_unwrapDefault(${afterImportName}) `
|
|
457
|
+
)
|
|
458
|
+
} else if (spec.type === 'ImportSpecifier') {
|
|
459
|
+
// like import {a as b} from 'lib'
|
|
460
|
+
const importedName = spec.imported.name
|
|
461
|
+
const localName = spec.local.name
|
|
462
|
+
deconstructStr += `${
|
|
463
|
+
importedName === localName
|
|
464
|
+
? localName
|
|
465
|
+
: `${importedName} : ${localName}`
|
|
466
|
+
},`
|
|
467
|
+
} else if (spec.type === 'ImportNamespaceSpecifier') {
|
|
468
|
+
// like import * as a from 'lib'
|
|
469
|
+
magicString.appendRight(
|
|
470
|
+
node.end,
|
|
471
|
+
`let {${spec.local.name}} = ${afterImportName}`
|
|
472
|
+
)
|
|
473
|
+
}
|
|
474
|
+
})
|
|
475
|
+
if (deconstructStr.length > 0) {
|
|
476
|
+
magicString.appendRight(
|
|
477
|
+
node.end,
|
|
478
|
+
`\n let {${deconstructStr.slice(
|
|
479
|
+
0,
|
|
480
|
+
-1
|
|
481
|
+
)}} = ${afterImportName}`
|
|
482
|
+
)
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
break
|
|
486
|
+
}
|
|
487
|
+
case 'ExportNamedDeclaration': {
|
|
488
|
+
// handle export like export {a} from 'remotes/lib'
|
|
489
|
+
const afterImportName = `__federation_var_${moduleId.replace(
|
|
490
|
+
/[@/\\.-]/g,
|
|
491
|
+
''
|
|
492
|
+
)}`
|
|
493
|
+
if (!hasStaticImported.has(moduleId)) {
|
|
494
|
+
hasStaticImported.set(moduleId, afterImportName)
|
|
495
|
+
magicString.overwrite(
|
|
496
|
+
node.start,
|
|
497
|
+
node.end,
|
|
498
|
+
`const ${afterImportName} = await __federation_method_getRemote(${JSON.stringify(
|
|
499
|
+
remote.id
|
|
500
|
+
)} , ${JSON.stringify(modName)});`
|
|
501
|
+
)
|
|
502
|
+
}
|
|
503
|
+
if (node.specifiers.length > 0) {
|
|
504
|
+
const specifiers = node.specifiers
|
|
505
|
+
let exportContent = ''
|
|
506
|
+
let deconstructContent = ''
|
|
507
|
+
specifiers.forEach((spec) => {
|
|
508
|
+
const localName = spec.local.name
|
|
509
|
+
const exportName = spec.exported.name
|
|
510
|
+
const variableName = `${afterImportName}_${localName}`
|
|
511
|
+
deconstructContent = deconstructContent.concat(
|
|
512
|
+
`${localName}:${variableName},`
|
|
513
|
+
)
|
|
514
|
+
exportContent = exportContent.concat(
|
|
515
|
+
`${variableName} as ${exportName},`
|
|
516
|
+
)
|
|
517
|
+
})
|
|
518
|
+
magicString.append(
|
|
519
|
+
`\n const {${deconstructContent.slice(
|
|
520
|
+
0,
|
|
521
|
+
deconstructContent.length - 1
|
|
522
|
+
)}} = ${afterImportName}; \n`
|
|
523
|
+
)
|
|
524
|
+
magicString.append(
|
|
525
|
+
`\n export {${exportContent.slice(
|
|
526
|
+
0,
|
|
527
|
+
exportContent.length - 1
|
|
528
|
+
)}}; `
|
|
529
|
+
)
|
|
530
|
+
}
|
|
531
|
+
break
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
})
|
|
538
|
+
|
|
539
|
+
if (requiresRuntime) {
|
|
540
|
+
let requiresCode = `import {__federation_method_ensure, __federation_method_getRemote , __federation_method_wrapDefault , __federation_method_unwrapDefault, __federation_method_add_origin_setRemote} from '__federation__';\n\n`
|
|
541
|
+
// clear static required
|
|
542
|
+
if (manualRequired) {
|
|
543
|
+
requiresCode = `import {__federation_method_setRemote, __federation_method_ensure, __federation_method_getRemote , __federation_method_wrapDefault , __federation_method_unwrapDefault, __federation_method_add_origin_setRemote} from '__federation__';\n\n`
|
|
544
|
+
magicString.overwrite(manualRequired.start, manualRequired.end, ``)
|
|
545
|
+
}
|
|
546
|
+
magicString.prepend(requiresCode)
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
if (hasImportShared) {
|
|
550
|
+
magicString.prepend(
|
|
551
|
+
`import {importShared} from '\0virtual:__federation_fn_import';\n`
|
|
552
|
+
)
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
if (requiresRuntime || hasImportShared || modify) {
|
|
556
|
+
return {
|
|
557
|
+
code: magicString.toString(),
|
|
558
|
+
map: magicString.generateMap({ hires: true })
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
},
|
|
563
|
+
|
|
564
|
+
generateBundle(options, bundle) {
|
|
565
|
+
const preloadSharedReg = parsedOptions.prodShared
|
|
566
|
+
.filter((shareInfo) => shareInfo[1].modulePreload)
|
|
567
|
+
.map(
|
|
568
|
+
(item) => new RegExp(`__federation_shared_${item[0]}-.{8}.js`, 'g')
|
|
569
|
+
)
|
|
570
|
+
const getImportedChunks = (
|
|
571
|
+
chunk: OutputChunk,
|
|
572
|
+
satisfy: (chunk: OutputChunk) => boolean,
|
|
573
|
+
seen: Set<string> = new Set()
|
|
574
|
+
): OutputChunk[] => {
|
|
575
|
+
const chunks: OutputChunk[] = []
|
|
576
|
+
chunk.imports.forEach((file) => {
|
|
577
|
+
const importee = bundle[file]
|
|
578
|
+
if (importee) {
|
|
579
|
+
if (importee.type === 'chunk' && !seen.has(file)) {
|
|
580
|
+
if (satisfy(importee)) {
|
|
581
|
+
seen.add(file)
|
|
582
|
+
chunks.push(...getImportedChunks(importee, satisfy, seen))
|
|
583
|
+
chunks.push(importee)
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
})
|
|
588
|
+
return chunks
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
const sharedFiles: string[] = []
|
|
592
|
+
const entryChunk: Record<string, OutputAsset> = {}
|
|
593
|
+
for (const fileName in bundle) {
|
|
594
|
+
const file = bundle[fileName]
|
|
595
|
+
if (file.type === 'asset') {
|
|
596
|
+
if (fileName.endsWith('.html')) {
|
|
597
|
+
entryChunk[fileName] = file
|
|
598
|
+
}
|
|
599
|
+
} else {
|
|
600
|
+
if (preloadSharedReg.some((item) => item.test(fileName))) {
|
|
601
|
+
sharedFiles.push(fileName)
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
if (!sharedFiles.length) return
|
|
607
|
+
|
|
608
|
+
Object.keys(entryChunk).forEach((fileName) => {
|
|
609
|
+
let html = entryChunk[fileName].source as string
|
|
610
|
+
const htmlPath = entryChunk[fileName].fileName
|
|
611
|
+
const basePath =
|
|
612
|
+
resolvedConfig.base === './' || resolvedConfig.base === ''
|
|
613
|
+
? path.posix.join(
|
|
614
|
+
path.posix
|
|
615
|
+
.relative(entryChunk[fileName].fileName, '')
|
|
616
|
+
.slice(0, -2),
|
|
617
|
+
'./'
|
|
618
|
+
)
|
|
619
|
+
: resolvedConfig.base
|
|
620
|
+
|
|
621
|
+
const toOutputFilePath = (filename: string) =>
|
|
622
|
+
toOutputFilePathWithoutRuntime(
|
|
623
|
+
filename,
|
|
624
|
+
'asset',
|
|
625
|
+
htmlPath,
|
|
626
|
+
'html',
|
|
627
|
+
resolvedConfig,
|
|
628
|
+
(filename) => basePath + filename
|
|
629
|
+
)
|
|
630
|
+
|
|
631
|
+
const importFiles = sharedFiles
|
|
632
|
+
.filter((item) => {
|
|
633
|
+
return !html.includes(toOutputFilePath(item))
|
|
634
|
+
})
|
|
635
|
+
.flatMap((item) => {
|
|
636
|
+
const filepath = item
|
|
637
|
+
const importFiles = getImportedChunks(
|
|
638
|
+
bundle[item] as OutputChunk,
|
|
639
|
+
(chunk) => !html.includes(toOutputFilePath(chunk.fileName))
|
|
640
|
+
).map((item) => item.fileName)
|
|
641
|
+
|
|
642
|
+
return [filepath, ...importFiles].map((item) =>
|
|
643
|
+
toOutputFilePath(item)
|
|
644
|
+
)
|
|
645
|
+
})
|
|
646
|
+
|
|
647
|
+
html = injectToHead(
|
|
648
|
+
html,
|
|
649
|
+
[...new Set(importFiles)].map((item) => toPreloadTag(item))
|
|
650
|
+
)
|
|
651
|
+
|
|
652
|
+
entryChunk[fileName].source = html
|
|
653
|
+
})
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
export { sharedFileName2Prop }
|