From e22c3681a6705f2184f0af7032ed30103ab9bfcc Mon Sep 17 00:00:00 2001 From: yehonatanz Date: Fri, 19 Apr 2024 16:38:19 +0300 Subject: [PATCH] fix(es/resolver): Prioritze `jsc.paths` by length in tsc resolver (#8875) **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 --- crates/swc_ecma_loader/src/resolvers/tsc.rs | 16 +++++++-- crates/swc_ecma_loader/tests/tsc_resolver.rs | 35 ++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/crates/swc_ecma_loader/src/resolvers/tsc.rs b/crates/swc_ecma_loader/src/resolvers/tsc.rs index 293b7e578fd7..844686d8581c 100644 --- a/crates/swc_ecma_loader/src/resolvers/tsc.rs +++ b/crates/swc_ecma_loader/src/resolvers/tsc.rs @@ -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; @@ -58,7 +61,7 @@ where ); } - let paths = paths + let mut paths: Vec<(Pattern, Vec)> = paths .into_iter() .map(|(from, to)| { assert!( @@ -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()), diff --git a/crates/swc_ecma_loader/tests/tsc_resolver.rs b/crates/swc_ecma_loader/tests/tsc_resolver.rs index b806707ce1f8..583486b576cf 100644 --- a/crates/swc_ecma_loader/tests/tsc_resolver.rs +++ b/crates/swc_ecma_loader/tests/tsc_resolver.rs @@ -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); impl Resolve for TestResolver {