diff --git a/Cargo.lock b/Cargo.lock
index 54354a0faf8..bf16bb5e0d5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3639,6 +3639,7 @@ dependencies = [
"ahash",
"anyhow",
"indexmap",
+ "path-clean",
"pathdiff",
"serde",
"serde_json",
diff --git a/crates/swc_ecma_transforms_module/Cargo.toml b/crates/swc_ecma_transforms_module/Cargo.toml
index 45766898872..100f1aa4840 100644
--- a/crates/swc_ecma_transforms_module/Cargo.toml
+++ b/crates/swc_ecma_transforms_module/Cargo.toml
@@ -17,6 +17,7 @@ Inflector = "0.11.4"
ahash = "0.7.4"
anyhow = "1.0.41"
indexmap = "1.8.0"
+path-clean = "0.1.0"
pathdiff = "0.2.0"
serde = { version = "1.0.118", features = ["derive"] }
swc_atoms = { version = "0.2", path = "../swc_atoms" }
diff --git a/crates/swc_ecma_transforms_module/src/path.rs b/crates/swc_ecma_transforms_module/src/path.rs
index 5fb6ba496ae..9c0b323efb2 100644
--- a/crates/swc_ecma_transforms_module/src/path.rs
+++ b/crates/swc_ecma_transforms_module/src/path.rs
@@ -1,11 +1,13 @@
use std::{
borrow::Cow,
env::current_dir,
- path::{Component, PathBuf},
+ io,
+ path::{Component, Path, PathBuf},
sync::Arc,
};
use anyhow::{Context, Error};
+use path_clean::PathClean;
use pathdiff::diff_paths;
use swc_atoms::JsWord;
use swc_common::{FileName, Mark, Span, DUMMY_SP};
@@ -183,7 +185,7 @@ where
}
};
- let target = match target {
+ let mut target = match target {
FileName::Real(v) => v,
FileName::Custom(s) => return Ok(to_specifier(&s, None, orig_ext)),
_ => {
@@ -193,7 +195,7 @@ where
)
}
};
- let base = match base {
+ let mut base = match base {
FileName::Real(v) => Cow::Borrowed(v),
FileName::Anon => {
if cfg!(target_arch = "wasm32") {
@@ -212,6 +214,11 @@ where
let is_file = target.is_file();
+ if base.is_absolute() != target.is_absolute() {
+ base = Cow::Owned(absolute_path(&base)?);
+ target = absolute_path(&target)?;
+ }
+
let rel_path = diff_paths(
&target,
match base.parent() {
@@ -279,3 +286,14 @@ macro_rules! impl_ref {
impl_ref!(P, &'_ P);
impl_ref!(P, Box
);
impl_ref!(P, Arc
);
+
+fn absolute_path(path: &Path) -> io::Result {
+ let absolute_path = if path.is_absolute() {
+ path.to_path_buf()
+ } else {
+ std::env::current_dir()?.join(path)
+ }
+ .clean();
+
+ Ok(absolute_path)
+}
diff --git a/crates/swc_ecma_transforms_module/tests/fixture-manual/issue-4730/output/index.js b/crates/swc_ecma_transforms_module/tests/fixture-manual/issue-4730/output/index.js
index 00a8246f403..ec142a77c1d 100644
--- a/crates/swc_ecma_transforms_module/tests/fixture-manual/issue-4730/output/index.js
+++ b/crates/swc_ecma_transforms_module/tests/fixture-manual/issue-4730/output/index.js
@@ -1,6 +1,6 @@
-import { displayB } from "$DIR/tests/fixture-manual/issue-4730/input/packages/b/src/index";
+import { displayB } from "../packages/b/src/index";
async function display() {
- const displayA = await import("$DIR/tests/fixture-manual/issue-4730/input/packages/a/src/index").then((c)=>c.displayA);
+ const displayA = await import("../packages/a/src/index").then((c)=>c.displayA);
console.log(displayA());
console.log(displayB());
}
diff --git a/crates/swc_ecma_transforms_module/tests/path_node.rs b/crates/swc_ecma_transforms_module/tests/path_node.rs
index 65693ffe5cb..e6eee26a3d1 100644
--- a/crates/swc_ecma_transforms_module/tests/path_node.rs
+++ b/crates/swc_ecma_transforms_module/tests/path_node.rs
@@ -4,8 +4,7 @@ use std::{
};
use indexmap::IndexMap;
-use swc_common::{chain, FileName};
-use swc_ecma_ast::*;
+use swc_common::FileName;
use swc_ecma_loader::resolvers::{node::NodeModulesResolver, tsc::TsConfigResolver};
use swc_ecma_parser::Syntax;
use swc_ecma_transforms_module::{
@@ -13,7 +12,6 @@ use swc_ecma_transforms_module::{
rewriter::import_rewriter,
};
use swc_ecma_transforms_testing::test_fixture;
-use swc_ecma_visit::{as_folder, VisitMut, VisitMutWith};
use testing::run_test2;
type TestProvider = NodeImportResolver;
@@ -36,34 +34,6 @@ fn node_modules() {
.unwrap();
}
-struct Normalizer;
-
-impl VisitMut for Normalizer {
- fn visit_mut_import_decl(&mut self, i: &mut ImportDecl) {
- if cfg!(target_os = "windows") {
- let path = Path::new(&*i.src.value).with_extension("ts");
- if path.is_file() {
- let p = path.canonicalize().unwrap().with_extension("");
- i.src.value = p.display().to_string().into()
- }
- }
- }
-
- fn visit_mut_call_expr(&mut self, i: &mut CallExpr) {
- i.visit_mut_children_with(self);
-
- if let Callee::Import(..) = i.callee {
- if let Expr::Lit(Lit::Str(s)) = &mut *i.args[0].expr {
- let path = Path::new(&*s.value).with_extension("ts");
- if path.is_file() {
- let p = path.canonicalize().unwrap().with_extension("");
- s.value = p.display().to_string().into()
- }
- }
- }
- }
-}
-
#[test]
fn issue_4730() {
let dir = Path::new("tests/fixture-manual/issue-4730");
@@ -109,12 +79,9 @@ fn issue_4730() {
let resolver = paths_resolver(&input_dir, rules);
- chain!(
- import_rewriter(
- FileName::Real(input_dir.join("src").join("index.js")),
- resolver,
- ),
- as_folder(Normalizer)
+ import_rewriter(
+ FileName::Real(input_dir.join("src").join("index.js")),
+ resolver,
)
},
&input_dir.join("src").join("index.js"),