fix(es/modules): Support jsc.baseUrl without jsc.paths (#7302)

**Related issue:**

 - Closes #1324.
This commit is contained in:
Donny/강동윤 2023-04-20 16:33:29 +09:00 committed by GitHub
parent 9816ba2795
commit 9c279b802b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 136 additions and 61 deletions

View File

@ -1438,10 +1438,11 @@ impl ModuleConfig {
}
_ => base.clone(),
};
let skip_resolver = base_url.as_os_str().is_empty() && paths.is_empty();
match config {
None | Some(ModuleConfig::Es6) | Some(ModuleConfig::NodeNext) => {
if paths.is_empty() {
if skip_resolver {
Box::new(noop())
} else {
let resolver = build_resolver(base_url, paths);
@ -1450,7 +1451,7 @@ impl ModuleConfig {
}
}
Some(ModuleConfig::CommonJs(config)) => {
if paths.is_empty() {
if skip_resolver {
Box::new(modules::common_js::common_js(
unresolved_mark,
config,
@ -1470,7 +1471,7 @@ impl ModuleConfig {
}
}
Some(ModuleConfig::Umd(config)) => {
if paths.is_empty() {
if skip_resolver {
Box::new(modules::umd::umd(
cm,
unresolved_mark,
@ -1493,7 +1494,7 @@ impl ModuleConfig {
}
}
Some(ModuleConfig::Amd(config)) => {
if paths.is_empty() {
if skip_resolver {
Box::new(modules::amd::amd(
unresolved_mark,
config,
@ -1514,7 +1515,7 @@ impl ModuleConfig {
}
}
Some(ModuleConfig::SystemJs(config)) => {
if paths.is_empty() {
if skip_resolver {
Box::new(modules::system_js::system_js(unresolved_mark, config))
} else {
let resolver = build_resolver(base_url, paths);

View File

@ -474,7 +474,7 @@ impl Resolve for NodeModulesResolver {
} else {
self.resolve_node_modules(base_dir, target)
.and_then(|path| {
let file_path = path.context("Impossible to get the node_modules path");
let file_path = path.context("failed to get the node_modules path");
let current_directory = current_dir()?;
let relative_path = diff_paths(file_path?, current_directory);
self.wrap(relative_path)

View File

@ -25,6 +25,7 @@ where
{
inner: R,
base_url: PathBuf,
base_url_filename: FileName,
paths: Vec<(Pattern, Vec<String>)>,
}
@ -93,6 +94,7 @@ where
Self {
inner,
base_url_filename: FileName::Real(base_url.clone()),
base_url,
paths,
}
@ -103,7 +105,7 @@ impl<R> Resolve for TsConfigResolver<R>
where
R: Resolve,
{
fn resolve(&self, base: &FileName, src: &str) -> Result<FileName, Error> {
fn resolve(&self, base: &FileName, module_specifier: &str) -> Result<FileName, Error> {
let _tracing = if cfg!(debug_assertions) {
Some(
tracing::span!(
@ -111,7 +113,7 @@ where
"tsc.resolve",
base_url = tracing::field::display(self.base_url.display()),
base = tracing::field::display(base),
src = tracing::field::display(src),
src = tracing::field::display(module_specifier),
)
.entered(),
)
@ -119,11 +121,14 @@ where
None
};
if src.starts_with('.') && (src == ".." || src.starts_with("./") || src.starts_with("../"))
if module_specifier.starts_with('.')
&& (module_specifier == ".."
|| module_specifier.starts_with("./")
|| module_specifier.starts_with("../"))
{
return self
.inner
.resolve(base, src)
.resolve(base, module_specifier)
.context("not processed by tsc resolver because it's relative import");
}
@ -136,7 +141,7 @@ where
Component::Normal(v) => v == "node_modules",
_ => false,
}) {
return self.inner.resolve(base, src).context(
return self.inner.resolve(base, module_specifier).context(
"not processed by tsc resolver because base module is in node_modules",
);
}
@ -146,7 +151,7 @@ where
for (from, to) in &self.paths {
match from {
Pattern::Wildcard { prefix } => {
let extra = src.strip_prefix(prefix);
let extra = module_specifier.strip_prefix(prefix);
let extra = match extra {
Some(v) => v,
None => {
@ -169,7 +174,7 @@ where
let res = self.inner.resolve(base, &rel).with_context(|| {
format!(
"failed to resolve `{}`, which is expanded from `{}`",
replaced, src
replaced, module_specifier
)
});
@ -192,14 +197,14 @@ where
bail!(
"`{}` matched `{}` (from tsconfig.paths) but failed to resolve:\n{:?}",
src,
module_specifier,
prefix,
errors
)
}
Pattern::Exact(from) => {
// Should be exactly matched
if src == from {
if module_specifier == from {
let replaced = self.base_url.join(&to[0]);
if replaced.exists() {
return Ok(FileName::Real(replaced));
@ -219,6 +224,13 @@ where
}
}
self.inner.resolve(base, src)
if let Ok(v) = self
.inner
.resolve(&self.base_url_filename, module_specifier)
{
return Ok(v);
}
self.inner.resolve(base, module_specifier)
}
}

View File

@ -4,6 +4,7 @@ use std::{
};
use indexmap::IndexMap;
use serde::Deserialize;
use swc_common::FileName;
use swc_ecma_loader::resolvers::{node::NodeModulesResolver, tsc::TsConfigResolver};
use swc_ecma_parser::Syntax;
@ -96,29 +97,46 @@ fn paths_resolver(
base_url: impl AsRef<Path>,
rules: Vec<(String, Vec<String>)>,
) -> JscPathsProvider {
let base_url = base_url.as_ref().to_path_buf();
dbg!(&base_url);
NodeImportResolver::new(TsConfigResolver::new(
NodeModulesResolver::new(swc_ecma_loader::TargetEnv::Node, Default::default(), true),
base_url.as_ref().to_path_buf(),
base_url,
rules,
))
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct TestConfig {
#[serde(default)]
base_url: Option<PathBuf>,
#[serde(default)]
input_file: Option<String>,
#[serde(default)]
paths: IndexMap<String, Vec<String>>,
}
#[testing::fixture("tests/paths/**/input")]
fn fixture(input_dir: PathBuf) {
let output_dir = input_dir.parent().unwrap().join("output");
let index_path = input_dir.join("index.ts");
let paths_json_path = input_dir.join("config.json");
let paths_json = std::fs::read_to_string(paths_json_path).unwrap();
let config = serde_json::from_str::<TestConfig>(&paths_json).unwrap();
let index_path = input_dir.join(config.input_file.as_deref().unwrap_or("index.ts"));
test_fixture(
Syntax::default(),
&|_| {
let paths_json_path = input_dir.join("paths.json");
let paths_json = std::fs::read_to_string(paths_json_path).unwrap();
let paths = serde_json::from_str::<IndexMap<String, Vec<String>>>(&paths_json).unwrap();
let rules = config.paths.clone().into_iter().collect();
let rules = paths.into_iter().collect();
let resolver = paths_resolver(&input_dir, rules);
let resolver =
paths_resolver(config.base_url.clone().unwrap_or(input_dir.clone()), rules);
import_rewriter(FileName::Real(index_path.clone()), resolver)
},

View File

@ -0,0 +1,4 @@
{
"baseUrl": "src",
"inputFile": "src/index.ts"
}

View File

@ -0,0 +1,3 @@
import jq from "jquery";
import file from "folder/file2";
console.log(jq, file);

View File

@ -0,0 +1,3 @@
import jq from "jquery";
import file from "./folder/file2";
console.log(jq, file);

View File

@ -0,0 +1,4 @@
{
"baseUrl": "src",
"inputFile": "src/index.ts"
}

View File

@ -0,0 +1,3 @@
import jq from "../jquery";
import file from "./file2";
console.log(jq, file);

View File

@ -0,0 +1,3 @@
import jq from "./jquery";
import file from "./folder/file2";
console.log(jq, file);

View File

@ -0,0 +1,4 @@
{
"baseUrl": "src",
"inputFile": "src/index.ts"
}

View File

@ -0,0 +1,4 @@
import jq from 'jquery';
import file from "folder/file2";
console.log(jq, file)

View File

@ -0,0 +1,5 @@
{
"paths": {
"@src/*": ["./*"]
}
}

View File

@ -1,3 +0,0 @@
{
"@src/*": ["./*"]
}

View File

@ -0,0 +1,5 @@
{
"paths": {
"@lib/*": ["./src/*"]
}
}

View File

@ -1,3 +0,0 @@
{
"@lib/*": ["./src/*"]
}

View File

@ -0,0 +1,5 @@
{
"paths": {
"@src/*": ["./src/*"]
}
}

View File

@ -1,3 +0,0 @@
{
"@src/*": ["./src/*"]
}

View File

@ -0,0 +1,5 @@
{
"paths": {
"@src/*": ["./src/*"]
}
}

View File

@ -1,3 +0,0 @@
{
"@src/*": ["./src/*"]
}

View File

@ -0,0 +1,6 @@
{
"paths": {
"shared/*": ["./src/shared/*"],
"utils/*": ["./src/utils/*"]
}
}

View File

@ -1,8 +0,0 @@
{
"shared/*": [
"./src/shared/*"
],
"utils/*": [
"./src/utils/*"
]
}

View File

@ -0,0 +1,5 @@
{
"paths": {
"@src/*": ["./src/*"]
}
}

View File

@ -1,3 +0,0 @@
{
"@src/*": ["./src/*"]
}

View File

@ -0,0 +1,5 @@
{
"paths": {
"@src/*": ["./src/*"]
}
}

View File

@ -1,3 +0,0 @@
{
"@src/*": ["./src/*"]
}

View File

@ -0,0 +1,5 @@
{
"paths": {
"@/*": ["./src/*"]
}
}

View File

@ -1,5 +0,0 @@
{
"@/*": [
"./src/*"
]
}

View File

@ -0,0 +1,5 @@
{
"paths": {
"@/utils/*": ["./*"]
}
}

View File

@ -1,3 +0,0 @@
{
"@/utils/*": ["./*"]
}

View File

@ -0,0 +1,5 @@
{
"paths": {
"@/utils/*": ["./*"]
}
}

View File

@ -1,3 +0,0 @@
{
"@/utils/*": ["./*"]
}