mirror of
https://github.com/swc-project/swc.git
synced 2024-10-04 04:07:18 +03:00
fix(es/module): Read link if an import is resolved as symlink (#8297)
**Related issue:** - Closes #8265
This commit is contained in:
parent
38c489c26c
commit
7dfdc12218
162
Cargo.lock
generated
162
Cargo.lock
generated
@ -173,6 +173,36 @@ version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||
|
||||
[[package]]
|
||||
name = "assert_cmd"
|
||||
version = "2.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88903cb14723e4d4003335bb7f8a14f27691649105346a0f0957466c096adfe6"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"bstr",
|
||||
"doc-comment",
|
||||
"predicates",
|
||||
"predicates-core",
|
||||
"predicates-tree",
|
||||
"wait-timeout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "assert_fs"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f070617a68e5c2ed5d06ee8dd620ee18fb72b99f6c094bed34cf8ab07c875b48"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"doc-comment",
|
||||
"globwalk",
|
||||
"predicates",
|
||||
"predicates-core",
|
||||
"predicates-tree",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ast_node"
|
||||
version = "0.9.5"
|
||||
@ -358,7 +388,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
"either",
|
||||
"itertools",
|
||||
"itertools 0.10.5",
|
||||
"nom",
|
||||
"once_cell",
|
||||
"quote",
|
||||
@ -369,6 +399,17 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"regex-automata 0.4.3",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.13.0"
|
||||
@ -849,7 +890,7 @@ dependencies = [
|
||||
"clap 4.4.6",
|
||||
"criterion-plot",
|
||||
"is-terminal",
|
||||
"itertools",
|
||||
"itertools 0.10.5",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"oorandom",
|
||||
@ -870,7 +911,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
|
||||
dependencies = [
|
||||
"cast",
|
||||
"itertools",
|
||||
"itertools 0.10.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1124,6 +1165,12 @@ version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
|
||||
|
||||
[[package]]
|
||||
name = "difflib"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
@ -1161,6 +1208,12 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
||||
|
||||
[[package]]
|
||||
name = "doc-comment"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.1"
|
||||
@ -1515,6 +1568,30 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"bstr",
|
||||
"fnv",
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "globwalk"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"ignore",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.18"
|
||||
@ -1767,6 +1844,23 @@ version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
|
||||
|
||||
[[package]]
|
||||
name = "ignore"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492"
|
||||
dependencies = [
|
||||
"globset",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"memchr",
|
||||
"regex",
|
||||
"same-file",
|
||||
"thread_local",
|
||||
"walkdir",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
@ -1855,6 +1949,15 @@ dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.6"
|
||||
@ -2080,7 +2183,7 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||
dependencies = [
|
||||
"regex-automata",
|
||||
"regex-automata 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2752,6 +2855,34 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
|
||||
[[package]]
|
||||
name = "predicates"
|
||||
version = "3.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6dfc28575c2e3f19cb3c73b93af36460ae898d426eba6fc15b9bd2a5220758a0"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"difflib",
|
||||
"itertools 0.11.0",
|
||||
"predicates-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "predicates-core"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174"
|
||||
|
||||
[[package]]
|
||||
name = "predicates-tree"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf"
|
||||
dependencies = [
|
||||
"predicates-core",
|
||||
"termtree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "preset_env_base"
|
||||
version = "0.4.8"
|
||||
@ -3012,6 +3143,12 @@ dependencies = [
|
||||
"regex-syntax 0.6.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.29"
|
||||
@ -3823,6 +3960,8 @@ name = "swc_cli_impl"
|
||||
version = "0.4.71"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"assert_cmd",
|
||||
"assert_fs",
|
||||
"atty",
|
||||
"clap 3.2.25",
|
||||
"glob",
|
||||
@ -5454,6 +5593,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termtree"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
|
||||
|
||||
[[package]]
|
||||
name = "testing"
|
||||
version = "0.35.11"
|
||||
@ -6124,6 +6269,15 @@ dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wait-timeout"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "waker-fn"
|
||||
version = "1.1.0"
|
||||
|
17
crates/swc/tests/fixture/issues-8xxx/8265/1/input/.swcrc
Normal file
17
crates/swc/tests/fixture/issues-8xxx/8265/1/input/.swcrc
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"jsc": {
|
||||
"parser": {
|
||||
"syntax": "typescript"
|
||||
},
|
||||
"target": "es2021",
|
||||
"baseUrl": "./src",
|
||||
"paths": {
|
||||
"@modules/*": [
|
||||
"./modules/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"module": {
|
||||
"type": "commonjs"
|
||||
},
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
import { moduleA } from "@modules/moduleA";
|
||||
|
||||
moduleA();
|
@ -0,0 +1,6 @@
|
||||
import { moduleB } from "@modules/moduleB";
|
||||
|
||||
export const moduleA = () => {
|
||||
console.log("This is module A");
|
||||
moduleB();
|
||||
};
|
@ -0,0 +1 @@
|
||||
export const moduleB = () => console.log("This is module B!");
|
@ -0,0 +1,6 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
const _moduleA = require("./modules/moduleA");
|
||||
(0, _moduleA.moduleA)();
|
@ -0,0 +1,15 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "moduleA", {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return moduleA;
|
||||
}
|
||||
});
|
||||
const _moduleB = require("../moduleB");
|
||||
const moduleA = ()=>{
|
||||
console.log("This is module A");
|
||||
(0, _moduleB.moduleB)();
|
||||
};
|
@ -0,0 +1,11 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "moduleB", {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return moduleB;
|
||||
}
|
||||
});
|
||||
const moduleB = ()=>console.log("This is module B!");
|
@ -8,11 +8,19 @@ name = "swc_cli_impl"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.4.71"
|
||||
|
||||
[[bin]]
|
||||
name = "swc"
|
||||
path = "src/main.rs"
|
||||
|
||||
[lib]
|
||||
crate-type = ["rlib"]
|
||||
path = "src/lib.rs"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
plugin = [
|
||||
"swc_core/plugin_transform_host_native",
|
||||
"swc_core/plugin_transform_host_native_filesystem_cache",
|
||||
"swc_core/plugin_transform_host_native",
|
||||
"swc_core/plugin_transform_host_native_filesystem_cache",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
@ -37,3 +45,7 @@ swc_core = { version = "0.86.71", features = [
|
||||
"common_concurrent",
|
||||
"base_concurrent",
|
||||
], path = "../swc_core" }
|
||||
|
||||
[dev-dependencies]
|
||||
assert_cmd = "2.0.12"
|
||||
assert_fs = "1.0.13"
|
||||
|
5
crates/swc_cli_impl/src/main.rs
Normal file
5
crates/swc_cli_impl/src/main.rs
Normal file
@ -0,0 +1,5 @@
|
||||
//! Used for testing
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
swc_cli_impl::run()
|
||||
}
|
18
crates/swc_cli_impl/tests/fixture-manual/8265/.swcrc
Normal file
18
crates/swc_cli_impl/tests/fixture-manual/8265/.swcrc
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"jsc": {
|
||||
"parser": {
|
||||
"syntax": "typescript"
|
||||
},
|
||||
"target": "es2021",
|
||||
"baseUrl": "./src",
|
||||
"paths": {
|
||||
"@modules/*": [
|
||||
"./modules/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"module": {
|
||||
"type": "commonjs"
|
||||
},
|
||||
"sourceMaps": true
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
import { moduleA } from "@modules/moduleA";
|
||||
|
||||
moduleA();
|
@ -0,0 +1,6 @@
|
||||
import { moduleB } from "@modules/moduleB";
|
||||
|
||||
export const moduleA = () => {
|
||||
console.log("This is module A");
|
||||
moduleB();
|
||||
};
|
@ -0,0 +1 @@
|
||||
export const moduleB = () => console.log("This is module B!");
|
78
crates/swc_cli_impl/tests/issues.rs
Normal file
78
crates/swc_cli_impl/tests/issues.rs
Normal file
@ -0,0 +1,78 @@
|
||||
use std::{
|
||||
fs::{self, create_dir_all},
|
||||
path::Path,
|
||||
process::{Command, Stdio},
|
||||
};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use assert_cmd::prelude::*;
|
||||
use assert_fs::TempDir;
|
||||
|
||||
fn cli() -> Result<Command> {
|
||||
let mut cmd = Command::cargo_bin("swc").context("Failed to get swc binary")?;
|
||||
cmd.stderr(Stdio::inherit());
|
||||
Ok(cmd)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_8265_1() -> Result<()> {
|
||||
let pwd = Path::new("tests/fixture-manual/8265").canonicalize()?;
|
||||
let tmp = TempDir::new()?;
|
||||
|
||||
create_dir_all(tmp.path().join("src/modules/moduleA"))?;
|
||||
create_dir_all(tmp.path().join("src/modules/moduleB"))?;
|
||||
|
||||
symlink(&pwd.join(".swcrc"), &tmp.path().join(".swcrc"));
|
||||
symlink(&pwd.join("src/index.ts"), &tmp.path().join("src/index.ts"));
|
||||
symlink(
|
||||
&pwd.join("src/modules/moduleA/index.ts"),
|
||||
&tmp.path().join("src/modules/moduleA/index.ts"),
|
||||
);
|
||||
symlink(
|
||||
&pwd.join("src/modules/moduleB/index.ts"),
|
||||
&tmp.path().join("src/modules/moduleB/index.ts"),
|
||||
);
|
||||
|
||||
print_ls_alr(&tmp);
|
||||
|
||||
let mut cmd = cli()?;
|
||||
cmd.current_dir(&tmp)
|
||||
.arg("compile")
|
||||
.arg("--source-maps")
|
||||
.arg("false")
|
||||
.arg("--config-file")
|
||||
.arg(".swcrc")
|
||||
.arg("--out-file")
|
||||
.arg("src/index.js")
|
||||
.arg("src/index.ts");
|
||||
|
||||
cmd.assert().success();
|
||||
|
||||
let content = fs::read_to_string(tmp.join("src/index.js"))?;
|
||||
assert!(
|
||||
content.contains("require(\"./modules/moduleA\")"),
|
||||
"{}",
|
||||
content
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// ln -s $a $b
|
||||
fn symlink(a: &Path, b: &Path) {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
std::os::unix::fs::symlink(a, b).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
std::os::windows::fs::symlink_file(a, b).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn print_ls_alr(path: &Path) {
|
||||
let mut cmd = Command::new("ls");
|
||||
cmd.arg("-alR").arg(path);
|
||||
cmd.status().unwrap();
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
env::current_dir,
|
||||
fs::read_link,
|
||||
io,
|
||||
path::{Component, Path, PathBuf},
|
||||
sync::Arc,
|
||||
@ -212,7 +213,7 @@ where
|
||||
let orig_filename = module_specifier.split('/').last();
|
||||
|
||||
let target = self.resolver.resolve(base, module_specifier);
|
||||
let target = match target {
|
||||
let mut target = match target {
|
||||
Ok(v) => v,
|
||||
Err(err) => {
|
||||
warn!("import rewriter: failed to resolve: {}", err);
|
||||
@ -220,6 +221,15 @@ where
|
||||
}
|
||||
};
|
||||
|
||||
// Bazel uses symlink
|
||||
//
|
||||
// https://github.com/swc-project/swc/issues/8265
|
||||
if let FileName::Real(resolved) = &target {
|
||||
if let Ok(orig) = read_link(resolved) {
|
||||
target = FileName::Real(orig);
|
||||
}
|
||||
}
|
||||
|
||||
info!("Resolved to {}", target);
|
||||
|
||||
let mut target = match target {
|
||||
|
Loading…
Reference in New Issue
Block a user