@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.
Files changed (72) hide show
  1. package/dist/index.d.ts +4 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +2118 -0
  4. package/dist/index.mjs +2096 -0
  5. package/dist/src/federation/src/dev/expose-development.d.ts +5 -0
  6. package/dist/src/federation/src/dev/expose-development.d.ts.map +1 -0
  7. package/dist/src/federation/src/dev/remote-development.d.ts +5 -0
  8. package/dist/src/federation/src/dev/remote-development.d.ts.map +1 -0
  9. package/dist/src/federation/src/dev/shared-development.d.ts +5 -0
  10. package/dist/src/federation/src/dev/shared-development.d.ts.map +1 -0
  11. package/dist/src/federation/src/index.d.ts +7 -0
  12. package/dist/src/federation/src/index.d.ts.map +1 -0
  13. package/dist/src/federation/src/prod/expose-production.d.ts +5 -0
  14. package/dist/src/federation/src/prod/expose-production.d.ts.map +1 -0
  15. package/dist/src/federation/src/prod/remote-production.d.ts +7 -0
  16. package/dist/src/federation/src/prod/remote-production.d.ts.map +1 -0
  17. package/dist/src/federation/src/prod/shared-production.d.ts +5 -0
  18. package/dist/src/federation/src/prod/shared-production.d.ts.map +1 -0
  19. package/dist/src/federation/src/public.d.ts +40 -0
  20. package/dist/src/federation/src/public.d.ts.map +1 -0
  21. package/dist/src/federation/src/runtime/dynamic-remote.d.ts +79 -0
  22. package/dist/src/federation/src/runtime/dynamic-remote.d.ts.map +1 -0
  23. package/dist/src/federation/src/utils/html.d.ts +12 -0
  24. package/dist/src/federation/src/utils/html.d.ts.map +1 -0
  25. package/dist/src/federation/src/utils/index.d.ts +29 -0
  26. package/dist/src/federation/src/utils/index.d.ts.map +1 -0
  27. package/dist/src/federation/src/utils/semver/compare.d.ts +10 -0
  28. package/dist/src/federation/src/utils/semver/compare.d.ts.map +1 -0
  29. package/dist/src/federation/src/utils/semver/constants.d.ts +11 -0
  30. package/dist/src/federation/src/utils/semver/constants.d.ts.map +1 -0
  31. package/dist/src/federation/src/utils/semver/parser.d.ts +10 -0
  32. package/dist/src/federation/src/utils/semver/parser.d.ts.map +1 -0
  33. package/dist/src/federation/src/utils/semver/satisfy.d.ts +2 -0
  34. package/dist/src/federation/src/utils/semver/satisfy.d.ts.map +1 -0
  35. package/dist/src/federation/src/utils/semver/utils.d.ts +12 -0
  36. package/dist/src/federation/src/utils/semver/utils.d.ts.map +1 -0
  37. package/dist/src/monaco-editor/index.d.ts +35 -0
  38. package/dist/src/monaco-editor/index.d.ts.map +1 -0
  39. package/dist/src/monaco-editor/languageWork.d.ts +10 -0
  40. package/dist/src/monaco-editor/languageWork.d.ts.map +1 -0
  41. package/dist/src/monaco-editor/workerMiddleware.d.ts +9 -0
  42. package/dist/src/monaco-editor/workerMiddleware.d.ts.map +1 -0
  43. package/dist/src/sharp/index.d.ts +12 -0
  44. package/dist/src/sharp/index.d.ts.map +1 -0
  45. package/index.ts +3 -0
  46. package/package.json +48 -0
  47. package/src/federation/src/dev/expose-development.ts +29 -0
  48. package/src/federation/src/dev/remote-development.ts +435 -0
  49. package/src/federation/src/dev/shared-development.ts +29 -0
  50. package/src/federation/src/index.ts +242 -0
  51. package/src/federation/src/prod/expose-production.ts +333 -0
  52. package/src/federation/src/prod/federation_fn_import.js +75 -0
  53. package/src/federation/src/prod/remote-production.ts +658 -0
  54. package/src/federation/src/prod/shared-production.ts +268 -0
  55. package/src/federation/src/public.ts +54 -0
  56. package/src/federation/src/runtime/dynamic-remote.ts +247 -0
  57. package/src/federation/src/utils/html.ts +165 -0
  58. package/src/federation/src/utils/index.ts +255 -0
  59. package/src/federation/src/utils/semver/compare.ts +131 -0
  60. package/src/federation/src/utils/semver/constants.ts +46 -0
  61. package/src/federation/src/utils/semver/parser.ts +253 -0
  62. package/src/federation/src/utils/semver/satisfy.ts +151 -0
  63. package/src/federation/src/utils/semver/utils.ts +93 -0
  64. package/src/federation/types/dynamic-remote.d.ts +105 -0
  65. package/src/federation/types/index.d.ts +344 -0
  66. package/src/federation/types/pluginHooks.d.ts +4 -0
  67. package/src/federation/types/virtual-modules.d.ts +48 -0
  68. package/src/federation/types/viteDevServer.d.ts +22 -0
  69. package/src/monaco-editor/index.ts +205 -0
  70. package/src/monaco-editor/languageWork.ts +36 -0
  71. package/src/monaco-editor/workerMiddleware.ts +78 -0
  72. package/src/sharp/index.ts +93 -0
