1
- import type { Compiler , WebpackPluginInstance } from 'webpack' ;
1
+ import type { Compilation , Compiler , WebpackPluginInstance } from 'webpack' ;
2
2
import fs from 'fs' ;
3
3
import path from 'path' ;
4
4
import { isDev , getCompilerOutputDir } from './utils' ;
@@ -88,7 +88,130 @@ export class GenerateTypesPlugin implements WebpackPluginInstance {
88
88
return fn ;
89
89
} ;
90
90
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
+ } ;
92
215
93
216
compiler . hooks . thisCompilation . tap ( 'mf:generateTypes' , ( compilation ) => {
94
217
compilation . hooks . processAssets . tapPromise (
@@ -100,70 +223,9 @@ export class GenerateTypesPlugin implements WebpackPluginInstance {
100
223
} ,
101
224
async ( ) => {
102
225
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 ;
167
229
}
168
230
} ,
169
231
) ;
0 commit comments