1- import type { Compiler , WebpackPluginInstance } from 'webpack' ;
1+ import type { Compilation , Compiler , WebpackPluginInstance } from 'webpack' ;
22import fs from 'fs' ;
33import path from 'path' ;
44import { isDev , getCompilerOutputDir } from './utils' ;
@@ -88,7 +88,130 @@ export class GenerateTypesPlugin implements WebpackPluginInstance {
8888 return fn ;
8989 } ;
9090 const generateTypesFn = getGenerateTypesFn ( ) ;
91- let compiledOnce = false ;
91+
92+ const emitTypesFiles = async ( compilation : Compilation ) => {
93+ // Dev types will be generated by DevPlugin, the archive filename usually is dist/.dev-server.zip
94+ try {
95+ const { zipTypesPath, apiTypesPath, zipName, apiFileName } =
96+ retrieveTypesAssetsInfo ( finalOptions . remote ) ;
97+
98+ if ( isProd && zipName && compilation . getAsset ( zipName ) ) {
99+ callback ( ) ;
100+ return ;
101+ }
102+
103+ await generateTypesFn ( finalOptions ) ;
104+ const config = finalOptions . remote . moduleFederationConfig ;
105+ let zipPrefix = '' ;
106+ if ( typeof config . manifest === 'object' && config . manifest . filePath ) {
107+ zipPrefix = config . manifest . filePath ;
108+ } else if (
109+ typeof config . manifest === 'object' &&
110+ config . manifest . fileName
111+ ) {
112+ zipPrefix = path . dirname ( config . manifest . fileName ) ;
113+ } else if ( config . filename ) {
114+ zipPrefix = path . dirname ( config . filename ) ;
115+ }
116+
117+ if ( isProd ) {
118+ const zipAssetName = path . join ( zipPrefix , zipName ) ;
119+ const apiAssetName = path . join ( zipPrefix , apiFileName ) ;
120+ if ( zipTypesPath && ! compilation . getAsset ( zipAssetName ) ) {
121+ compilation . emitAsset (
122+ zipAssetName ,
123+ new compiler . webpack . sources . RawSource (
124+ fs . readFileSync ( zipTypesPath ) ,
125+ false ,
126+ ) ,
127+ ) ;
128+ }
129+
130+ if ( apiTypesPath && ! compilation . getAsset ( apiAssetName ) ) {
131+ compilation . emitAsset (
132+ apiAssetName ,
133+ new compiler . webpack . sources . RawSource (
134+ fs . readFileSync ( apiTypesPath ) ,
135+ false ,
136+ ) ,
137+ ) ;
138+ }
139+ callback ( ) ;
140+ } else {
141+ const isEEXIST = ( err : NodeJS . ErrnoException ) => {
142+ return err . code == 'EEXIST' ;
143+ } ;
144+ if ( zipTypesPath ) {
145+ const zipContent = fs . readFileSync ( zipTypesPath ) ;
146+ const zipOutputPath = path . join (
147+ compiler . outputPath ,
148+ zipPrefix ,
149+ zipName ,
150+ ) ;
151+ await new Promise < void > ( ( resolve , reject ) => {
152+ compiler . outputFileSystem . mkdir (
153+ path . dirname ( zipOutputPath ) ,
154+ ( err ) => {
155+ if ( err && ! isEEXIST ( err ) ) {
156+ reject ( err ) ;
157+ } else {
158+ compiler . outputFileSystem . writeFile (
159+ zipOutputPath ,
160+ zipContent ,
161+ ( writeErr ) => {
162+ if ( writeErr && ! isEEXIST ( writeErr ) ) {
163+ reject ( writeErr ) ;
164+ } else {
165+ resolve ( ) ;
166+ }
167+ } ,
168+ ) ;
169+ }
170+ } ,
171+ ) ;
172+ } ) ;
173+ }
174+
175+ if ( apiTypesPath ) {
176+ const apiContent = fs . readFileSync ( apiTypesPath ) ;
177+ const apiOutputPath = path . join (
178+ compiler . outputPath ,
179+ zipPrefix ,
180+ apiFileName ,
181+ ) ;
182+ await new Promise < void > ( ( resolve , reject ) => {
183+ compiler . outputFileSystem . mkdir (
184+ path . dirname ( apiOutputPath ) ,
185+ ( err ) => {
186+ if ( err && ! isEEXIST ( err ) ) {
187+ reject ( err ) ;
188+ } else {
189+ compiler . outputFileSystem . writeFile (
190+ apiOutputPath ,
191+ apiContent ,
192+ ( writeErr ) => {
193+ if ( writeErr && ! isEEXIST ( writeErr ) ) {
194+ reject ( writeErr ) ;
195+ } else {
196+ resolve ( ) ;
197+ }
198+ } ,
199+ ) ;
200+ }
201+ } ,
202+ ) ;
203+ } ) ;
204+ }
205+
206+ callback ( ) ;
207+ }
208+ } catch ( err ) {
209+ callback ( ) ;
210+ if ( finalOptions . displayErrorInTerminal ) {
211+ console . error ( 'Error in mf:generateTypes processAssets hook:' , err ) ;
212+ }
213+ }
214+ } ;
92215
93216 compiler . hooks . thisCompilation . tap ( 'mf:generateTypes' , ( compilation ) => {
94217 compilation . hooks . processAssets . tapPromise (
@@ -100,70 +223,9 @@ export class GenerateTypesPlugin implements WebpackPluginInstance {
100223 } ,
101224 async ( ) => {
102225 await consumeTypesPromise ;
103- try {
104- if ( pluginOptions . dev === false && compiledOnce ) {
105- return ;
106- }
107-
108- if ( compiledOnce ) {
109- // Dev types will be generated by DevPlugin, the archive filename usually is dist/.dev-server.zip
110- return ;
111- }
112-
113- const { zipTypesPath, apiTypesPath, zipName, apiFileName } =
114- retrieveTypesAssetsInfo ( finalOptions . remote ) ;
115- if ( zipName && compilation . getAsset ( zipName ) ) {
116- return ;
117- }
118-
119- await generateTypesFn ( finalOptions ) ;
120- const config = finalOptions . remote . moduleFederationConfig ;
121- let zipPrefix = '' ;
122- if (
123- typeof config . manifest === 'object' &&
124- config . manifest . filePath
125- ) {
126- zipPrefix = config . manifest . filePath ;
127- } else if (
128- typeof config . manifest === 'object' &&
129- config . manifest . fileName
130- ) {
131- zipPrefix = path . dirname ( config . manifest . fileName ) ;
132- } else if ( config . filename ) {
133- zipPrefix = path . dirname ( config . filename ) ;
134- }
135-
136- const zipAssetName = path . join ( zipPrefix , zipName ) ;
137- if ( zipTypesPath && ! compilation . getAsset ( zipAssetName ) ) {
138- compilation . emitAsset (
139- path . join ( zipPrefix , zipName ) ,
140- new compiler . webpack . sources . RawSource (
141- fs . readFileSync ( zipTypesPath ) ,
142- false ,
143- ) ,
144- ) ;
145- }
146-
147- const apiAssetName = path . join ( zipPrefix , apiFileName ) ;
148- if ( apiTypesPath && ! compilation . getAsset ( apiAssetName ) ) {
149- compilation . emitAsset (
150- path . join ( zipPrefix , apiFileName ) ,
151- new compiler . webpack . sources . RawSource (
152- fs . readFileSync ( apiTypesPath ) ,
153- false ,
154- ) ,
155- ) ;
156- }
157- compiledOnce = true ;
158- callback ( ) ;
159- } catch ( err ) {
160- callback ( ) ;
161- if ( finalOptions . displayErrorInTerminal ) {
162- console . error (
163- 'Error in mf:generateTypes processAssets hook:' ,
164- err ,
165- ) ;
166- }
226+ const emitTypesFilesPromise = emitTypesFiles ( compilation ) ;
227+ if ( isProd ) {
228+ await emitTypesFilesPromise ;
167229 }
168230 } ,
169231 ) ;
0 commit comments