@@ -259,104 +259,9 @@ impl AfterResolvePlugin for ExternalCjsModulesResolvePlugin {
259259 } ;
260260 break result_from_original_location;
261261 } ;
262- let node_resolved = resolve (
263- self . project_path . clone ( ) ,
264- reference_type. clone ( ) ,
265- request,
266- node_resolve_options,
267- ) ;
268-
269- let Some ( result) = * node_resolved. first_source ( ) . await ? else {
270- // this can't resolve with node.js from the project directory, so bundle it
271- return unable_to_externalize ( vec ! [
272- StyledString :: Text (
273- "The request could not be resolved by Node.js from the project \
274- directory.\n Packages that should be external need to be installed in the \
275- project directory, so they can be resolved from the output files.\n Try to \
276- install it into the project directory by running "
277- . into( ) ,
278- ) ,
279- StyledString :: Code ( format!( "npm install {package}" ) . into( ) ) ,
280- StyledString :: Text ( rcstr!( " from the project directory." ) ) ,
281- ] ) ;
282- } ;
283262
284- if result_from_original_location != result {
285- let package_json_file =
286- find_context_file ( result. ident ( ) . path ( ) . await ?. parent ( ) , package_json ( ) , false ) ;
287- let package_json_from_original_location = find_context_file (
288- result_from_original_location. ident ( ) . path ( ) . await ?. parent ( ) ,
289- package_json ( ) ,
290- false ,
291- ) ;
292- let FindContextFileResult :: Found ( package_json_file, _) = & * package_json_file. await ?
293- else {
294- return unable_to_externalize ( vec ! [ StyledString :: Text (
295- "The package.json of the package resolved from the project directory can't be \
296- found."
297- . into( ) ,
298- ) ] ) ;
299- } ;
300- let FindContextFileResult :: Found ( package_json_from_original_location, _) =
301- & * package_json_from_original_location. await ?
302- else {
303- return unable_to_externalize ( vec ! [ StyledString :: Text ( rcstr!(
304- "The package.json of the package can't be found."
305- ) ) ] ) ;
306- } ;
307- let FileJsonContent :: Content ( package_json_file) =
308- & * package_json_file. read_json ( ) . await ?
309- else {
310- return unable_to_externalize ( vec ! [ StyledString :: Text (
311- "The package.json of the package resolved from project directory can't be \
312- parsed."
313- . into( ) ,
314- ) ] ) ;
315- } ;
316- let FileJsonContent :: Content ( package_json_from_original_location) =
317- & * package_json_from_original_location. read_json ( ) . await ?
318- else {
319- return unable_to_externalize ( vec ! [ StyledString :: Text ( rcstr!(
320- "The package.json of the package can't be parsed."
321- ) ) ] ) ;
322- } ;
323- let ( Some ( name) , Some ( version) ) = (
324- package_json_file. get ( "name" ) . and_then ( |v| v. as_str ( ) ) ,
325- package_json_file. get ( "version" ) . and_then ( |v| v. as_str ( ) ) ,
326- ) else {
327- return unable_to_externalize ( vec ! [ StyledString :: Text ( rcstr!(
328- "The package.json of the package has no name or version."
329- ) ) ] ) ;
330- } ;
331- let ( Some ( name2) , Some ( version2) ) = (
332- package_json_from_original_location
333- . get ( "name" )
334- . and_then ( |v| v. as_str ( ) ) ,
335- package_json_from_original_location
336- . get ( "version" )
337- . and_then ( |v| v. as_str ( ) ) ,
338- ) else {
339- return unable_to_externalize ( vec ! [ StyledString :: Text (
340- "The package.json of the package resolved from project directory has no name \
341- or version."
342- . into( ) ,
343- ) ] ) ;
344- } ;
345- if ( name, version) != ( name2, version2) {
346- // this can't resolve with node.js from the original location, so bundle it
347- return unable_to_externalize ( vec ! [ StyledString :: Text (
348- format!(
349- "The package resolves to a different version when requested from the \
350- project directory ({version}) compared to the package requested from the \
351- importing module ({version2}).\n Make sure to install the same version of \
352- the package in both locations."
353- )
354- . into( ) ,
355- ) ] ) ;
356- }
357- }
358- let path = result. ident ( ) . path ( ) . owned ( ) . await ?;
359- let file_type = get_file_type ( path. clone ( ) , & path) . await ?;
263+ let path = result_from_original_location. ident ( ) . path ( ) . await ?;
264+ let file_type = get_file_type ( ( * path) . clone ( ) , & path) . await ?;
360265
361266 let external_type = match ( file_type, is_esm) {
362267 ( FileType :: UnsupportedExtension , _) => {
@@ -375,7 +280,8 @@ impl AfterResolvePlugin for ExternalCjsModulesResolvePlugin {
375280 ( FileType :: CommonJs , false ) => ExternalType :: CommonJs ,
376281 ( FileType :: CommonJs , true ) => {
377282 // It would be more efficient to use an CJS external instead of an ESM external,
378- // but we need to verify if that would be correct (as in resolves to the same file).
283+ // but we need to verify if that would be correct (as in resolves to the same
284+ // file).
379285 let node_resolve_options =
380286 node_cjs_resolve_options ( lookup_path. root ( ) . owned ( ) . await ?) ;
381287 let node_resolved = resolve (
@@ -386,7 +292,7 @@ impl AfterResolvePlugin for ExternalCjsModulesResolvePlugin {
386292 ) ;
387293 let resolves_equal = if let Some ( result) = * node_resolved. first_source ( ) . await ? {
388294 let cjs_path = result. ident ( ) . path ( ) . owned ( ) . await ?;
389- cjs_path == path
295+ cjs_path == * path
390296 } else {
391297 false
392298 } ;
@@ -407,7 +313,8 @@ impl AfterResolvePlugin for ExternalCjsModulesResolvePlugin {
407313 // ecmascript with esm is always external
408314 ( FileType :: EcmaScriptModule , true ) => ExternalType :: EcmaScriptModule ,
409315 ( FileType :: EcmaScriptModule , false ) => {
410- // even with require() this resolves to a ESM, which would break node.js, bundle it
316+ // even with require() this resolves to a ESM, which would break node.js, bundle
317+ // it
411318 return unable_to_externalize ( vec ! [ StyledString :: Text (
412319 "The package seems invalid. require() resolves to a EcmaScript module, which \
413320 would result in an error in Node.js."
@@ -416,11 +323,28 @@ impl AfterResolvePlugin for ExternalCjsModulesResolvePlugin {
416323 }
417324 } ;
418325
326+ let mut target = result_from_original_location. ident ( ) . path ( ) . owned ( ) . await ?;
327+ loop {
328+ let parent = target. parent ( ) ;
329+ if parent. is_root ( ) {
330+ break ;
331+ }
332+ if parent. file_name ( ) == "node_modules" {
333+ break ;
334+ }
335+ if parent. file_name ( ) . starts_with ( "@" ) && parent. parent ( ) . file_name ( ) == "node_modules"
336+ {
337+ break ;
338+ }
339+ target = parent;
340+ }
341+
419342 Ok ( ResolveResultOption :: some ( * ResolveResult :: primary (
420343 ResolveResultItem :: External {
421344 name : request_str. into ( ) ,
422345 ty : external_type,
423346 traced : ExternalTraced :: Traced ,
347+ target : Some ( target) ,
424348 } ,
425349 ) ) )
426350 }
0 commit comments