@@ -23,7 +23,7 @@ pub enum Request {
2323 fragment : RcStr ,
2424 } ,
2525 Module {
26- module : RcStr ,
26+ module : Pattern ,
2727 path : Pattern ,
2828 query : RcStr ,
2929 fragment : RcStr ,
@@ -236,7 +236,7 @@ impl Request {
236236 let ( path, query, fragment) = split_off_query_fragment ( path. as_str ( ) ) ;
237237
238238 return Request :: Module {
239- module : module. as_str ( ) . into ( ) ,
239+ module : RcStr :: from ( module. as_str ( ) ) . into ( ) ,
240240 path,
241241 query,
242242 fragment,
@@ -255,6 +255,12 @@ impl Request {
255255
256256 let mut result = Self :: parse_ref ( list[ 0 ] . clone ( ) ) ;
257257
258+ let mut was_module_name_terminated = if let Request :: Module { path, .. } = & result {
259+ !path. is_empty ( )
260+ } else {
261+ false
262+ } ;
263+
258264 for item in list. into_iter ( ) . skip ( 1 ) {
259265 match & mut result {
260266 Request :: Raw { path, .. } => {
@@ -263,8 +269,22 @@ impl Request {
263269 Request :: Relative { path, .. } => {
264270 path. push ( item) ;
265271 }
266- Request :: Module { path, .. } => {
267- path. push ( item) ;
272+ Request :: Module { module, path, .. } => {
273+ if !was_module_name_terminated && matches ! ( item, Pattern :: Dynamic ) {
274+ // TODO ideally this would be more general (i.e. support also
275+ // `module-part<dynamic>more-module/subpath`) and not just handle
276+ // Pattern::Dynamic, but this covers the common case of
277+ // `require('@img/sharp-' + arch + '/sharp.node')`
278+
279+ // Insert dynamic between module and path (by adding it to both of them,
280+ // because both could happen). Note that path is empty at this
281+ // point anyway.
282+ module. push ( Pattern :: Dynamic ) ;
283+ path. push ( item) ;
284+ } else {
285+ path. push ( item) ;
286+ was_module_name_terminated = true ;
287+ }
268288 }
269289 Request :: ServerRelative { path, .. } => {
270290 path. push ( item) ;
@@ -358,7 +378,7 @@ impl Request {
358378 }
359379
360380 #[ turbo_tasks:: function]
361- pub fn module ( module : RcStr , path : Pattern , query : RcStr , fragment : RcStr ) -> Vc < Self > {
381+ pub fn module ( module : Pattern , path : Pattern , query : RcStr , fragment : RcStr ) -> Vc < Self > {
362382 Self :: cell ( Request :: Module {
363383 module,
364384 path,
@@ -692,7 +712,7 @@ impl Request {
692712 Request :: Relative { path, .. } => path. clone ( ) ,
693713 Request :: Module { module, path, .. } => {
694714 let mut path = path. clone ( ) ;
695- path. push_front ( Pattern :: Constant ( module. clone ( ) ) ) ;
715+ path. push_front ( module. clone ( ) ) ;
696716 path. normalize ( ) ;
697717 path
698718 }
@@ -811,6 +831,64 @@ pub async fn stringify_data_uri(
811831mod tests {
812832 use super :: * ;
813833
834+ #[ test]
835+ fn test_parse_module ( ) {
836+ assert_eq ! (
837+ Request :: Module {
838+ module: rcstr!( "foo" ) . into( ) ,
839+ path: rcstr!( "" ) . into( ) ,
840+ query: rcstr!( "" ) ,
841+ fragment: rcstr!( "" ) ,
842+ } ,
843+ Request :: parse_ref( rcstr!( "foo" ) . into( ) )
844+ ) ;
845+ assert_eq ! (
846+ Request :: Module {
847+ module: rcstr!( "@org/foo" ) . into( ) ,
848+ path: rcstr!( "" ) . into( ) ,
849+ query: rcstr!( "" ) ,
850+ fragment: rcstr!( "" ) ,
851+ } ,
852+ Request :: parse_ref( rcstr!( "@org/foo" ) . into( ) )
853+ ) ;
854+
855+ assert_eq ! (
856+ Request :: Module {
857+ module: Pattern :: Concatenation ( vec![
858+ Pattern :: Constant ( rcstr!( "foo-" ) ) ,
859+ Pattern :: Dynamic ,
860+ ] ) ,
861+ path: Pattern :: Dynamic ,
862+ query: rcstr!( "" ) ,
863+ fragment: rcstr!( "" ) ,
864+ } ,
865+ Request :: parse_ref( Pattern :: Concatenation ( vec![
866+ Pattern :: Constant ( rcstr!( "foo-" ) ) ,
867+ Pattern :: Dynamic ,
868+ ] ) )
869+ ) ;
870+
871+ assert_eq ! (
872+ Request :: Module {
873+ module: Pattern :: Concatenation ( vec![
874+ Pattern :: Constant ( rcstr!( "foo-" ) ) ,
875+ Pattern :: Dynamic ,
876+ ] ) ,
877+ path: Pattern :: Concatenation ( vec![
878+ Pattern :: Dynamic ,
879+ Pattern :: Constant ( rcstr!( "/file" ) ) ,
880+ ] ) ,
881+ query: rcstr!( "" ) ,
882+ fragment: rcstr!( "" ) ,
883+ } ,
884+ Request :: parse_ref( Pattern :: Concatenation ( vec![
885+ Pattern :: Constant ( rcstr!( "foo-" ) ) ,
886+ Pattern :: Dynamic ,
887+ Pattern :: Constant ( rcstr!( "/file" ) ) ,
888+ ] ) )
889+ ) ;
890+ }
891+
814892 #[ test]
815893 fn test_split_query_fragment ( ) {
816894 assert_eq ! (
0 commit comments