-
Notifications
You must be signed in to change notification settings - Fork 206
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dynamic mf, sharing libs, bootstrap/main
- Loading branch information
1 parent
b4d3837
commit 12528da
Showing
11 changed files
with
211 additions
and
14 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './utils/dynamic-federation'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
const moduleMap = {}; | ||
const remoteMap = {} | ||
let isDefaultScopeInitialized = false; | ||
|
||
async function lookupExposedModule<T>(remoteName: string, exposedModule: string): Promise<T> { | ||
const container = window[remoteName] as Container; | ||
const factory = await container.get(exposedModule); | ||
const Module = factory(); | ||
return Module as T; | ||
} | ||
|
||
async function initRemote(remoteName: string) { | ||
const container = window[remoteName] as Container; | ||
|
||
// Do we still need to initialize the remote? | ||
if (remoteMap[remoteName]) { | ||
return container; | ||
} | ||
|
||
// Do we still need to initialize the share scope? | ||
if (!isDefaultScopeInitialized) { | ||
await __webpack_init_sharing__('default'); | ||
isDefaultScopeInitialized = true; | ||
} | ||
|
||
await container.init(__webpack_share_scopes__.default); | ||
remoteMap[remoteName] = true; | ||
return container; | ||
} | ||
|
||
export type LoadRemoteModuleOptions = { | ||
remoteEntry?: string; | ||
remoteName: string; | ||
exposedModule: string | ||
} | ||
|
||
export function loadRemoteEntry(remoteEntry: string, remoteName: string): Promise<void> { | ||
return new Promise<any>((resolve, reject) => { | ||
|
||
// Is remoteEntry already loaded? | ||
if (moduleMap[remoteEntry]) { | ||
resolve(); | ||
return; | ||
} | ||
|
||
const script = document.createElement('script'); | ||
script.src = remoteEntry; | ||
|
||
script.onerror = reject; | ||
|
||
script.onload = () => { | ||
initRemote(remoteName); | ||
moduleMap[remoteEntry] = true; | ||
resolve(); | ||
} | ||
|
||
document.body.append(script); | ||
}); | ||
} | ||
|
||
export async function loadRemoteModule<T = any>(options: LoadRemoteModuleOptions): Promise<T> { | ||
if (options.remoteEntry) { | ||
await loadRemoteEntry(options.remoteEntry, options.remoteName); | ||
} | ||
return await lookupExposedModule<T>(options.remoteName, options.exposedModule); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import {NormalModuleReplacementPlugin} from 'webpack'; | ||
import * as path from 'path'; | ||
import * as fs from 'fs'; | ||
import * as JSON5 from 'json5'; | ||
|
||
|
||
interface KeyValuePair { | ||
key: string; | ||
value: string; | ||
} | ||
|
||
export class SharedMappings { | ||
|
||
private mappings: KeyValuePair[] = []; | ||
|
||
register(tsConfigPath: string, shared: string[] = null): void { | ||
|
||
if (!path.isAbsolute(tsConfigPath)) { | ||
throw new Error('SharedMappings.register: tsConfigPath needs to be an absolute path!'); | ||
} | ||
|
||
const tsConfig = JSON5.parse( | ||
fs.readFileSync(tsConfigPath, {encoding: 'UTF8'})); | ||
const mappings = tsConfig?.compilerOptions?.paths; | ||
const rootPath = path.normalize(path.dirname(tsConfigPath)); | ||
|
||
if (!mappings) { | ||
return; | ||
} | ||
|
||
for (const key in mappings) { | ||
if (!shared || shared.length === 0 || shared.includes(key)) { | ||
this.mappings.push({ | ||
key, | ||
value: path.normalize(path.join(rootPath, mappings[key][0])) | ||
}); | ||
} | ||
} | ||
} | ||
|
||
getPlugin(): NormalModuleReplacementPlugin { | ||
return new NormalModuleReplacementPlugin(/./, (req) => { | ||
const from = req.context; | ||
const to = path.normalize(path.join(req.context, req.request)); | ||
|
||
if (!req.request.startsWith('.')) return; | ||
|
||
for (const m of this.mappings) { | ||
const libFolder = path.normalize(path.dirname(m.value)); | ||
if (!from.startsWith(libFolder) && to.startsWith(libFolder)) { | ||
req.request = m.key; | ||
// console.log('remapping', { from, to, libFolder }); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
getDescriptors(): object { | ||
const result = {}; | ||
|
||
for (const m of this.mappings) { | ||
result[m.key] = { | ||
import: m.value, | ||
requiredVersion: false | ||
}; | ||
} | ||
|
||
return result; | ||
} | ||
|
||
getDescriptor(mappedPath: string, requiredVersion: string = null): any { | ||
|
||
if (!this.mappings[mappedPath]) { | ||
throw new Error('No mapping found for ' + mappedPath + ' in tsconfig'); | ||
} | ||
|
||
return ({ | ||
[mappedPath]: { | ||
import: this.mappings[mappedPath], | ||
requiredVersion: requiredVersion ?? false | ||
} | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
type Scope = unknown; | ||
type Factory = () => any; | ||
|
||
type Container = { | ||
init(shareScope: Scope): void; | ||
get(module: string): Factory; | ||
}; | ||
|
||
declare const __webpack_init_sharing__: (shareScope: string) => Promise<void>; | ||
declare const __webpack_share_scopes__: { default: Scope }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './utils/shared-mappings'; |