From 75bb8586cc7fa8ca08a9b8cf5db6c66eb5de9e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Tue, 24 May 2022 20:00:26 +0900 Subject: [PATCH] fix(es/modules): Adjust absolute path while rewriting imports (#4776) --- Cargo.lock | 1 + crates/swc_ecma_transforms_module/Cargo.toml | 1 + crates/swc_ecma_transforms_module/src/path.rs | 24 +++++++++-- .../fixture-manual/issue-4730/output/index.js | 4 +- .../tests/path_node.rs | 41 ++----------------- 5 files changed, 29 insertions(+), 42 deletions(-) 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"),