1+ import fs from 'node:fs/promises' ;
12import path from 'path' ;
23import { appTools , defineConfig } from '@modern-js/app-tools' ;
34import { moduleFederationPlugin } from '@module-federation/modern-js-v3' ;
@@ -6,6 +7,45 @@ const serverOnlyEmptyPath = path.join(
67 path . dirname ( require . resolve ( 'server-only' ) ) ,
78 'empty.js' ,
89) ;
10+ const remoteDistStaticDir = path . resolve ( __dirname , '../remote/dist/static' ) ;
11+
12+ const copyRemoteExposeAssets = async ( subDir : 'js' | 'css' ) => {
13+ const remoteAsyncDir = path . join ( remoteDistStaticDir , subDir , 'async' ) ;
14+ const hostAsyncDir = path . resolve ( __dirname , 'dist/static' , subDir , 'async' ) ;
15+ const remoteFiles = await fs . readdir ( remoteAsyncDir ) . catch ( ( ) => [ ] ) ;
16+ if ( remoteFiles . length === 0 ) {
17+ return ;
18+ }
19+
20+ await fs . mkdir ( hostAsyncDir , { recursive : true } ) ;
21+ await Promise . all (
22+ remoteFiles
23+ . filter ( file => file . startsWith ( '__federation_expose_' ) )
24+ . map ( file =>
25+ fs . copyFile (
26+ path . join ( remoteAsyncDir , file ) ,
27+ path . join ( hostAsyncDir , file ) ,
28+ ) ,
29+ ) ,
30+ ) ;
31+ } ;
32+
33+ class CopyRemoteExposeAssetsPlugin {
34+ apply ( compiler : any ) {
35+ compiler . hooks . afterEmit . tapPromise (
36+ 'CopyRemoteExposeAssetsPlugin' ,
37+ async ( ) => {
38+ if ( compiler . options . mode !== 'production' ) {
39+ return ;
40+ }
41+ await Promise . all ( [
42+ copyRemoteExposeAssets ( 'js' ) ,
43+ copyRemoteExposeAssets ( 'css' ) ,
44+ ] ) ;
45+ } ,
46+ ) ;
47+ }
48+ }
949
1050export default defineConfig ( {
1151 server : {
@@ -35,6 +75,10 @@ export default defineConfig({
3575 . add ( 'import' )
3676 . add ( 'default' ) ;
3777 chain . resolve . alias . set ( 'server-only$' , serverOnlyEmptyPath ) ;
78+ } else {
79+ chain
80+ . plugin ( 'rsc-mf-copy-remote-exposes' )
81+ . use ( CopyRemoteExposeAssetsPlugin ) ;
3882 }
3983
4084 chain . resolve . modules
0 commit comments