Skip to content

Commit 87b9b9d

Browse files
committed
Fix
1 parent 5631158 commit 87b9b9d

File tree

6 files changed

+224
-129
lines changed

6 files changed

+224
-129
lines changed

crates/next-core/src/next_server/resolve.rs

Lines changed: 24 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -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.\nPackages that should be external need to be installed in the \
275-
project directory, so they can be resolved from the output files.\nTry 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}).\nMake 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
}

crates/next-core/src/next_shared/resolve.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ impl AfterResolvePlugin for NextExternalResolvePlugin {
254254
name: specifier.clone(),
255255
ty: ExternalType::CommonJs,
256256
traced: ExternalTraced::Traced,
257+
target: None,
257258
},
258259
))))
259260
}

turbopack/crates/turbopack-core/src/resolve/mod.rs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ pub enum ResolveResultItem {
414414
name: RcStr,
415415
ty: ExternalType,
416416
traced: ExternalTraced,
417+
target: Option<FileSystemPath>,
417418
},
418419
Ignore,
419420
Error(ResolvedVc<RcStr>),
@@ -494,10 +495,19 @@ impl ValueToString for ResolveResult {
494495
name: s,
495496
ty,
496497
traced,
498+
target,
497499
} => {
498500
result.push_str("external ");
499501
result.push_str(s);
500-
write!(result, " ({ty}, {traced})")?;
502+
write!(
503+
result,
504+
" ({ty}, {traced}, {:?})",
505+
if let Some(target) = target {
506+
Some(target.value_to_string().await?)
507+
} else {
508+
None
509+
}
510+
)?;
501511
}
502512
ResolveResultItem::Ignore => {
503513
result.push_str("ignore");
@@ -626,8 +636,13 @@ impl ResolveResult {
626636
request,
627637
match item {
628638
ResolveResultItem::Source(source) => asset_fn(source).await?,
629-
ResolveResultItem::External { name, ty, traced } => {
630-
if traced == ExternalTraced::Traced {
639+
ResolveResultItem::External {
640+
name,
641+
ty,
642+
traced,
643+
target,
644+
} => {
645+
if traced == ExternalTraced::Traced || target.is_some() {
631646
// Should use map_primary_items instead
632647
bail!("map_module doesn't handle traced externals");
633648
}
@@ -1979,6 +1994,7 @@ async fn resolve_internal_inline(
19791994
name: uri,
19801995
ty: ExternalType::Url,
19811996
traced: ExternalTraced::Untraced,
1997+
target: None,
19821998
},
19831999
)
19842000
}
@@ -1996,6 +2012,7 @@ async fn resolve_internal_inline(
19962012
name: uri,
19972013
ty: ExternalType::Url,
19982014
traced: ExternalTraced::Untraced,
2015+
target: None,
19992016
},
20002017
)
20012018
}
@@ -2721,13 +2738,17 @@ async fn resolve_import_map_result(
27212738
))
27222739
}
27232740
}
2724-
ImportMapResult::External { name, ty, traced } => {
2725-
Some(*ResolveResult::primary(ResolveResultItem::External {
2726-
name: name.clone(),
2727-
ty: *ty,
2728-
traced: *traced,
2729-
}))
2730-
}
2741+
ImportMapResult::External {
2742+
name,
2743+
ty,
2744+
traced,
2745+
target,
2746+
} => Some(*ResolveResult::primary(ResolveResultItem::External {
2747+
name: name.clone(),
2748+
ty: *ty,
2749+
traced: *traced,
2750+
target: target.clone(),
2751+
})),
27312752
ImportMapResult::AliasExternal {
27322753
name,
27332754
ty,
@@ -2763,6 +2784,7 @@ async fn resolve_import_map_result(
27632784
name: name.clone(),
27642785
ty: *ty,
27652786
traced: *traced,
2787+
target: None,
27662788
}))
27672789
} else {
27682790
None

turbopack/crates/turbopack-core/src/resolve/options.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ pub enum ReplacedImportMapping {
138138
name_override: Option<RcStr>,
139139
ty: ExternalType,
140140
traced: ExternalTraced,
141+
target: Option<FileSystemPath>,
141142
},
142143
PrimaryAlternativeExternal {
143144
name: Option<RcStr>,
@@ -198,6 +199,8 @@ impl AliasTemplate for Vc<ImportMapping> {
198199
name_override: name.clone(),
199200
ty: *ty,
200201
traced: *traced,
202+
// TODO
203+
target: None,
201204
},
202205
ImportMapping::PrimaryAlternativeExternal {
203206
name,
@@ -246,12 +249,14 @@ impl AliasTemplate for Vc<ImportMapping> {
246249
.cloned(),
247250
ty: *ty,
248251
traced: *traced,
252+
target: None,
249253
}
250254
} else {
251255
ReplacedImportMapping::External {
252256
name_override: None,
253257
ty: *ty,
254258
traced: *traced,
259+
target: None,
255260
}
256261
}
257262
}
@@ -410,6 +415,7 @@ pub enum ImportMapResult {
410415
name: RcStr,
411416
ty: ExternalType,
412417
traced: ExternalTraced,
418+
target: Option<FileSystemPath>,
413419
},
414420
AliasExternal {
415421
name: RcStr,
@@ -433,6 +439,7 @@ async fn import_mapping_to_result(
433439
name_override,
434440
ty,
435441
traced,
442+
target,
436443
} => ImportMapResult::External {
437444
name: if let Some(name) = name_override {
438445
name.clone()
@@ -446,6 +453,7 @@ async fn import_mapping_to_result(
446453
},
447454
ty: *ty,
448455
traced: *traced,
456+
target: target.clone(),
449457
},
450458
ReplacedImportMapping::PrimaryAlternativeExternal {
451459
name,

0 commit comments

Comments
 (0)