@@ -3,14 +3,15 @@ const path = require("path");
3
3
const fetch = require ( "node-fetch" ) ;
4
4
const AutomaticVendorFederation = require ( "@module-federation/automatic-vendor-federation" ) ;
5
5
const convertToGraph = require ( "./convertToGraph" ) ;
6
+ const mergeGraphs = require ( "./mergeGraphs" ) ;
6
7
const DefinePlugin = require ( "webpack/lib/DefinePlugin" ) ;
7
8
const parser = require ( "@babel/parser" ) ;
8
9
const generate = require ( "@babel/generator" ) . default ;
9
10
const traverse = require ( "@babel/traverse" ) . default ;
10
11
const { isNode } = require ( "@babel/types" ) ;
11
12
const webpack = require ( "webpack" ) ;
12
- /** @typedef {import(' webpack/lib/Compilation' ) } Compilation */
13
- /** @typedef {import(' webpack/lib/Compiler' ) } Compiler */
13
+ /** @typedef {import(" webpack/lib/Compilation" ) } Compilation */
14
+ /** @typedef {import(" webpack/lib/Compiler" ) } Compiler */
14
15
15
16
/**
16
17
* @typedef FederationDashboardPluginOptions
@@ -44,7 +45,8 @@ class FederationDashboardPlugin {
44
45
if ( FederationPlugin ) {
45
46
this . FederationPluginOptions = Object . assign (
46
47
{ } ,
47
- FederationPlugin . _options
48
+ FederationPlugin . _options ,
49
+ this . _options . standalone || { }
48
50
) ;
49
51
} else if ( this . _options . standalone ) {
50
52
this . FederationPluginOptions = this . _options . standalone ;
@@ -53,6 +55,7 @@ class FederationDashboardPlugin {
53
55
"Dashboard plugin is missing Module Federation or standalone option"
54
56
) ;
55
57
}
58
+
56
59
this . FederationPluginOptions . name =
57
60
this . FederationPluginOptions . name . replace ( "__REMOTE_VERSION__" , "" ) ;
58
61
compiler . hooks . thisCompilation . tap ( PLUGIN_NAME , ( compilation ) => {
@@ -61,7 +64,7 @@ class FederationDashboardPlugin {
61
64
name : PLUGIN_NAME ,
62
65
stage : compilation . constructor . PROCESS_ASSETS_STAGE_REPORT ,
63
66
} ,
64
- ( ) => this . processWebpackGraph ( compilation )
67
+ ( ) => this . processWebpackGraph ( compilation )
65
68
) ;
66
69
} ) ;
67
70
@@ -177,13 +180,14 @@ class FederationDashboardPlugin {
177
180
this . parseModuleAst ( curCompiler ) ;
178
181
}
179
182
180
- let gitSha
183
+ let gitSha ;
181
184
try {
182
- gitSha = require ( 'child_process' )
183
- . execSync ( 'git rev-parse HEAD' )
184
- . toString ( ) . trim ( )
185
- } catch ( e ) {
186
- console . error ( e )
185
+ gitSha = require ( "child_process" )
186
+ . execSync ( "git rev-parse HEAD" )
187
+ . toString ( )
188
+ . trim ( ) ;
189
+ } catch ( e ) {
190
+ console . error ( e ) ;
187
191
}
188
192
189
193
// filter modules
@@ -227,19 +231,15 @@ class FederationDashboardPlugin {
227
231
228
232
if ( graphData ) {
229
233
const dashData = ( this . _dashData = JSON . stringify ( graphData ) ) ;
230
-
231
234
// this.writeStatsFiles(stats, dashData);
232
-
233
- if ( this . _options . dashboardURL ) {
234
- this . postDashboardData ( dashData )
235
- . then ( ( ) => { } )
236
- . catch ( ( err ) => {
237
- if ( err ) {
238
- curCompiler . errors . push ( err ) ;
239
- // eslint-disable-next-line promise/no-callback-in-promise
240
- throw err ;
241
- }
242
- } ) ;
235
+ if ( this . _options . dashboardURL && ! this . _options . nextjs ) {
236
+ this . postDashboardData ( dashData ) . catch ( ( err ) => {
237
+ if ( err ) {
238
+ curCompiler . errors . push ( err ) ;
239
+ // eslint-disable-next-line promise/no-callback-in-promise
240
+ throw err ;
241
+ }
242
+ } ) ;
243
243
}
244
244
return Promise . resolve ( ) . then ( ( ) => {
245
245
const statsBuf = Buffer . from ( dashData || "{}" , "utf-8" ) ;
@@ -255,15 +255,18 @@ class FederationDashboardPlugin {
255
255
// for dashboard.json
256
256
if ( curCompiler . emitAsset && this . _options . filename ) {
257
257
const asset = curCompiler . getAsset ( this . _options . filename ) ;
258
-
259
258
if ( asset ) {
260
259
curCompiler . updateAsset ( this . _options . filename , source ) ;
261
260
} else {
262
261
curCompiler . emitAsset ( this . _options . filename , source ) ;
263
262
}
264
263
}
265
264
// for versioned remote
266
- if ( curCompiler . emitAsset && this . FederationPluginOptions . filename ) {
265
+ if (
266
+ curCompiler . emitAsset &&
267
+ this . FederationPluginOptions . filename &&
268
+ Object . keys ( this . FederationPluginOptions . exposes || { } ) . length !== 0
269
+ ) {
267
270
const remoteEntry = curCompiler . getAsset (
268
271
this . FederationPluginOptions . filename
269
272
) ;
@@ -368,12 +371,9 @@ class FederationDashboardPlugin {
368
371
buildVendorFederationMap ( liveStats ) {
369
372
const vendorFederation = { } ;
370
373
let packageJson ;
371
- this . _webpackContext = liveStats . compilation . options . context ;
372
374
try {
373
- packageJson = require ( path . join (
374
- liveStats . compilation . options . context ,
375
- "package.json"
376
- ) ) ;
375
+ packageJson = require ( this . _options . packageJsonPath ||
376
+ path . join ( liveStats . compilation . options . context , "package.json" ) ) ;
377
377
this . _packageJson = packageJson ;
378
378
} catch ( e ) { }
379
379
@@ -530,6 +530,9 @@ class FederationDashboardPlugin {
530
530
}
531
531
532
532
async postDashboardData ( dashData ) {
533
+ if ( ! this . _options . dashboardURL ) {
534
+ return Promise . resolve ( ) ;
535
+ }
533
536
try {
534
537
const res = await fetch ( this . _options . dashboardURL , {
535
538
method : "POST" ,
@@ -540,7 +543,7 @@ class FederationDashboardPlugin {
540
543
} ,
541
544
} ) ;
542
545
543
- if ( ! res . ok ) throw new Error ( msg ) ;
546
+ if ( ! res . ok ) throw new Error ( res . statusText ) ;
544
547
} catch ( err ) {
545
548
console . warn (
546
549
`Error posting data to dashboard URL: ${ this . _options . dashboardURL } `
@@ -550,6 +553,90 @@ class FederationDashboardPlugin {
550
553
}
551
554
}
552
555
553
- FederationDashboardPlugin . clientVersion = require ( "./client-version" ) ;
556
+ class NextMedusaPlugin {
557
+ constructor ( options ) {
558
+ this . _options = options ;
559
+ }
560
+
561
+ apply ( compiler ) {
562
+ const sidecarData = this . _options . filename . includes ( "sidecar" )
563
+ ? path . join ( compiler . options . output . path , this . _options . filename )
564
+ : path . join (
565
+ compiler . options . output . path ,
566
+ "sidecar-" + this . _options . filename
567
+ ) ;
568
+ const hostData = path . join (
569
+ compiler . options . output . path ,
570
+ this . _options . filename . replace ( "sidecar-" , "" )
571
+ ) ;
572
+
573
+ const MedusaPlugin = new FederationDashboardPlugin ( {
574
+ ...this . _options ,
575
+ nextjs : true ,
576
+ } ) ;
577
+ MedusaPlugin . apply ( compiler ) ;
578
+
579
+ compiler . hooks . afterEmit . tap ( PLUGIN_NAME , ( ) => {
580
+ const sidecarData = path . join (
581
+ compiler . options . output . path ,
582
+ "sidecar-" + this . _options . filename
583
+ ) ;
584
+ const hostData = path . join (
585
+ compiler . options . output . path ,
586
+ this . _options . filename . replace ( "sidecar-" , "" )
587
+ ) ;
588
+ if ( fs . existsSync ( sidecarData ) && fs . existsSync ( hostData ) ) {
589
+ fs . writeFileSync (
590
+ hostData ,
591
+ JSON . stringify ( mergeGraphs ( require ( sidecarData ) , require ( hostData ) ) )
592
+ ) ;
593
+ }
594
+ } ) ;
595
+
596
+ compiler . hooks . done . tapAsync ( "NextMedusaPlugin" , ( stats , done ) => {
597
+ if ( fs . existsSync ( sidecarData ) && fs . existsSync ( hostData ) ) {
598
+ const dashboardData = fs . readFileSync ( hostData , "utf8" ) ;
599
+ MedusaPlugin . postDashboardData ( dashboardData ) . then ( done ) . catch ( done ) ;
600
+ } else {
601
+ done ( ) ;
602
+ }
603
+ } ) ;
604
+ }
605
+ }
606
+
607
+ const withMedusa =
608
+ ( { name, ...medusaConfig } ) =>
609
+ ( nextConfig = { } ) => {
610
+ return Object . assign ( { } , nextConfig , {
611
+ webpack ( config , options ) {
612
+ if (
613
+ options . nextRuntime !== "edge" &&
614
+ ! options . isServer &&
615
+ process . env . NODE_ENV === "production"
616
+ ) {
617
+ if ( ! name ) {
618
+ throw new Error (
619
+ "Medusa needs a name for the app, please ensure plugin options has {name: <appname>}"
620
+ ) ;
621
+ }
622
+ config . plugins . push (
623
+ new NextMedusaPlugin ( {
624
+ standalone : { name } ,
625
+ ...medusaConfig ,
626
+ } )
627
+ ) ;
628
+ }
629
+
630
+ if ( typeof nextConfig . webpack === "function" ) {
631
+ return nextConfig . webpack ( config , options ) ;
632
+ }
633
+
634
+ return config ;
635
+ } ,
636
+ } ) ;
637
+ } ;
554
638
555
639
module . exports = FederationDashboardPlugin ;
640
+ module . exports . clientVersion = require ( "./client-version" ) ;
641
+ module . exports . NextMedusaPlugin = NextMedusaPlugin ;
642
+ module . exports . withMedusa = withMedusa ;
0 commit comments