From bbd0e5d6ec313c33f632de0dc5a16ed67ffddd00 Mon Sep 17 00:00:00 2001 From: zhn Date: Tue, 29 Oct 2024 17:21:07 +0800 Subject: [PATCH] fix: issue with multiple init calls in remote (#167) --- src/index.ts | 1 + src/plugins/pluginAddEntry.ts | 34 +++++++++++++++++++++--- src/virtualModules/virtualRemoteEntry.ts | 3 ++- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/index.ts b/src/index.ts index 1ad05a5..d9a657b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -38,6 +38,7 @@ function federation(mfUserOptions: ModuleFederationOptions): Plugin[] { ...addEntry({ entryName: 'hostInit', entryPath: getHostAutoInitPath(), + inject: 'html', }), ...addEntry({ entryName: 'virtualExposes', diff --git a/src/plugins/pluginAddEntry.ts b/src/plugins/pluginAddEntry.ts index 72396f5..93e3f07 100644 --- a/src/plugins/pluginAddEntry.ts +++ b/src/plugins/pluginAddEntry.ts @@ -6,13 +6,21 @@ interface AddEntryOptions { entryName: string; entryPath: string; fileName?: string; + inject?: 'entry' | 'html'; } -const addEntry = ({ entryName, entryPath, fileName }: AddEntryOptions): Plugin[] => { +const addEntry = ({ + entryName, + entryPath, + fileName, + inject = 'entry', +}: AddEntryOptions): Plugin[] => { const devEntryPath = entryPath.startsWith('virtual:mf') ? '/@id/' + entryPath : entryPath; let entryFiles: string[] = []; let htmlFilePath: string; let _command: string; + let emitFileId: string; + let viteConfig: any; return [ { @@ -50,6 +58,7 @@ const addEntry = ({ entryName, entryPath, fileName }: AddEntryOptions): Plugin[] name: 'add-entry', enforce: 'post', configResolved(config) { + viteConfig = config; const inputOptions = config.build.rollupOptions.input; if (!inputOptions) { @@ -77,7 +86,7 @@ const addEntry = ({ entryName, entryPath, fileName }: AddEntryOptions): Plugin[] if (!hasHash) { emitFileOptions.fileName = fileName; } - this.emitFile(emitFileOptions); + emitFileId = this.emitFile(emitFileOptions); if (htmlFilePath) { const htmlContent = fs.readFileSync(htmlFilePath, 'utf-8'); const scriptRegex = /]*src=["']([^"']+)["'][^>]*>/gi; @@ -88,8 +97,27 @@ const addEntry = ({ entryName, entryPath, fileName }: AddEntryOptions): Plugin[] } } }, + generateBundle(options, bundle) { + if (inject !== 'html') return; + const file = this.getFileName(emitFileId); + const scriptContent = ` + + `; + + for (const fileName in bundle) { + if (fileName.endsWith('.html')) { + let htmlAsset = bundle[fileName]; + if (htmlAsset.type === 'chunk') return; + let htmlContent = htmlAsset.source.toString() || ''; + + htmlContent = htmlContent.replace('', `${scriptContent}`); + + htmlAsset.source = htmlContent; + } + } + }, transform(code, id) { - if (entryFiles.some((file) => id.endsWith(file))) { + if (inject === 'entry' && entryFiles.some((file) => id.endsWith(file))) { const injection = ` import ${JSON.stringify(entryPath)}; `; diff --git a/src/virtualModules/virtualRemoteEntry.ts b/src/virtualModules/virtualRemoteEntry.ts index af7bc25..6450107 100644 --- a/src/virtualModules/virtualRemoteEntry.ts +++ b/src/virtualModules/virtualRemoteEntry.ts @@ -153,7 +153,8 @@ export function generateRemoteEntry(options: NormalizedModuleFederationOptions): * Inject entry file, automatically init when used as host, * and will not inject remoteEntry */ -const hostAutoInitModule = new VirtualModule('hostAutoInit'); +export const HOST_AUTO_INIT_TAG = '__H_A_I__'; +const hostAutoInitModule = new VirtualModule('hostAutoInit', HOST_AUTO_INIT_TAG); export function writeHostAutoInit() { hostAutoInitModule.writeSync(` import {init} from "${REMOTE_ENTRY_ID}"