@@ -0,0 +1,435 @@
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 type { UserConfig } from 'vite'
17
+ import type { ConfigTypeSet, VitePluginFederationOptions } from '../../types'
18
+ import { walk } from 'estree-walker'
19
+ import MagicString from 'magic-string'
20
+ import { readFileSync } from 'fs'
21
+ import { posix } from 'path'
22
+ import type { TransformPluginContext } from 'rollup'
23
+ import type { ViteDevServer } from '../../types/viteDevServer'
24
+ import {
25
+ createRemotesMap,
26
+ getFileExtname,
27
+ getModuleMarker,
28
+ normalizePath,
29
+ parseRemoteOptions,
30
+ REMOTE_FROM_PARAMETER
31
+ } from '../utils'
32
+ import { builderInfo, parsedOptions, devRemotes } from '../public'
33
+ import type { PluginHooks } from '../../types/pluginHooks'
34
+
35
+ export function devRemotePlugin(
36
+ options: VitePluginFederationOptions
37
+ ): PluginHooks {
38
+ parsedOptions.devRemote = parseRemoteOptions(options)
39
+ // const remotes: { id: string; regexp: RegExp; config: RemotesConfig }[] = []
40
+ for (const item of parsedOptions.devRemote) {
41
+ devRemotes.push({
42
+ id: item[0],
43
+ regexp: new RegExp(`^${item[0]}/.+?`),
44
+ config: item[1]
45
+ })
46
+ }
47
+
48
+ const needHandleFileType = [
49
+ '.js',
50
+ '.ts',
51
+ '.jsx',
52
+ '.tsx',
53
+ '.mjs',
54
+ '.cjs',
55
+ '.vue',
56
+ '.svelte'
57
+ ]
58
+ options.transformFileTypes = (options.transformFileTypes ?? [])
59
+ .concat(needHandleFileType)
60
+ .map((item) => item.toLowerCase())
61
+ const transformFileTypeSet = new Set(options.transformFileTypes)
62
+ let viteDevServer: ViteDevServer
63
+ return {
64
+ name: 'originjs:remote-development',
65
+ virtualFile: options.remotes || options.enableDynamicRemotes
66
+ ? {
67
+ __federation__: `
68
+ ${createRemotesMap(devRemotes)}
69
+ const loadJS = async (url, fn) => {
70
+ const resolvedUrl = typeof url === 'function' ? await url() : url;
71
+ const script = document.createElement('script')
72
+ script.type = 'text/javascript';
73
+ script.onload = fn;
74
+ script.src = resolvedUrl;
75
+ document.getElementsByTagName('head')[0].appendChild(script);
76
+ }
77
+ function get(name, ${REMOTE_FROM_PARAMETER}){
78
+ return import(/* @vite-ignore */ name).then(module => ()=> {
79
+ if (${REMOTE_FROM_PARAMETER} === 'webpack') {
80
+ return Object.prototype.toString.call(module).indexOf('Module') > -1 && module.default ? module.default : module
81
+ }
82
+ return module
83
+ })
84
+ }
85
+ const wrapShareScope = ${REMOTE_FROM_PARAMETER} => {
86
+ return {
87
+ ${getModuleMarker('shareScope')}
88
+ }
89
+ }
90
+
91
+ const initMap = Object.create(null);
92
+ async function __federation_method_ensure(remoteId) {
93
+ const remote = remotesMap[remoteId];
94
+ if (!remote.inited) {
95
+ if ('var' === remote.format) {
96
+ // loading js with script tag
97
+ return new Promise(resolve => {
98
+ const callback = () => {
99
+ if (!remote.inited) {
100
+ remote.lib = window[remoteId];
101
+ remote.lib.init(wrapShareScope(remote.from))
102
+ remote.inited = true;
103
+ }
104
+ resolve(remote.lib);
105
+ }
106
+ return loadJS(remote.url, callback);
107
+ });
108
+ } else if (['esm', 'systemjs'].includes(remote.format)) {
109
+ // loading js with import(...)
110
+ return new Promise((resolve, reject) => {
111
+ const getUrl = typeof remote.url === 'function' ? remote.url : () => Promise.resolve(remote.url);
112
+ getUrl().then(url => {
113
+ import(/* @vite-ignore */ url).then(lib => {
114
+ if (!remote.inited) {
115
+ const shareScope = wrapShareScope(remote.from)
116
+ lib.init(shareScope);
117
+ remote.lib = lib;
118
+ remote.lib.init(shareScope);
119
+ remote.inited = true;
120
+ }
121
+ resolve(remote.lib);
122
+ }).catch(reject)
123
+ })
124
+ })
125
+ }
126
+ } else {
127
+ return remote.lib;
128
+ }
129
+ }
130
+
131
+ function __federation_method_unwrapDefault(module) {
132
+ return (module?.__esModule || module?.[Symbol.toStringTag] === 'Module')?module.default:module
133
+ }
134
+
135
+ function __federation_method_wrapDefault(module ,need){
136
+ if (!module?.default && need) {
137
+ let obj = Object.create(null);
138
+ obj.default = module;
139
+ obj.__esModule = true;
140
+ return obj;
141
+ }
142
+ return module;
143
+ }
144
+
145
+ function __federation_method_getRemote(remoteName, componentName){
146
+ return __federation_method_ensure(remoteName).then((remote) => remote.get(componentName).then(factory => factory()));
147
+ }
148
+
149
+ function __federation_method_setRemote(remoteName, remoteConfig) {
150
+ remotesMap[remoteName] = remoteConfig;
151
+ }
152
+
153
+ async function __federation_method_add_origin_setRemote(remoteName, remoteUrl, options) {
154
+ const _options = options || {}
155
+ const _item = {
156
+ external: Array.isArray(_options.external) ? _options.external : [_options.external],
157
+ shareScope: _options.shareScope || 'default',
158
+ format: _options.format || 'esm',
159
+ from: _options.from ?? 'vite',
160
+ externalType: _options.externalType || 'url'
161
+ }
162
+
163
+ __federation_method_setRemote(remoteName, {
164
+ url: remoteUrl,
165
+ format: _item.format,
166
+ from: _item.from
167
+ })
168
+ }
169
+
170
+ export {__federation_method_ensure, __federation_method_getRemote , __federation_method_setRemote , __federation_method_unwrapDefault , __federation_method_wrapDefault, __federation_method_add_origin_setRemote}
171
+ ;`
172
+ }
173
+ : { __federation__: '' },
174
+ config(config: UserConfig) {
175
+ // need to include remotes in the optimizeDeps.exclude
176
+ if (parsedOptions.devRemote.length) {
177
+ const excludeRemotes: string[] = []
178
+ parsedOptions.devRemote.forEach((item) => excludeRemotes.push(item[0]))
179
+ let optimizeDeps = config.optimizeDeps
180
+ if (!optimizeDeps) {
181
+ optimizeDeps = config.optimizeDeps = {}
182
+ }
183
+ if (!optimizeDeps.exclude) {
184
+ optimizeDeps.exclude = []
185
+ }
186
+ optimizeDeps.exclude = optimizeDeps.exclude.concat(excludeRemotes)
187
+ }
188
+ },
189
+
190
+ configureServer(server: ViteDevServer) {
191
+ // get moduleGraph for dev mode dynamic reference
192
+ viteDevServer = server
193
+ },
194
+ async transform(this: TransformPluginContext, code: string, id: string) {
195
+ if (builderInfo.isHost && !builderInfo.isRemote) {
196
+ for (const arr of parsedOptions.devShared) {
197
+ if (!arr[1].version && !arr[1].manuallyPackagePathSetting) {
198
+ const packageJsonPath = (
199
+ await this.resolve(`${arr[0]}/package.json`)
200
+ )?.id
201
+ if (!packageJsonPath) {
202
+ this.error(
203
+ `No description file or no version in description file (usually package.json) of ${arr[0]}(${packageJsonPath}). Add version to description file, or manually specify version in shared config.`
204
+ )
205
+ } else {
206
+ const json = JSON.parse(
207
+ readFileSync(packageJsonPath, { encoding: 'utf-8' })
208
+ )
209
+ arr[1].version = json.version
210
+ }
211
+ }
212
+ }
213
+ }
214
+
215
+ if (id === '\0virtual:__federation__') {
216
+ const scopeCode = await devSharedScopeCode.call(
217
+ this,
218
+ parsedOptions.devShared
219
+ )
220
+ return code.replace(getModuleMarker('shareScope'), scopeCode.join(','))
221
+ }
222
+
223
+ // ignore some not need to handle file types
224
+ const fileExtname = getFileExtname(id)
225
+ if (!transformFileTypeSet.has((fileExtname ?? '').toLowerCase())) {
226
+ return
227
+ }
228
+
229
+ let ast: any | null = null
230
+ try {
231
+ ast = this.parse(code)
232
+ } catch (err) {
233
+ console.error(err)
234
+ }
235
+ if (!ast) {
236
+ return null
237
+ }
238
+
239
+ const magicString = new MagicString(code)
240
+ const hasStaticImported = new Map<string, string>()
241
+
242
+ let requiresRuntime = false
243
+ let manualRequired: any = null // set static import if exists
244
+ walk(ast, {
245
+ enter(node: any) {
246
+ if (
247
+ node.type === 'ImportDeclaration' &&
248
+ node.source?.value === 'virtual:__federation__'
249
+ ) {
250
+ manualRequired = node
251
+ }
252
+
253
+ if (
254
+ (node.type === 'ImportExpression' ||
255
+ node.type === 'ImportDeclaration' ||
256
+ node.type === 'ExportNamedDeclaration') &&
257
+ node.source?.value?.indexOf('/') > -1
258
+ ) {
259
+ const moduleId = node.source.value
260
+ const remote = devRemotes.find((r) => r.regexp.test(moduleId))
261
+ const needWrap = remote?.config.from === 'vite'
262
+ if (remote) {
263
+ requiresRuntime = true
264
+ const modName = `.${moduleId.slice(remote.id.length)}`
265
+ switch (node.type) {
266
+ case 'ImportExpression': {
267
+ magicString.overwrite(
268
+ node.start,
269
+ node.end,
270
+ `__federation_method_getRemote(${JSON.stringify(
271
+ remote.id
272
+ )} , ${JSON.stringify(
273
+ modName
274
+ )}).then(module=>__federation_method_wrapDefault(module, ${needWrap}))`
275
+ )
276
+ break
277
+ }
278
+ case 'ImportDeclaration': {
279
+ if (node.specifiers?.length) {
280
+ const afterImportName = `__federation_var_${moduleId.replace(
281
+ /[@/\\.-]/g,
282
+ ''
283
+ )}`
284
+ if (!hasStaticImported.has(moduleId)) {
285
+ magicString.overwrite(
286
+ node.start,
287
+ node.end,
288
+ `const ${afterImportName} = await __federation_method_getRemote(${JSON.stringify(
289
+ remote.id
290
+ )} , ${JSON.stringify(modName)});`
291
+ )
292
+ hasStaticImported.set(moduleId, afterImportName)
293
+ }
294
+ let deconstructStr = ''
295
+ node.specifiers.forEach((spec) => {
296
+ // default import , like import a from 'lib'
297
+ if (spec.type === 'ImportDefaultSpecifier') {
298
+ magicString.appendRight(
299
+ node.end,
300
+ `\n let ${spec.local.name} = __federation_method_unwrapDefault(${afterImportName}) `
301
+ )
302
+ } else if (spec.type === 'ImportSpecifier') {
303
+ // like import {a as b} from 'lib'
304
+ const importedName = spec.imported.name
305
+ const localName = spec.local.name
306
+ deconstructStr += `${
307
+ importedName === localName
308
+ ? localName
309
+ : `${importedName} : ${localName}`
310
+ },`
311
+ } else if (spec.type === 'ImportNamespaceSpecifier') {
312
+ // like import * as a from 'lib'
313
+ magicString.appendRight(
314
+ node.end,
315
+ `let {${spec.local.name}} = ${afterImportName}`
316
+ )
317
+ }
318
+ })
319
+ if (deconstructStr.length > 0) {
320
+ magicString.appendRight(
321
+ node.end,
322
+ `\n let {${deconstructStr.slice(
323
+ 0,
324
+ -1
325
+ )}} = ${afterImportName}`
326
+ )
327
+ }
328
+ }
329
+ break
330
+ }
331
+ case 'ExportNamedDeclaration': {
332
+ // handle export like export {a} from 'remotes/lib'
333
+ const afterImportName = `__federation_var_${moduleId.replace(
334
+ /[@/\\.-]/g,
335
+ ''
336
+ )}`
337
+ if (!hasStaticImported.has(moduleId)) {
338
+ hasStaticImported.set(moduleId, afterImportName)
339
+ magicString.overwrite(
340
+ node.start,
341
+ node.end,
342
+ `const ${afterImportName} = await __federation_method_getRemote(${JSON.stringify(
343
+ remote.id
344
+ )} , ${JSON.stringify(modName)});`
345
+ )
346
+ }
347
+ if (node.specifiers.length > 0) {
348
+ const specifiers = node.specifiers
349
+ let exportContent = ''
350
+ let deconstructContent = ''
351
+ specifiers.forEach((spec) => {
352
+ const localName = spec.local.name
353
+ const exportName = spec.exported.name
354
+ const variableName = `${afterImportName}_${localName}`
355
+ deconstructContent = deconstructContent.concat(
356
+ `${localName}:${variableName},`
357
+ )
358
+ exportContent = exportContent.concat(
359
+ `${variableName} as ${exportName},`
360
+ )
361
+ })
362
+ magicString.append(
363
+ `\n const {${deconstructContent.slice(
364
+ 0,
365
+ deconstructContent.length - 1
366
+ )}} = ${afterImportName}; \n`
367
+ )
368
+ magicString.append(
369
+ `\n export {${exportContent.slice(
370
+ 0,
371
+ exportContent.length - 1
372
+ )}}; `
373
+ )
374
+ }
375
+ break
376
+ }
377
+ }
378
+ }
379
+ }
380
+ }
381
+ })
382
+
383
+ if (requiresRuntime) {
384
+ let requiresCode = `import {__federation_method_ensure, __federation_method_getRemote , __federation_method_wrapDefault , __federation_method_unwrapDefault, __federation_method_add_origin_setRemote} from '__federation__';\n\n`
385
+ // clear static required
386
+ if (manualRequired) {
387
+ 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`
388
+ magicString.overwrite(manualRequired.start, manualRequired.end, ``)
389
+ }
390
+ magicString.prepend(requiresCode)
391
+ }
392
+ return magicString.toString()
393
+ }
394
+ }
395
+
396
+ async function devSharedScopeCode(
397
+ this: TransformPluginContext,
398
+ shared: (string | ConfigTypeSet)[]
399
+ ): Promise<string[]> {
400
+ const res: string[] = []
401
+ if (shared.length) {
402
+ const serverConfiguration = viteDevServer.config.server
403
+ const base = viteDevServer.config.base
404
+ const cwdPath = normalizePath(process.cwd())
405
+
406
+ for (const item of shared) {
407
+ const moduleInfo = await this.resolve(item[1].packagePath, undefined, {
408
+ skipSelf: true
409
+ })
410
+
411
+ if (!moduleInfo) continue
412
+
413
+ const moduleFilePath = normalizePath(moduleInfo.id)
414
+ const idx = moduleFilePath.indexOf(cwdPath)
415
+
416
+ const relativePath =
417
+ idx === 0 ? posix.join(base, moduleFilePath.slice(cwdPath.length)) : null
418
+
419
+ const sharedName = item[0]
420
+ const obj = item[1]
421
+ let str = ''
422
+ if (typeof obj === 'object') {
423
+ const origin = serverConfiguration.origin
424
+ const pathname = relativePath ?? `/@fs/${moduleInfo.id}`
425
+ const url = origin
426
+ ? `'${origin}${pathname}'`
427
+ : `window.location.origin+'${pathname}'`
428
+ str += `get:()=> get(${url}, ${REMOTE_FROM_PARAMETER})`
429
+ res.push(`'${sharedName}':{'${obj.version}':{${str}}}`)
430
+ }
431
+ }
432
+ }
433
+ return res
434
+ }
435
+ }
@@ -0,0 +1,29 @@
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 type { PluginHooks } from '../../types/pluginHooks'
17
+ import { parseSharedOptions } from '../utils'
18
+ import { parsedOptions } from '../public'
19
+ import type { VitePluginFederationOptions } from '../../types'
20
+
21
+ export function devSharedPlugin(
22
+ options: VitePluginFederationOptions
23
+ ): PluginHooks {
24
+ parsedOptions.devShared = parseSharedOptions(options)
25
+
26
+ return {
27
+ name: 'originjs:shared-development'
28
+ }
29
+ }
@@ -0,0 +1,242 @@
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 type {
17
+ ConfigEnv,
18
+ Plugin,
19
+ UserConfig,
20
+ ViteDevServer,
21
+ ResolvedConfig
22
+ } from 'vite'
23
+ import virtual from '@rollup/plugin-virtual'
24
+ import { dirname, isAbsolute, relative, resolve } from 'path'
25
+ import { prodRemotePlugin } from './prod/remote-production'
26
+ import type { VitePluginFederationOptions } from '../types'
27
+ import { builderInfo, DEFAULT_ENTRY_FILENAME, parsedOptions } from './public'
28
+ import type { PluginHooks } from '../types/pluginHooks'
29
+ import type { ModuleInfo } from 'rollup'
30
+ import { prodSharedPlugin } from './prod/shared-production'
31
+ import { prodExposePlugin } from './prod/expose-production'
32
+ import { devSharedPlugin } from './dev/shared-development'
33
+ import { devRemotePlugin } from './dev/remote-development'
34
+ import { devExposePlugin } from './dev/expose-development'
35
+
36
+ const normalizeAssetsDir = (config?: UserConfig) => {
37
+ const configured = config?.build?.assetsDir ?? 'assets'
38
+ if (!configured) return ''
39
+ if (!isAbsolute(configured)) return configured
40
+ const root = config?.root ? resolve(config.root) : process.cwd()
41
+ const resolvedOutDir = config?.build?.outDir
42
+ ? (isAbsolute(config.build.outDir)
43
+ ? config.build.outDir
44
+ : resolve(root, config.build.outDir))
45
+ : resolve(root, 'dist')
46
+ const normalized = relative(resolvedOutDir, configured).replace(/\\/g, '/')
47
+ return normalized.startsWith('..') ? '' : normalized || 'assets'
48
+ }
49
+
50
+ export { VitePluginFederationVersion } from './public'
51
+ export * from './runtime/dynamic-remote'
52
+ export default function federation(
53
+ options: VitePluginFederationOptions
54
+ ): Plugin {
55
+ options.filename = options.filename
56
+ ? options.filename
57
+ : DEFAULT_ENTRY_FILENAME
58
+
59
+ let pluginList: PluginHooks[] = []
60
+ let virtualMod
61
+ let registerCount = 0
62
+
63
+ function registerPlugins(mode: string, command: string) {
64
+ if (mode === 'production' || command === 'build') {
65
+ pluginList = [
66
+ prodSharedPlugin(options),
67
+ prodExposePlugin(options),
68
+ prodRemotePlugin(options)
69
+ ]
70
+ } else if (mode === 'development' || command === 'serve') {
71
+ pluginList = [
72
+ devSharedPlugin(options),
73
+ devExposePlugin(options),
74
+ devRemotePlugin(options)
75
+ ]
76
+ } else {
77
+ pluginList = []
78
+ }
79
+ builderInfo.isHost = options.isHost || !!(
80
+ parsedOptions.prodRemote.length || parsedOptions.devRemote.length
81
+ )
82
+ builderInfo.isRemote = !!(
83
+ parsedOptions.prodExpose.length || parsedOptions.devExpose.length
84
+ )
85
+ builderInfo.isShared = !!(
86
+ parsedOptions.prodShared.length || parsedOptions.devShared.length
87
+ )
88
+
89
+ let virtualFiles = {}
90
+ pluginList.forEach((plugin) => {
91
+ if (plugin.virtualFile) {
92
+ virtualFiles = Object.assign(virtualFiles, plugin.virtualFile)
93
+ }
94
+ })
95
+ virtualMod = virtual(virtualFiles)
96
+ }
97
+
98
+ return {
99
+ name: 'originjs:federation',
100
+ // for scenario vite.config.js build.cssCodeSplit: false
101
+ // vite:css-post plugin will summarize all the styles in the style.xxxxxx.css file
102
+ // so, this plugin need run after vite:css-post in post plugin list
103
+ enforce: 'post',
104
+ // apply:'build',
105
+ options(_options) {
106
+ // rollup doesnt has options.mode and options.command
107
+ if (!registerCount++) {
108
+ registerPlugins((options.mode = options.mode ?? 'production'), '')
109
+ }
110
+
111
+ if (typeof _options.input === 'string') {
112
+ _options.input = { index: _options.input }
113
+ }
114
+ _options.external = _options.external || []
115
+ if (!Array.isArray(_options.external)) {
116
+ _options.external = [_options.external as string]
117
+ }
118
+ for (const pluginHook of pluginList) {
119
+ // @ts-ignore
120
+ pluginHook.options?.call(this, _options)
121
+ }
122
+ return _options
123
+ },
124
+ config(config: UserConfig, env: ConfigEnv) {
125
+ options.mode = options.mode ?? env.mode
126
+ registerPlugins(options.mode, env.command)
127
+ registerCount++
128
+ for (const pluginHook of pluginList) {
129
+ // @ts-ignores
130
+ pluginHook.config?.call(this, config, env)
131
+ }
132
+
133
+ // only run when builder is vite,rollup doesnt has hook named `config`
134
+ builderInfo.builder = 'vite'
135
+ builderInfo.assetsDir = normalizeAssetsDir(config) ?? 'assets'
136
+ },
137
+ configureServer(server: ViteDevServer) {
138
+ for (const pluginHook of pluginList) {
139
+ // @ts-ignore
140
+ pluginHook.configureServer?.call(this, server)
141
+ }
142
+ },
143
+ configResolved(config: ResolvedConfig) {
144
+ for (const pluginHook of pluginList) {
145
+ // @ts-ignore
146
+ pluginHook.configResolved?.call(this, config)
147
+ }
148
+ },
149
+ buildStart(inputOptions) {
150
+ for (const pluginHook of pluginList) {
151
+ // @ts-ignore
152
+ pluginHook.buildStart?.call(this, inputOptions)
153
+ }
154
+ },
155
+
156
+ async resolveId(...args) {
157
+ const v = virtualMod.resolveId.call(this, ...args)
158
+ if (v) {
159
+ return v
160
+ }
161
+ if (args[0] === '\0virtual:__federation_fn_import') {
162
+ return {
163
+ id: '\0virtual:__federation_fn_import',
164
+ moduleSideEffects: true
165
+ }
166
+ }
167
+ if (args[0] === '__federation_fn_satisfy') {
168
+ const federationId = (
169
+ await this.resolve('@meethive/vite')
170
+ )?.id
171
+ if (federationId) {
172
+ return await this.resolve(`${dirname(federationId)}/satisfy.mjs`)
173
+ }
174
+ return null
175
+ }
176
+ if (args[0] === 'virtual:__federation__') {
177
+ return {
178
+ id: '\0virtual:__federation__',
179
+ moduleSideEffects: true
180
+ }
181
+ }
182
+ return null
183
+ },
184
+
185
+ load(...args) {
186
+ const v = virtualMod.load.call(this, ...args)
187
+ if (v) {
188
+ return v
189
+ }
190
+ return null
191
+ },
192
+
193
+ transform(code: string, id: string) {
194
+ for (const pluginHook of pluginList) {
195
+ // @ts-ignore
196
+ const result = pluginHook.transform?.call(this, code, id)
197
+ if (result) {
198
+ return result
199
+ }
200
+ }
201
+ return code
202
+ },
203
+ moduleParsed(moduleInfo: ModuleInfo): void {
204
+ for (const pluginHook of pluginList) {
205
+ // @ts-ignore
206
+ pluginHook.moduleParsed?.call(this, moduleInfo)
207
+ }
208
+ },
209
+
210
+ outputOptions(outputOptions) {
211
+ // @ts-ignore
212
+ for (const pluginHook of pluginList) {
213
+ // @ts-ignore
214
+ pluginHook.outputOptions?.call(this, outputOptions)
215
+ }
216
+ return outputOptions
217
+ },
218
+
219
+ renderChunk(code, chunkInfo, _options) {
220
+ for (const pluginHook of pluginList) {
221
+ // @ts-ignore
222
+ const result = pluginHook.renderChunk?.call(
223
+ this,
224
+ code,
225
+ chunkInfo,
226
+ _options
227
+ )
228
+ if (result) {
229
+ return result
230
+ }
231
+ }
232
+ return null
233
+ },
234
+
235
+ generateBundle: function (_options, bundle, isWrite) {
236
+ for (const pluginHook of pluginList) {
237
+ // @ts-ignore
238
+ pluginHook.generateBundle?.call(this, _options, bundle, isWrite)
239
+ }
240
+ }
241
+ }
242
+ }