@@ -17,11 +17,24 @@ import type { PluginHooks } from '../../types/pluginHooks'
1717import { NAME_CHAR_REG , parseSharedOptions , removeNonRegLetter } from '../utils'
1818import { parsedOptions } from '../public'
1919import type { ConfigTypeSet , VitePluginFederationOptions } from 'types'
20+ import { walk } from 'estree-walker'
21+ import MagicString from 'magic-string'
2022import { basename , join , resolve } from 'path'
2123import { readdirSync , readFileSync , statSync } from 'fs'
22- const sharedFilePathReg = / _ _ f e d e r a t i o n _ s h a r e d _ ( .+ ) - .{ 8 } \. j s $ /
24+ import type {
25+ NormalizedOutputOptions ,
26+ OutputChunk ,
27+ PluginContext
28+ } from 'rollup'
29+
2330import federation_fn_import from './federation_fn_import.js?raw'
2431
32+ const sharedFilePathReg = / _ _ f e d e r a t i o n _ s h a r e d _ ( .+ ) - .{ 8 } \. j s $ /
33+ const getSharedName = ( importName : string ) => {
34+ const regRst = sharedFilePathReg . exec ( importName )
35+ return regRst ?. [ 1 ]
36+ }
37+
2538export function prodSharedPlugin (
2639 options : VitePluginFederationOptions
2740) : PluginHooks {
@@ -34,6 +47,85 @@ export function prodSharedPlugin(
3447 let isRemote
3548 const id2Prop = new Map < string , any > ( )
3649
50+ const transformImportFn = function (
51+ this : PluginContext ,
52+ code ,
53+ chunk : OutputChunk
54+ ) {
55+ const ast = this . parse ( code )
56+ const magicString = new MagicString ( code )
57+ let importSharedRequired = false
58+ let importSharedFound = false
59+ let modified = false
60+
61+ walk ( ast , {
62+ enter ( node : any ) {
63+ if ( node . type === 'ImportDeclaration' ) {
64+ if (
65+ node . source . value . includes ( '__federation_fn_import-' ) &&
66+ node . specifiers . some (
67+ ( specify ) => specify . imported ?. name === 'importShared'
68+ )
69+ ) {
70+ importSharedFound = true
71+ }
72+
73+ const sharedName = getSharedName ( node . source . value )
74+ if ( sharedName ) {
75+ const declaration : ( string | never ) [ ] = [ ]
76+ if ( ! node . specifiers ?. length ) {
77+ // invalid import , like import './__federation_shared_lib.js' , and remove it
78+ magicString . remove ( node . start , node . end )
79+ modified = true
80+ } else {
81+ node . specifiers . forEach ( ( specify ) => {
82+ declaration . push (
83+ `${
84+ specify . imported ?. name
85+ ? `${
86+ specify . imported . name === specify . local . name
87+ ? specify . local . name
88+ : `${ specify . imported . name } :${ specify . local . name } `
89+ } `
90+ : `default:${ specify . local . name } `
91+ } `
92+ )
93+ } )
94+ }
95+ if ( declaration . length ) {
96+ magicString . overwrite (
97+ node . start ,
98+ node . end ,
99+ `const {${ declaration . join (
100+ ','
101+ ) } } = await importShared('${ sharedName } ');\n`
102+ )
103+ importSharedRequired = true
104+ modified = true
105+ }
106+ }
107+ }
108+ }
109+ } )
110+ if ( importSharedRequired && ! importSharedFound ) {
111+ const prop = id2Prop . get ( chunk . facadeModuleId as string )
112+ magicString . prepend (
113+ `import {importShared} from '${
114+ prop ?. root ? '.' : ''
115+ } ./__federation_fn_import.js';\n`
116+ )
117+ }
118+ if ( modified ) {
119+ return {
120+ code : magicString . toString ( ) ,
121+ map : magicString . generateMap ( {
122+ source : chunk . map ?. file ,
123+ hires : true
124+ } )
125+ }
126+ }
127+ }
128+
37129 return {
38130 name : 'originjs:shared-production' ,
39131 virtualFile : {
@@ -190,9 +282,25 @@ export function prodSharedPlugin(
190282 const chunk = bundle [ key ]
191283 if ( chunk . type === 'chunk' ) {
192284 if ( ! isHost ) {
193- const regRst = sharedFilePathReg . exec ( chunk . fileName )
194- if ( regRst && shareName2Prop . get ( regRst [ 1 ] ) ?. generate === false ) {
285+ const sharedName = getSharedName ( chunk . fileName )
286+ if (
287+ sharedName &&
288+ shareName2Prop . get ( sharedName ) ?. generate === false
289+ ) {
195290 needRemoveShared . add ( key )
291+ continue
292+ }
293+ const hasSharedImport = chunk . imports ?. some ( ( name ) =>
294+ sharedFilePathReg . test ( name )
295+ )
296+
297+ if ( hasSharedImport && options . format === 'es' ) {
298+ const transformedCode = transformImportFn . apply ( this , [
299+ chunk . code ,
300+ chunk
301+ ] )
302+ chunk . code = transformedCode ?. code ?? chunk . code
303+ chunk . map = transformedCode ?. map ?? chunk . map
196304 }
197305 }
198306 }
0 commit comments