Skip to content

Commit

Permalink
Fix multiple react imports during runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
wurstbonbon committed Mar 15, 2024
1 parent cfaa562 commit 74c2414
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 11 deletions.
9 changes: 1 addition & 8 deletions packages/lib/src/prod/remote-production.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import { walk } from 'estree-walker'
import MagicString from 'magic-string'
import type { AcornNode, TransformPluginContext } from 'rollup'
import type { ConfigTypeSet, VitePluginFederationOptions } from 'types'
import type { VitePluginFederationOptions } from 'types'
import type { PluginHooks } from '../../types/pluginHooks'
import {
builderInfo,
Expand All @@ -31,11 +31,6 @@ import {
REMOTE_FROM_PARAMETER
} from '../utils'

const sharedFileName2Prop: Map<string, ConfigTypeSet> = new Map<
string,
ConfigTypeSet
>()

export function prodRemotePlugin(
options: VitePluginFederationOptions
): PluginHooks {
Expand Down Expand Up @@ -476,5 +471,3 @@ export function prodRemotePlugin(
}
}
}

export { sharedFileName2Prop }
110 changes: 107 additions & 3 deletions packages/lib/src/prod/shared-production.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,20 @@ import type { PluginHooks } from '../../types/pluginHooks'
import { NAME_CHAR_REG, parseSharedOptions, removeNonRegLetter } from '../utils'
import { parsedOptions } from '../public'
import type { ConfigTypeSet, VitePluginFederationOptions } from 'types'
import { walk } from 'estree-walker'
import MagicString from 'magic-string'
import { basename, join, resolve } from 'path'
import { readdirSync, readFileSync, statSync } from 'fs'
const sharedFilePathReg = /__federation_shared_(.+)-.{8}\.js$/
import type { OutputChunk, PluginContext } from 'rollup'

import federation_fn_import from './federation_fn_import.js?raw'

const sharedFilePathReg = /__federation_shared_(.+)-.{8}\.js$/
const getSharedName = (importName: string) => {
const regRst = sharedFilePathReg.exec(importName)
return regRst?.[1]
}

export function prodSharedPlugin(
options: VitePluginFederationOptions
): PluginHooks {
Expand All @@ -34,6 +43,85 @@ export function prodSharedPlugin(
let isRemote
const id2Prop = new Map<string, any>()

const transformImportFn = function (
this: PluginContext,
code,
chunk: OutputChunk
) {
const ast = this.parse(code)
const magicString = new MagicString(code)
let importSharedRequired = false
let importSharedFound = false
let modified = false

walk(ast, {
enter(node: any) {
if (node.type === 'ImportDeclaration') {
if (
node.source.value.includes('__federation_fn_import-') &&
node.specifiers.some(
(specify) => specify.imported?.name === 'importShared'
)
) {
importSharedFound = true
}

const sharedName = getSharedName(node.source.value)
if (sharedName) {
const declaration: (string | never)[] = []
if (!node.specifiers?.length) {
// invalid import , like import './__federation_shared_lib.js' , and remove it
magicString.remove(node.start, node.end)
modified = true
} else {
node.specifiers.forEach((specify) => {
declaration.push(
`${
specify.imported?.name
? `${
specify.imported.name === specify.local.name
? specify.local.name
: `${specify.imported.name}:${specify.local.name}`
}`
: `default:${specify.local.name}`
}`
)
})
}
if (declaration.length) {
magicString.overwrite(
node.start,
node.end,
`const {${declaration.join(
','
)}} = await importShared('${sharedName}');\n`
)
importSharedRequired = true
modified = true
}
}
}
}
})
if (importSharedRequired && !importSharedFound) {
const prop = id2Prop.get(chunk.facadeModuleId as string)
magicString.prepend(
`import {importShared} from '${
prop?.root ? '.' : ''
}./__federation_fn_import.js';\n`
)
}
if (modified) {
return {
code: magicString.toString(),
map: magicString.generateMap({
source: chunk.map?.file,
hires: true
})
}
}
}

return {
name: 'originjs:shared-production',
virtualFile: {
Expand Down Expand Up @@ -190,9 +278,25 @@ export function prodSharedPlugin(
const chunk = bundle[key]
if (chunk.type === 'chunk') {
if (!isHost) {
const regRst = sharedFilePathReg.exec(chunk.fileName)
if (regRst && shareName2Prop.get(regRst[1])?.generate === false) {
const sharedName = getSharedName(chunk.fileName)
if (
sharedName &&
shareName2Prop.get(sharedName)?.generate === false
) {
needRemoveShared.add(key)
continue
}
const hasSharedImport = chunk.imports?.some((name) =>
sharedFilePathReg.test(name)
)

if (hasSharedImport && options.format === 'es') {
const transformedCode = transformImportFn.apply(this, [
chunk.code,
chunk
])
chunk.code = transformedCode?.code ?? chunk.code
chunk.map = transformedCode?.map ?? chunk.map
}
}
}
Expand Down

0 comments on commit 74c2414

Please sign in to comment.