@@ -141,6 +141,39 @@ export async function loadConfig({
141
141
return { content : content as RslibConfig , filePath : configFilePath } ;
142
142
}
143
143
144
+ // Match logic is derived from https://github.com/webpack/webpack/blob/94aba382eccf3de1004d235045d4462918dfdbb7/lib/ExternalModuleFactoryPlugin.js#L89-L158
145
+ const handleMatchedExternal = (
146
+ value : string | string [ ] | boolean | Record < string , string | string [ ] > ,
147
+ request : string ,
148
+ ) : boolean => {
149
+ if ( typeof value === 'boolean' ) {
150
+ return value ;
151
+ }
152
+
153
+ if ( typeof value === 'string' ) {
154
+ const [ first , second ] = value . split ( ' ' ) ;
155
+ const hasType = ! ! second ;
156
+ const _request = second ? second : first ;
157
+
158
+ // Don't need to warn explicit declared external type.
159
+ if ( ! hasType ) {
160
+ return request === _request ;
161
+ }
162
+
163
+ return false ;
164
+ }
165
+
166
+ if ( Array . isArray ( value ) ) {
167
+ return handleMatchedExternal ( value [ 0 ] ?? '' , request ) ;
168
+ }
169
+
170
+ if ( typeof value === 'object' ) {
171
+ return false ;
172
+ }
173
+
174
+ return false ;
175
+ } ;
176
+
144
177
const composeExternalsWarnConfig = (
145
178
format : Format ,
146
179
...externalsArray : NonNullable < EnvironmentConfig [ 'output' ] > [ 'externals' ] [ ]
@@ -163,18 +196,24 @@ const composeExternalsWarnConfig = (
163
196
const matchUserExternals = (
164
197
externals : NonNullable < EnvironmentConfig [ 'output' ] > [ 'externals' ] ,
165
198
request : string ,
166
- callback : ( matched ?: true ) => void ,
199
+ callback : ( matched : boolean , shouldWarn ?: boolean ) => void ,
167
200
) => {
201
+ // string
168
202
if ( typeof externals === 'string' ) {
169
- if ( externals === request ) {
170
- callback ( true ) ;
203
+ if ( handleMatchedExternal ( externals , request ) ) {
204
+ callback ( true , true ) ;
171
205
return ;
172
206
}
173
- } else if ( Array . isArray ( externals ) ) {
207
+ }
208
+ // array
209
+ if ( Array . isArray ( externals ) ) {
174
210
let i = 0 ;
175
211
const next = ( ) => {
176
212
let asyncFlag : boolean ;
177
- const handleExternalsAndCallback = ( matched ?: true ) => {
213
+ const handleExternalsAndCallback = (
214
+ matched : boolean ,
215
+ shouldWarn ?: boolean ,
216
+ ) => {
178
217
if ( ! matched ) {
179
218
if ( asyncFlag ) {
180
219
asyncFlag = false ;
@@ -183,13 +222,13 @@ const composeExternalsWarnConfig = (
183
222
return next ( ) ;
184
223
}
185
224
186
- callback ( matched ) ;
225
+ callback ( matched , shouldWarn ) ;
187
226
} ;
188
227
189
228
do {
190
229
asyncFlag = true ;
191
230
if ( i >= externals . length ) {
192
- return callback ( ) ;
231
+ return callback ( false ) ;
193
232
}
194
233
matchUserExternals (
195
234
externals [ i ++ ] ,
@@ -202,37 +241,47 @@ const composeExternalsWarnConfig = (
202
241
203
242
next ( ) ;
204
243
return ;
205
- } else if ( externals instanceof RegExp ) {
244
+ }
245
+ // regexp
246
+ if ( externals instanceof RegExp ) {
206
247
if ( externals . test ( request ) ) {
207
- callback ( true ) ;
248
+ callback ( true , true ) ;
208
249
return ;
209
250
}
210
- } else if ( typeof externals === 'function' ) {
251
+ }
252
+ // function
253
+ else if ( typeof externals === 'function' ) {
211
254
// TODO: Support function
212
- } else if ( typeof externals === 'object' ) {
255
+ }
256
+ // object
257
+ else if ( typeof externals === 'object' ) {
213
258
if ( Object . prototype . hasOwnProperty . call ( externals , request ) ) {
214
- callback ( true ) ;
259
+ if ( handleMatchedExternal ( externals [ request ] ! , request ) ) {
260
+ callback ( true , true ) ;
261
+ } else {
262
+ callback ( true ) ;
263
+ }
215
264
return ;
216
265
}
217
266
}
218
267
219
- callback ( ) ;
268
+ callback ( false ) ;
220
269
} ;
221
270
222
271
return {
223
272
output : {
224
273
externals : [
225
274
( { request, dependencyType, contextInfo } : any , callback : any ) => {
226
- let externalized = false ;
227
- const _callback = ( matched ?: true ) => {
228
- if ( matched ) {
229
- externalized = true ;
275
+ let shouldWarn = false ;
276
+ const _callback = ( _matched : boolean , _shouldWarn ?: boolean ) => {
277
+ if ( _shouldWarn ) {
278
+ shouldWarn = true ;
230
279
}
231
280
} ;
232
281
233
282
if ( contextInfo . issuer && dependencyType === 'commonjs' ) {
234
283
matchUserExternals ( externals , request , _callback ) ;
235
- if ( externalized ) {
284
+ if ( shouldWarn ) {
236
285
logger . warn ( composeModuleImportWarn ( request ) ) ;
237
286
}
238
287
}
@@ -1449,8 +1498,8 @@ async function composeLibRsbuildConfig(
1449
1498
const dtsConfig = await composeDtsConfig ( config , dtsExtension ) ;
1450
1499
const externalsWarnConfig = composeExternalsWarnConfig (
1451
1500
format ! ,
1452
- autoExternalConfig ?. output ?. externals ,
1453
1501
userExternalsConfig ?. output ?. externals ,
1502
+ autoExternalConfig ?. output ?. externals ,
1454
1503
) ;
1455
1504
const minifyConfig = composeMinifyConfig ( config ) ;
1456
1505
const bannerFooterConfig = composeBannerFooterConfig ( banner , footer ) ;
0 commit comments