fix(es/loader): Fix support for jsc.paths. (#2227)

swc_ecma_loader:
 - `TsConfigResolver`: Use `baseUrl`. (#2050)

swc:
 - Change type of `JscConfig.base_url` to `PathBuf`.

testing:
 - Improve `NormalizedOutput::compare_to_file`.
This commit is contained in:
강동윤 2021-09-10 21:29:26 +09:00 committed by GitHub
parent 9ffe47106a
commit 9eafd0c6c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 130 additions and 48 deletions

6
Cargo.lock generated
View File

@ -2287,7 +2287,7 @@ checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
[[package]]
name = "swc"
version = "0.52.0"
version = "0.53.0"
dependencies = [
"ahash",
"anyhow",
@ -2608,7 +2608,7 @@ dependencies = [
[[package]]
name = "swc_ecma_loader"
version = "0.18.1"
version = "0.18.2"
dependencies = [
"anyhow",
"dashmap",
@ -3161,7 +3161,7 @@ dependencies = [
[[package]]
name = "testing"
version = "0.13.0"
version = "0.13.1"
dependencies = [
"ansi_term 0.12.1",
"difference",

View File

@ -20,7 +20,7 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "swc"
repository = "https://github.com/swc-project/swc.git"
version = "0.52.0"
version = "0.53.0"
[lib]
name = "swc"

View File

@ -6,7 +6,7 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "swc_ecma_loader"
repository = "https://github.com/swc-project/swc.git"
version = "0.18.1"
version = "0.18.2"
[package.metadata.docs.rs]
all-features = true

View File

@ -135,7 +135,7 @@ where
);
let mut errors = vec![];
for target in to {
let replaced = target.replace('*', capture.as_str());
let mut replaced = target.replace('*', capture.as_str());
let rel = format!("./{}", replaced);
let res = self.inner.resolve(base, &rel).with_context(|| {
@ -150,8 +150,15 @@ where
Err(err) => err,
});
if cfg!(target_os = "windows") {
if replaced.starts_with("./") {
replaced = replaced[2..].to_string();
}
replaced = replaced.replace('/', "\\");
}
if to.len() == 1 {
return Ok(FileName::Custom(replaced));
return Ok(FileName::Real(self.base_url.join(replaced)));
}
}

View File

@ -97,7 +97,7 @@ where
let rel_path = match rel_path {
Some(v) => v,
None => return Ok(module_specifier.into()),
None => return Ok(to_specifier(&target.display().to_string())),
};
{

View File

@ -1,4 +1,8 @@
import swc from "../..";
import { dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
it("should respect paths", async () => {
const { code } = await swc.transform(`
@ -13,6 +17,7 @@ it("should respect paths", async () => {
transform: {
},
baseUrl: __dirname,
paths: {
'@src/*': ['bar/*']
}

View File

@ -4,7 +4,7 @@ use crate::{
};
use compat::es2020::export_namespace_from;
use either::Either;
use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc};
use std::{cell::RefCell, collections::HashMap, path::PathBuf, rc::Rc, sync::Arc};
use swc_atoms::JsWord;
use swc_common::{
chain, comments::Comments, errors::Handler, sync::Lrc, util::take::Take, FileName, Mark,
@ -142,7 +142,7 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
/// - fixer if enabled
pub fn finalize<'cmt>(
self,
base_url: String,
base_url: PathBuf,
paths: CompiledPaths,
base: &FileName,
syntax: Syntax,

View File

@ -208,6 +208,7 @@ impl Options {
minify: js_minify,
..
} = config.jsc;
let target = target.unwrap_or_default();
let syntax = syntax.unwrap_or_default();
@ -774,7 +775,7 @@ pub struct JscConfig {
pub keep_class_names: bool,
#[serde(default)]
pub base_url: String,
pub base_url: PathBuf,
#[serde(default)]
pub paths: Paths,
@ -816,7 +817,7 @@ pub enum ModuleConfig {
impl ModuleConfig {
pub fn build(
cm: Arc<SourceMap>,
base_url: String,
base_url: PathBuf,
paths: CompiledPaths,
base: &FileName,
root_mark: Mark,
@ -1224,8 +1225,8 @@ impl Merge for ConstModulesConfig {
}
}
fn build_resolver(base_url: String, paths: CompiledPaths) -> SwcImportResolver {
static CACHE: Lazy<DashMap<(String, CompiledPaths), SwcImportResolver>> =
fn build_resolver(base_url: PathBuf, paths: CompiledPaths) -> SwcImportResolver {
static CACHE: Lazy<DashMap<(PathBuf, CompiledPaths), SwcImportResolver>> =
Lazy::new(|| Default::default());
if let Some(cached) = CACHE.get(&(base_url.clone(), paths.clone())) {

View File

@ -52,6 +52,8 @@ use swc_ecma_visit::{noop_visit_type, FoldWith, Visit, VisitWith};
mod builder;
pub mod config;
pub mod resolver {
use std::path::PathBuf;
use crate::config::CompiledPaths;
use fxhash::FxHashMap;
use swc_ecma_ast::TargetEnv;
@ -64,14 +66,10 @@ pub mod resolver {
pub fn paths_resolver(
target_env: TargetEnv,
alias: FxHashMap<String, String>,
base_url: String,
base_url: PathBuf,
paths: CompiledPaths,
) -> CachingResolver<TsConfigResolver<NodeModulesResolver>> {
let r = TsConfigResolver::new(
NodeModulesResolver::new(target_env, alias),
base_url.clone().into(),
paths.clone(),
);
let r = TsConfigResolver::new(NodeModulesResolver::new(target_env, alias), base_url, paths);
CachingResolver::new(40, r)
}
@ -588,6 +586,35 @@ impl Compiler {
config.merge(&config_file.into_config(Some(path))?)
}
if let Some(c) = &mut config {
if c.jsc.base_url != PathBuf::new() {
let joined = dir.join(&c.jsc.base_url);
c.jsc.base_url = if cfg!(target_os = "windows")
&& c.jsc.base_url.as_os_str() == "."
{
dir.canonicalize().with_context(|| {
format!(
"failed to canonicalize base url using the \
path of .swcrc\nDir: {}\n(Used logic for \
windows)",
dir.display(),
)
})?
} else {
joined.canonicalize().with_context(|| {
format!(
"failed to canonicalize base url using the \
path of .swcrc\nPath: {}\nDir: {}\nbaseUrl: \
{}",
joined.display(),
dir.display(),
c.jsc.base_url.display()
)
})?
};
}
}
return Ok(config);
}

View File

@ -6,7 +6,7 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "testing"
repository = "https://github.com/swc-project/swc.git"
version = "0.13.0"
version = "0.13.1"
[dependencies]
ansi_term = "0.12.1"

View File

@ -2,7 +2,7 @@ use crate::paths;
use pretty_assertions::assert_eq;
use std::{
fmt,
fs::{create_dir_all, remove_file, File},
fs::{create_dir_all, File},
io::Read,
ops::Deref,
path::Path,
@ -79,22 +79,12 @@ impl NormalizedOutput {
String::new()
});
let path_for_actual = paths::test_results_dir().join("ui").join(
path.strip_prefix(&paths::manifest_dir())
.unwrap_or_else(|_| {
unreachable!(
"failed to strip prefix: CARGO_MANIFEST_DIR\nPath: {}\nManifest dir: {}",
path.display(),
paths::manifest_dir().display()
)
}),
);
eprintln!("{}:{}", path.display(), path_for_actual.display());
if self.0 == expected {
let _ = remove_file(path_for_actual);
if expected == self.0 {
return Ok(());
}
create_dir_all(path_for_actual.parent().unwrap()).expect("failed to run `mkdir -p`");
eprintln!("Comparing output to {}", path.display());
create_dir_all(path.parent().unwrap()).expect("failed to run `mkdir -p`");
let diff = Diff {
expected: NormalizedOutput(expected),
@ -106,7 +96,7 @@ impl NormalizedOutput {
eprintln!(
"Assertion failed: \nActual file printed to {}",
path_for_actual.display()
path.display()
);
}

View File

@ -0,0 +1,17 @@
{
"jsc": {
"parser": {
"syntax": "typescript"
},
"target": "es2020",
"baseUrl": ".",
"paths": {
"~/*": [
"./*"
]
}
},
"module": {
"type": "commonjs"
}
}

View File

@ -0,0 +1,4 @@
import A from './subfolder/A'
console.log(A);

View File

@ -0,0 +1,5 @@
import { B } from '~/subfolder/B';
console.log(B);
export const A = 400;

View File

@ -0,0 +1 @@
export const B = 500;

View File

@ -0,0 +1,8 @@
"use strict";
var _a = _interopRequireDefault(require("./subfolder/A"));
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
console.log(_a.default);

View File

@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.A = void 0;
var _b = require("./B");
console.log(_b.B);
const A = 400;
exports.A = A;

View File

@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.B = void 0;
const B = 500;
exports.B = B;

View File

@ -783,15 +783,14 @@ fn should_visit() {
}
#[testing::fixture("tests/fixture/**/input/")]
fn tests(dir: PathBuf) {
let output = dir.parent().unwrap().join("output");
let _ = create_dir_all(&output);
fn tests(input_dir: PathBuf) {
let output = input_dir.parent().unwrap().join("output");
Tester::new()
.print_errors(|cm, handler| {
let c = Compiler::new(cm.clone());
for entry in WalkDir::new(&dir) {
for entry in WalkDir::new(&input_dir) {
let entry = entry.unwrap();
if entry.metadata().unwrap().is_dir() {
continue;
@ -805,6 +804,11 @@ fn tests(dir: PathBuf) {
continue;
}
let rel_path = entry
.path()
.strip_prefix(&input_dir)
.expect("failed to strip prefix");
let fm = cm.load_file(entry.path()).expect("failed to load file");
match c.process_js_file(
fm,
@ -819,9 +823,11 @@ fn tests(dir: PathBuf) {
) {
Ok(v) => {
NormalizedOutput::from(v.code)
.compare_to_file(output.join(entry.file_name()))
.compare_to_file(output.join(rel_path))
.unwrap();
let _ = create_dir_all(output.join(rel_path).parent().unwrap());
let map = v.map.map(|json| {
let json: serde_json::Value = serde_json::from_str(&json).unwrap();
serde_json::to_string_pretty(&json).unwrap()
@ -829,8 +835,7 @@ fn tests(dir: PathBuf) {
NormalizedOutput::from(map.unwrap_or_default())
.compare_to_file(
output
.join(entry.path().with_extension("map").file_name().unwrap()),
output.join(rel_path.with_extension("map").file_name().unwrap()),
)
.unwrap();
}

View File

@ -1,4 +0,0 @@
console.log('--Hello--');
throw new Error('Error here');
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9rZHkxL3Byb2plY3RzL3N3Yy1idWdzL3Rlc3RzL3N0YWNrdHJhY2UvaXNzdWUtMTY4NS9pbnB1dC9pbmRleC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zb2xlLmxvZygnLS1IZWxsby0tJylcblxudGhyb3cgbmV3IEVycm9yKCdFcnJvciBoZXJlJyk7Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sQ0FBQyxHQUFHLEVBQUMsU0FBVztBQUV2QixLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBQyxVQUFZIn0=