Skip to content

Commit

Permalink
fix(es/resolver): Prioritze jsc.paths by length in tsc resolver (#8875
Browse files Browse the repository at this point in the history
)

**Description:**

See #8858 

**BREAKING CHANGE:**
`jsc.paths` are now prioritized differently to align with `tsc`. The order is:
1. Exact matches
2. Wildcard pattern matches, sorted by length of prefix before wildcard


**Related issue:**

 - Closes #8858
  • Loading branch information
yehonatanz committed Apr 19, 2024
1 parent 2e0663b commit e22c368
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
16 changes: 14 additions & 2 deletions crates/swc_ecma_loader/src/resolvers/tsc.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use std::path::{Component, Path, PathBuf};
use std::{
cmp::Ordering,
path::{Component, Path, PathBuf},
};

use anyhow::{bail, Context, Error};
use swc_common::FileName;
Expand Down Expand Up @@ -58,7 +61,7 @@ where
);
}

let paths = paths
let mut paths: Vec<(Pattern, Vec<String>)> = paths
.into_iter()
.map(|(from, to)| {
assert!(
Expand Down Expand Up @@ -92,6 +95,15 @@ where
})
.collect();

paths.sort_by(|(a, _), (b, _)| match (a, b) {
(Pattern::Wildcard { .. }, Pattern::Exact(_)) => Ordering::Greater,
(Pattern::Exact(_), Pattern::Wildcard { .. }) => Ordering::Less,
(Pattern::Exact(_), Pattern::Exact(_)) => Ordering::Equal,
(Pattern::Wildcard { prefix: prefix_a }, Pattern::Wildcard { prefix: prefix_b }) => {
prefix_a.len().cmp(&prefix_b.len()).reverse()
}
});

Self {
inner,
base_url_filename: FileName::Real(base_url.clone()),
Expand Down
35 changes: 35 additions & 0 deletions crates/swc_ecma_loader/tests/tsc_resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,41 @@ fn base_url_precedence() {
}
}

#[test]
fn pattern_length_precedence() {
let mut map = HashMap::default();
map.insert(
"./packages/helpers/src/hello".to_string(),
"good".to_string(),
);

let r = TsConfigResolver::new(
TestResolver(map),
".".into(),
vec![
("@app/*".into(), vec!["./packages/*/src".into()]),
(
"@app/helpers/*".into(),
vec!["./packages/helpers/src/*".into()],
),
],
);

{
let resolved = r
.resolve(&FileName::Anon, "@app/helpers/hello")
.expect("should resolve @app/helpers/hello");

assert_eq!(
resolved,
Resolution {
filename: FileName::Custom("good".into()),
slug: None
}
);
}
}

struct TestResolver(AHashMap<String, String>);

impl Resolve for TestResolver {
Expand Down

0 comments on commit e22c368

Please sign in to comment.