44 type EnvironmentConfig ,
55 type RsbuildConfig ,
66 type RsbuildPlugin ,
7+ type Rspack ,
78 defineConfig as defineRsbuildConfig ,
89 loadConfig as loadRsbuildConfig ,
910 mergeRsbuildConfig ,
@@ -36,6 +37,7 @@ import type {
3637 DeepRequired ,
3738 ExcludesFalse ,
3839 Format ,
40+ GetAsyncFunctionFromUnion ,
3941 LibConfig ,
4042 LibOnlyConfig ,
4143 PkgJson ,
@@ -949,23 +951,37 @@ const composeBundleConfig = (
949951
950952 const isStyleRedirect = redirect . style ?? true ;
951953
954+ type Resolver = GetAsyncFunctionFromUnion <
955+ ReturnType < NonNullable < Rspack . ExternalItemFunctionData [ 'getResolve' ] > >
956+ > ;
957+ let resolver : Resolver | undefined ;
958+
952959 return {
953960 output : {
954961 externals : [
955- ( data : any , callback : any ) => {
962+ async ( data , callback ) => {
963+ const { request, getResolve, context, contextInfo } = data ;
964+ if ( ! request || ! getResolve || ! context || ! contextInfo ) {
965+ return callback ( ) ;
966+ }
967+
968+ if ( ! resolver ) {
969+ resolver = ( await getResolve ( ) ) as Resolver ;
970+ }
971+
956972 // Issuer is not empty string when the module is imported by another module.
957973 // Prevent from externalizing entry modules here.
958- if ( data . contextInfo . issuer ) {
974+ if ( contextInfo . issuer ) {
959975 // Node.js ECMAScript module loader does no extension searching.
960976 // Add a file extension according to autoExtension config
961977 // when data.request is a relative path and do not have an extension.
962978 // If data.request already have an extension, we replace it with new extension
963979 // This may result in a change in semantics,
964980 // user should use copy to keep origin file or use another separate entry to deal this
965- let request : string = data . request ;
981+ let resolvedRequest : string = request ;
966982
967983 const cssExternal = cssExternalHandler (
968- request ,
984+ resolvedRequest ,
969985 callback ,
970986 jsExtension ,
971987 cssModulesAuto ,
@@ -976,27 +992,40 @@ const composeBundleConfig = (
976992 return cssExternal ;
977993 }
978994
979- if ( request [ 0 ] === '.' ) {
980- const ext = extname ( request ) ;
995+ if ( resolvedRequest [ 0 ] === '.' ) {
996+ const resolved = await resolver ( context , resolvedRequest ) ;
997+ resolvedRequest = path . posix . relative (
998+ path . dirname ( contextInfo . issuer ) ,
999+ resolved ,
1000+ ) ;
1001+
1002+ if ( resolvedRequest [ 0 ] !== '.' ) {
1003+ resolvedRequest = `./${ resolvedRequest } ` ;
1004+ }
1005+
1006+ const ext = extname ( resolvedRequest ) ;
9811007
9821008 if ( ext ) {
983- if ( JS_EXTENSIONS_PATTERN . test ( request ) ) {
984- request = request . replace ( / \. [ ^ . ] + $ / , jsExtension ) ;
1009+ if ( JS_EXTENSIONS_PATTERN . test ( resolvedRequest ) ) {
1010+ resolvedRequest = resolvedRequest . replace (
1011+ / \. [ ^ . ] + $ / ,
1012+ jsExtension ,
1013+ ) ;
9851014 } else {
9861015 // If it does not match jsExtensionsPattern, we should do nothing, eg: ./foo.png
9871016 return callback ( ) ;
9881017 }
9891018 } else {
9901019 // TODO: add redirect.extension option
991- request = `${ request } ${ jsExtension } ` ;
1020+ resolvedRequest = `${ resolvedRequest } ${ jsExtension } ` ;
9921021 }
9931022 }
9941023
995- return callback ( null , request ) ;
1024+ return callback ( undefined , resolvedRequest ) ;
9961025 }
9971026 callback ( ) ;
9981027 } ,
999- ] ,
1028+ ] as Rspack . ExternalItem [ ] ,
10001029 } ,
10011030 } ;
10021031} ;
0 commit comments