Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
1
third-party/vendor/swc_ecma_loader/.cargo-checksum.json
vendored
Normal file
1
third-party/vendor/swc_ecma_loader/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{"Cargo.toml":"2441c5727f8fc7a8ea984d5d1327b5e0257513259789824f65b0e52684dca714","src/lib.rs":"f0574f53ee044742de273fdd148600a26ad6352818e1e13f488f46184ce69d60","src/resolve.rs":"f8991b808a2f4592be9865c49d4851216fe84618e58b97d9a7d4e6c60f299eee","src/resolvers/lru.rs":"4bd4bfdf0da2f9d2b17ab7380992b505f364ff9f6de0d23453454c2ac253b76f","src/resolvers/mod.rs":"e383ac51bfb549be72ce510fee279f073b7375860551946a3a1bc17700fe5016","src/resolvers/node.rs":"227d9bebabe502c607f6a21363bfe63f25c2db801070412b8ede7f4fbc6345c3","src/resolvers/tsc.rs":"bbb665584e0e9f0beca530c29aee60775b05593311c9966e2b720105b9fb7084","tests/basic_import/node_modules/jquery/index.js":"b97dc449b77078dc8b6af5996da434382ae78a551e2268d0e9b7c0dea5dce8ab","tests/basic_import/node_modules/jquery/package.json":"239dfc0bd6b1e2a0859f9683801d41ca46d7f3e6e5ab9cc967d9d22ca14c98af","tests/browser_overwrite/node_modules/jquery/browser.js":"b97dc449b77078dc8b6af5996da434382ae78a551e2268d0e9b7c0dea5dce8ab","tests/browser_overwrite/node_modules/jquery/index.js":"b97dc449b77078dc8b6af5996da434382ae78a551e2268d0e9b7c0dea5dce8ab","tests/browser_overwrite/node_modules/jquery/package.json":"90521fbd10df8533a3af012884e389937a42dd78623b810aef1265ca50ac6fd8","tests/hoisting/node_modules/jquery/index.js":"b97dc449b77078dc8b6af5996da434382ae78a551e2268d0e9b7c0dea5dce8ab","tests/hoisting/node_modules/jquery/package.json":"239dfc0bd6b1e2a0859f9683801d41ca46d7f3e6e5ab9cc967d9d22ca14c98af","tests/hoisting/packages/app/file.js":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","tests/hoisting/packages/app/node_modules/example/index.js":"b97dc449b77078dc8b6af5996da434382ae78a551e2268d0e9b7c0dea5dce8ab","tests/hoisting/packages/app/node_modules/example/package.json":"d4463f734c27f09438eac742821dc2ee69e0e24659a8d5f470bdcfdfca2ca4e2","tests/hoisting/packages/app/package.json":"0e4b70448868163c4ce770bc7053e2e688671a444f0cce8e9819027bc713d499","tests/node_resolver.rs":"bb2ea9cf8c0ff97fd7b164c2958c655bcffea58083d79c8dccf2052d7c379352","tests/tsc_resolver.rs":"5503e2cbd58f008730ec4eedfb8d47fa35ef623a901513daa399b4f7dd715735"},"package":"e7d7c322462657ae27ac090a2c89f7e456c94416284a2f5ecf66c43a6a3c19d1"}
|
||||
100
third-party/vendor/swc_ecma_loader/Cargo.toml
vendored
Normal file
100
third-party/vendor/swc_ecma_loader/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2021"
|
||||
name = "swc_ecma_loader"
|
||||
version = "0.44.2"
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
description = "General ecmascript loader used for transforms"
|
||||
documentation = "https://rustdoc.swc.rs/swc_ecma_loader/"
|
||||
license = "Apache-2.0"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = [
|
||||
"--cfg",
|
||||
"docsrs",
|
||||
]
|
||||
|
||||
[lib]
|
||||
bench = false
|
||||
|
||||
[dependencies.anyhow]
|
||||
version = "1.0.71"
|
||||
|
||||
[dependencies.dashmap]
|
||||
version = "5.4.0"
|
||||
optional = true
|
||||
|
||||
[dependencies.lru]
|
||||
version = "0.10.0"
|
||||
optional = true
|
||||
|
||||
[dependencies.once_cell]
|
||||
version = "1.18.0"
|
||||
optional = true
|
||||
|
||||
[dependencies.parking_lot]
|
||||
version = "0.12.1"
|
||||
optional = true
|
||||
|
||||
[dependencies.path-clean]
|
||||
version = "=0.1.0"
|
||||
optional = true
|
||||
|
||||
[dependencies.pathdiff]
|
||||
version = "0.2.1"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1"
|
||||
features = ["derive"]
|
||||
|
||||
[dependencies.serde_json]
|
||||
version = "1.0.64"
|
||||
optional = true
|
||||
|
||||
[dependencies.swc_cached]
|
||||
version = "0.3.17"
|
||||
optional = true
|
||||
|
||||
[dependencies.swc_common]
|
||||
version = "0.32.0"
|
||||
|
||||
[dependencies.tracing]
|
||||
version = "0.1.37"
|
||||
|
||||
[dev-dependencies.lazy_static]
|
||||
version = "1.4.0"
|
||||
|
||||
[features]
|
||||
cache = [
|
||||
"lru",
|
||||
"parking_lot",
|
||||
]
|
||||
default = []
|
||||
node = [
|
||||
"normpath",
|
||||
"serde_json",
|
||||
"dashmap",
|
||||
"once_cell",
|
||||
"path-clean",
|
||||
]
|
||||
tsc = [
|
||||
"dashmap",
|
||||
"once_cell",
|
||||
"swc_cached",
|
||||
]
|
||||
|
||||
[target."cfg(windows)".dependencies.normpath]
|
||||
version = "0.2"
|
||||
optional = true
|
||||
93
third-party/vendor/swc_ecma_loader/src/lib.rs
vendored
Normal file
93
third-party/vendor/swc_ecma_loader/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub mod resolve;
|
||||
pub mod resolvers;
|
||||
|
||||
/// List of built in packages for latest stable node with LTS (node@16).
|
||||
///
|
||||
/// Run `node -p "require('module').builtinModules"`
|
||||
pub const NODE_BUILTINS: &[&str] = &[
|
||||
"_http_agent",
|
||||
"_http_client",
|
||||
"_http_common",
|
||||
"_http_incoming",
|
||||
"_http_outgoing",
|
||||
"_http_server",
|
||||
"_stream_duplex",
|
||||
"_stream_passthrough",
|
||||
"_stream_readable",
|
||||
"_stream_transform",
|
||||
"_stream_wrap",
|
||||
"_stream_writable",
|
||||
"_tls_common",
|
||||
"_tls_wrap",
|
||||
"assert",
|
||||
"assert/strict",
|
||||
"async_hooks",
|
||||
"buffer",
|
||||
"child_process",
|
||||
"cluster",
|
||||
"console",
|
||||
"constants",
|
||||
"crypto",
|
||||
"dgram",
|
||||
"diagnostics_channel",
|
||||
"dns",
|
||||
"dns/promises",
|
||||
"domain",
|
||||
"events",
|
||||
"fs",
|
||||
"fs/promises",
|
||||
"http",
|
||||
"http2",
|
||||
"https",
|
||||
"inspector",
|
||||
"module",
|
||||
"net",
|
||||
"os",
|
||||
"path",
|
||||
"path/posix",
|
||||
"path/win32",
|
||||
"perf_hooks",
|
||||
"process",
|
||||
"punycode",
|
||||
"querystring",
|
||||
"readline",
|
||||
"readline/promises",
|
||||
"repl",
|
||||
"stream",
|
||||
"stream/consumers",
|
||||
"stream/promises",
|
||||
"stream/web",
|
||||
"string_decoder",
|
||||
"sys",
|
||||
"timers",
|
||||
"timers/promises",
|
||||
"tls",
|
||||
"trace_events",
|
||||
"tty",
|
||||
"url",
|
||||
"util",
|
||||
"util/types",
|
||||
"v8",
|
||||
"vm",
|
||||
"worker_threads",
|
||||
"zlib",
|
||||
];
|
||||
|
||||
/// Target runtime environment.
|
||||
#[derive(Debug, Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
||||
pub enum TargetEnv {
|
||||
#[serde(rename = "browser")]
|
||||
Browser,
|
||||
#[serde(rename = "node")]
|
||||
Node,
|
||||
}
|
||||
|
||||
impl Default for TargetEnv {
|
||||
fn default() -> Self {
|
||||
TargetEnv::Browser
|
||||
}
|
||||
}
|
||||
28
third-party/vendor/swc_ecma_loader/src/resolve.rs
vendored
Normal file
28
third-party/vendor/swc_ecma_loader/src/resolve.rs
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Error;
|
||||
use swc_common::{
|
||||
sync::{Send, Sync},
|
||||
FileName,
|
||||
};
|
||||
|
||||
pub trait Resolve: Send + Sync {
|
||||
fn resolve(&self, base: &FileName, module_specifier: &str) -> Result<FileName, Error>;
|
||||
}
|
||||
|
||||
macro_rules! impl_ref {
|
||||
($R:ident, $T:ty) => {
|
||||
impl<$R> Resolve for $T
|
||||
where
|
||||
R: ?Sized + Resolve,
|
||||
{
|
||||
fn resolve(&self, base: &FileName, src: &str) -> Result<FileName, Error> {
|
||||
(**self).resolve(base, src)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_ref!(R, &'_ R);
|
||||
impl_ref!(R, Box<R>);
|
||||
impl_ref!(R, Arc<R>);
|
||||
63
third-party/vendor/swc_ecma_loader/src/resolvers/lru.rs
vendored
Normal file
63
third-party/vendor/swc_ecma_loader/src/resolvers/lru.rs
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
use std::num::NonZeroUsize;
|
||||
|
||||
use anyhow::Error;
|
||||
use lru::LruCache;
|
||||
use parking_lot::Mutex;
|
||||
use swc_common::FileName;
|
||||
|
||||
use crate::resolve::Resolve;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CachingResolver<R>
|
||||
where
|
||||
R: Resolve,
|
||||
{
|
||||
cache: Mutex<LruCache<(FileName, String), FileName>>,
|
||||
inner: R,
|
||||
}
|
||||
|
||||
impl<R> Default for CachingResolver<R>
|
||||
where
|
||||
R: Resolve + Default,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self::new(40, Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> CachingResolver<R>
|
||||
where
|
||||
R: Resolve,
|
||||
{
|
||||
pub fn new(cap: usize, inner: R) -> Self {
|
||||
Self {
|
||||
cache: Mutex::new(LruCache::new(
|
||||
NonZeroUsize::try_from(cap).expect("cap == 0"),
|
||||
)),
|
||||
inner,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> Resolve for CachingResolver<R>
|
||||
where
|
||||
R: Resolve,
|
||||
{
|
||||
fn resolve(&self, base: &FileName, src: &str) -> Result<FileName, Error> {
|
||||
{
|
||||
let mut lock = self.cache.lock();
|
||||
//
|
||||
if let Some(v) = lock.get(&(base.clone(), src.to_string())) {
|
||||
return Ok(v.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let resolved = self.inner.resolve(base, src)?;
|
||||
{
|
||||
let mut lock = self.cache.lock();
|
||||
lock.put((base.clone(), src.to_string()), resolved.clone());
|
||||
}
|
||||
|
||||
Ok(resolved)
|
||||
}
|
||||
}
|
||||
9
third-party/vendor/swc_ecma_loader/src/resolvers/mod.rs
vendored
Normal file
9
third-party/vendor/swc_ecma_loader/src/resolvers/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#[cfg(feature = "lru")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "lru")))]
|
||||
pub mod lru;
|
||||
#[cfg(feature = "node")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "node")))]
|
||||
pub mod node;
|
||||
#[cfg(feature = "tsc")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tsc")))]
|
||||
pub mod tsc;
|
||||
529
third-party/vendor/swc_ecma_loader/src/resolvers/node.rs
vendored
Normal file
529
third-party/vendor/swc_ecma_loader/src/resolvers/node.rs
vendored
Normal file
|
|
@ -0,0 +1,529 @@
|
|||
//! Faster version of node-resolve.
|
||||
//!
|
||||
//! See: https://github.com/goto-bus-stop/node-resolve
|
||||
|
||||
use std::{
|
||||
env::current_dir,
|
||||
fs::File,
|
||||
io::BufReader,
|
||||
path::{Component, Path, PathBuf},
|
||||
};
|
||||
|
||||
use anyhow::{bail, Context, Error};
|
||||
use dashmap::DashMap;
|
||||
#[cfg(windows)]
|
||||
use normpath::BasePath;
|
||||
use once_cell::sync::Lazy;
|
||||
use path_clean::PathClean;
|
||||
use pathdiff::diff_paths;
|
||||
use serde::Deserialize;
|
||||
use swc_common::{
|
||||
collections::{AHashMap, AHashSet, ARandomState},
|
||||
FileName,
|
||||
};
|
||||
use tracing::{debug, trace, Level};
|
||||
|
||||
use crate::{resolve::Resolve, TargetEnv, NODE_BUILTINS};
|
||||
|
||||
static PACKAGE: &str = "package.json";
|
||||
|
||||
/// Map of cached `browser` fields from deserialized package.json
|
||||
/// used to determine if we need to map to alternative paths when
|
||||
/// bundling for the browser runtime environment. The key is the
|
||||
/// directory containing the package.json file which is important
|
||||
/// to ensure we only apply these `browser` rules to modules in
|
||||
/// the owning package.
|
||||
static BROWSER_CACHE: Lazy<DashMap<PathBuf, BrowserCache, ARandomState>> =
|
||||
Lazy::new(Default::default);
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct BrowserCache {
|
||||
rewrites: AHashMap<PathBuf, PathBuf>,
|
||||
ignores: AHashSet<PathBuf>,
|
||||
module_rewrites: AHashMap<String, PathBuf>,
|
||||
module_ignores: AHashSet<String>,
|
||||
}
|
||||
|
||||
/// Helper to find the nearest `package.json` file to get
|
||||
/// the base directory for a package.
|
||||
fn find_package_root(path: &Path) -> Option<PathBuf> {
|
||||
let mut parent = path.parent();
|
||||
while let Some(p) = parent {
|
||||
let pkg = p.join(PACKAGE);
|
||||
if pkg.is_file() {
|
||||
return Some(p.to_path_buf());
|
||||
}
|
||||
parent = p.parent();
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn to_absolute_path(path: &Path) -> Result<PathBuf, Error> {
|
||||
let absolute_path = if path.is_absolute() {
|
||||
path.to_path_buf()
|
||||
} else {
|
||||
current_dir()?.join(path)
|
||||
}
|
||||
.clean();
|
||||
|
||||
Ok(absolute_path)
|
||||
}
|
||||
|
||||
pub(crate) fn is_core_module(s: &str) -> bool {
|
||||
NODE_BUILTINS.contains(&s)
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct PackageJson {
|
||||
#[serde(default)]
|
||||
main: Option<String>,
|
||||
#[serde(default)]
|
||||
browser: Option<Browser>,
|
||||
#[serde(default)]
|
||||
module: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum Browser {
|
||||
Str(String),
|
||||
Obj(AHashMap<String, StringOrBool>),
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
#[serde(untagged)]
|
||||
enum StringOrBool {
|
||||
Str(String),
|
||||
Bool(bool),
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct NodeModulesResolver {
|
||||
target_env: TargetEnv,
|
||||
alias: AHashMap<String, String>,
|
||||
// if true do not resolve symlink
|
||||
preserve_symlinks: bool,
|
||||
ignore_node_modules: bool,
|
||||
}
|
||||
|
||||
static EXTENSIONS: &[&str] = &["ts", "tsx", "js", "jsx", "json", "node"];
|
||||
|
||||
impl NodeModulesResolver {
|
||||
/// Create a node modules resolver for the target runtime environment.
|
||||
pub fn new(
|
||||
target_env: TargetEnv,
|
||||
alias: AHashMap<String, String>,
|
||||
preserve_symlinks: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
target_env,
|
||||
alias,
|
||||
preserve_symlinks,
|
||||
ignore_node_modules: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a node modules resolver which does not care about `node_modules`
|
||||
pub fn without_node_modules(
|
||||
target_env: TargetEnv,
|
||||
alias: AHashMap<String, String>,
|
||||
preserve_symlinks: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
target_env,
|
||||
alias,
|
||||
preserve_symlinks,
|
||||
ignore_node_modules: true,
|
||||
}
|
||||
}
|
||||
|
||||
fn wrap(&self, path: Option<PathBuf>) -> Result<FileName, Error> {
|
||||
if let Some(path) = path {
|
||||
if self.preserve_symlinks {
|
||||
return Ok(FileName::Real(path.clean()));
|
||||
} else {
|
||||
return Ok(FileName::Real(path.canonicalize()?));
|
||||
}
|
||||
}
|
||||
bail!("index not found")
|
||||
}
|
||||
|
||||
/// Resolve a path as a file. If `path` refers to a file, it is returned;
|
||||
/// otherwise the `path` + each extension is tried.
|
||||
fn resolve_as_file(&self, path: &Path) -> Result<Option<PathBuf>, Error> {
|
||||
let _tracing = if cfg!(debug_assertions) {
|
||||
Some(
|
||||
tracing::span!(
|
||||
Level::ERROR,
|
||||
"resolve_as_file",
|
||||
path = tracing::field::display(path.display())
|
||||
)
|
||||
.entered(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
trace!("resolve_as_file({})", path.display());
|
||||
}
|
||||
|
||||
let try_exact = path.extension().is_some();
|
||||
if try_exact {
|
||||
if path.is_file() {
|
||||
return Ok(Some(path.to_path_buf()));
|
||||
}
|
||||
} else {
|
||||
// We try `.js` first.
|
||||
let mut path = path.to_path_buf();
|
||||
path.set_extension("js");
|
||||
if path.is_file() {
|
||||
return Ok(Some(path));
|
||||
}
|
||||
}
|
||||
|
||||
// Try exact file after checking .js, for performance
|
||||
if !try_exact && path.is_file() {
|
||||
return Ok(Some(path.to_path_buf()));
|
||||
}
|
||||
|
||||
if let Some(name) = path.file_name() {
|
||||
let mut ext_path = path.to_path_buf();
|
||||
let name = name.to_string_lossy();
|
||||
for ext in EXTENSIONS {
|
||||
ext_path.set_file_name(format!("{}.{}", name, ext));
|
||||
if ext_path.is_file() {
|
||||
return Ok(Some(ext_path));
|
||||
}
|
||||
}
|
||||
|
||||
// TypeScript-specific behavior: if the extension is ".js" or ".jsx",
|
||||
// try replacing it with ".ts" or ".tsx".
|
||||
ext_path.set_file_name(name.into_owned());
|
||||
let old_ext = path.extension().and_then(|ext| ext.to_str());
|
||||
|
||||
if let Some(old_ext) = old_ext {
|
||||
let extensions: &[&str] = match old_ext {
|
||||
// Note that the official compiler code always tries ".ts" before
|
||||
// ".tsx" even if the original extension was ".jsx".
|
||||
"js" => &["ts", "tsx"],
|
||||
"jsx" => &["ts", "tsx"],
|
||||
"mjs" => &["mts"],
|
||||
"cjs" => &["cts"],
|
||||
_ => &[],
|
||||
};
|
||||
|
||||
for ext in extensions {
|
||||
ext_path.set_extension(ext);
|
||||
|
||||
if ext_path.is_file() {
|
||||
return Ok(Some(ext_path));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bail!("file not found: {}", path.display())
|
||||
}
|
||||
|
||||
/// Resolve a path as a directory, using the "main" key from a package.json
|
||||
/// file if it exists, or resolving to the index.EXT file if it exists.
|
||||
fn resolve_as_directory(
|
||||
&self,
|
||||
path: &Path,
|
||||
allow_package_entry: bool,
|
||||
) -> Result<Option<PathBuf>, Error> {
|
||||
let _tracing = if cfg!(debug_assertions) {
|
||||
Some(
|
||||
tracing::span!(
|
||||
Level::ERROR,
|
||||
"resolve_as_directory",
|
||||
path = tracing::field::display(path.display())
|
||||
)
|
||||
.entered(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
trace!("resolve_as_directory({})", path.display());
|
||||
}
|
||||
|
||||
let pkg_path = path.join(PACKAGE);
|
||||
if allow_package_entry && pkg_path.is_file() {
|
||||
if let Some(main) = self.resolve_package_entry(path, &pkg_path)? {
|
||||
return Ok(Some(main));
|
||||
}
|
||||
}
|
||||
|
||||
// Try to resolve to an index file.
|
||||
for ext in EXTENSIONS {
|
||||
let ext_path = path.join(format!("index.{}", ext));
|
||||
if ext_path.is_file() {
|
||||
return Ok(Some(ext_path));
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Resolve using the package.json "main" or "browser" keys.
|
||||
fn resolve_package_entry(
|
||||
&self,
|
||||
pkg_dir: &Path,
|
||||
pkg_path: &Path,
|
||||
) -> Result<Option<PathBuf>, Error> {
|
||||
let _tracing = if cfg!(debug_assertions) {
|
||||
Some(
|
||||
tracing::span!(
|
||||
Level::ERROR,
|
||||
"resolve_package_entry",
|
||||
pkg_dir = tracing::field::display(pkg_dir.display()),
|
||||
pkg_path = tracing::field::display(pkg_path.display()),
|
||||
)
|
||||
.entered(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let file = File::open(pkg_path)?;
|
||||
let reader = BufReader::new(file);
|
||||
let pkg: PackageJson = serde_json::from_reader(reader)
|
||||
.context(format!("failed to deserialize {}", pkg_path.display()))?;
|
||||
|
||||
let main_fields = match self.target_env {
|
||||
TargetEnv::Node => {
|
||||
vec![pkg.module.as_ref(), pkg.main.as_ref()]
|
||||
}
|
||||
TargetEnv::Browser => {
|
||||
if let Some(browser) = &pkg.browser {
|
||||
match browser {
|
||||
Browser::Str(path) => {
|
||||
vec![Some(path), pkg.module.as_ref(), pkg.main.as_ref()]
|
||||
}
|
||||
Browser::Obj(map) => {
|
||||
let mut bucket = BrowserCache::default();
|
||||
|
||||
for (k, v) in map {
|
||||
let target_key = Path::new(k);
|
||||
let mut components = target_key.components();
|
||||
|
||||
// Relative file paths are sources for this package
|
||||
let source = if let Some(Component::CurDir) = components.next() {
|
||||
let path = pkg_dir.join(k);
|
||||
if let Ok(file) = self
|
||||
.resolve_as_file(&path)
|
||||
.or_else(|_| self.resolve_as_directory(&path, false))
|
||||
{
|
||||
file.map(|file| file.clean())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
match v {
|
||||
StringOrBool::Str(dest) => {
|
||||
let path = pkg_dir.join(dest);
|
||||
let file = self
|
||||
.resolve_as_file(&path)
|
||||
.or_else(|_| self.resolve_as_directory(&path, false))?;
|
||||
if let Some(file) = file {
|
||||
let target = file.clean();
|
||||
let target = target
|
||||
.strip_prefix(current_dir().unwrap_or_default())
|
||||
.map(|target| target.to_path_buf())
|
||||
.unwrap_or(target);
|
||||
|
||||
if let Some(source) = source {
|
||||
bucket.rewrites.insert(source, target);
|
||||
} else {
|
||||
bucket.module_rewrites.insert(k.clone(), target);
|
||||
}
|
||||
}
|
||||
}
|
||||
StringOrBool::Bool(flag) => {
|
||||
// If somebody set boolean `true` which is an
|
||||
// invalid value we will just ignore it
|
||||
if !flag {
|
||||
if let Some(source) = source {
|
||||
bucket.ignores.insert(source);
|
||||
} else {
|
||||
bucket.module_ignores.insert(k.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BROWSER_CACHE.insert(pkg_dir.to_path_buf(), bucket);
|
||||
|
||||
vec![pkg.module.as_ref(), pkg.main.as_ref()]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
vec![pkg.module.as_ref(), pkg.main.as_ref()]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(Some(target)) = main_fields.iter().find(|x| x.is_some()) {
|
||||
let path = pkg_dir.join(target);
|
||||
return self
|
||||
.resolve_as_file(&path)
|
||||
.or_else(|_| self.resolve_as_directory(&path, false));
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Resolve by walking up node_modules folders.
|
||||
fn resolve_node_modules(
|
||||
&self,
|
||||
base_dir: &Path,
|
||||
target: &str,
|
||||
) -> Result<Option<PathBuf>, Error> {
|
||||
if self.ignore_node_modules {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let absolute_path = to_absolute_path(base_dir)?;
|
||||
let mut path = Some(&*absolute_path);
|
||||
while let Some(dir) = path {
|
||||
let node_modules = dir.join("node_modules");
|
||||
if node_modules.is_dir() {
|
||||
let path = node_modules.join(target);
|
||||
if let Some(result) = self
|
||||
.resolve_as_file(&path)
|
||||
.ok()
|
||||
.or_else(|| self.resolve_as_directory(&path, true).ok())
|
||||
.flatten()
|
||||
{
|
||||
return Ok(Some(result));
|
||||
}
|
||||
}
|
||||
path = dir.parent();
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
impl Resolve for NodeModulesResolver {
|
||||
fn resolve(&self, base: &FileName, target: &str) -> Result<FileName, Error> {
|
||||
debug!(
|
||||
"Resolving {} from {:#?} for {:#?}",
|
||||
target, base, self.target_env
|
||||
);
|
||||
|
||||
let base = match base {
|
||||
FileName::Real(v) => v,
|
||||
_ => bail!("node-resolver supports only files"),
|
||||
};
|
||||
|
||||
let base_dir = if base.is_file() {
|
||||
let cwd = &Path::new(".");
|
||||
base.parent().unwrap_or(cwd)
|
||||
} else {
|
||||
base
|
||||
};
|
||||
|
||||
// Handle module references for the `browser` package config
|
||||
// before we map aliases.
|
||||
if let TargetEnv::Browser = self.target_env {
|
||||
if let Some(pkg_base) = find_package_root(base) {
|
||||
if let Some(item) = BROWSER_CACHE.get(&pkg_base) {
|
||||
let value = item.value();
|
||||
if value.module_ignores.contains(target) {
|
||||
return Ok(FileName::Custom(target.into()));
|
||||
}
|
||||
if let Some(rewrite) = value.module_rewrites.get(target) {
|
||||
return self.wrap(Some(rewrite.to_path_buf()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle builtin modules for nodejs
|
||||
if let TargetEnv::Node = self.target_env {
|
||||
if target.starts_with("node:") {
|
||||
return Ok(FileName::Custom(target.into()));
|
||||
}
|
||||
|
||||
if is_core_module(target) {
|
||||
return Ok(FileName::Custom(format!("node:{}", target)));
|
||||
}
|
||||
}
|
||||
|
||||
// Aliases allow browser shims to be renamed so we can
|
||||
// map `stream` to `stream-browserify` for example
|
||||
let target = if let Some(alias) = self.alias.get(target) {
|
||||
&alias[..]
|
||||
} else {
|
||||
target
|
||||
};
|
||||
|
||||
let target_path = Path::new(target);
|
||||
|
||||
let file_name = {
|
||||
if target_path.is_absolute() {
|
||||
let path = PathBuf::from(target_path);
|
||||
self.resolve_as_file(&path)
|
||||
.or_else(|_| self.resolve_as_directory(&path, true))
|
||||
.and_then(|p| self.wrap(p))
|
||||
} else {
|
||||
let mut components = target_path.components();
|
||||
|
||||
if let Some(Component::CurDir | Component::ParentDir) = components.next() {
|
||||
#[cfg(windows)]
|
||||
let path = {
|
||||
let base_dir = BasePath::new(base_dir).unwrap();
|
||||
base_dir
|
||||
.join(target.replace('/', "\\"))
|
||||
.normalize_virtually()
|
||||
.unwrap()
|
||||
.into_path_buf()
|
||||
};
|
||||
#[cfg(not(windows))]
|
||||
let path = base_dir.join(target);
|
||||
self.resolve_as_file(&path)
|
||||
.or_else(|_| self.resolve_as_directory(&path, true))
|
||||
.and_then(|p| self.wrap(p))
|
||||
} else {
|
||||
self.resolve_node_modules(base_dir, target)
|
||||
.and_then(|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)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
.and_then(|v| {
|
||||
// Handle path references for the `browser` package config
|
||||
if let TargetEnv::Browser = self.target_env {
|
||||
if let FileName::Real(path) = &v {
|
||||
if let Some(pkg_base) = find_package_root(path) {
|
||||
let pkg_base = to_absolute_path(&pkg_base).unwrap();
|
||||
if let Some(item) = BROWSER_CACHE.get(&pkg_base) {
|
||||
let value = item.value();
|
||||
let path = to_absolute_path(path).unwrap();
|
||||
if value.ignores.contains(&path) {
|
||||
return Ok(FileName::Custom(path.display().to_string()));
|
||||
}
|
||||
if let Some(rewrite) = value.rewrites.get(&path) {
|
||||
return self.wrap(Some(rewrite.to_path_buf()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(v)
|
||||
});
|
||||
|
||||
file_name
|
||||
}
|
||||
}
|
||||
292
third-party/vendor/swc_ecma_loader/src/resolvers/tsc.rs
vendored
Normal file
292
third-party/vendor/swc_ecma_loader/src/resolvers/tsc.rs
vendored
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
use std::path::{Component, Path, PathBuf};
|
||||
|
||||
use anyhow::{bail, Context, Error};
|
||||
use swc_common::FileName;
|
||||
use tracing::{debug, info, trace, warn, Level};
|
||||
|
||||
use crate::resolve::Resolve;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Pattern {
|
||||
Wildcard {
|
||||
prefix: String,
|
||||
},
|
||||
/// No wildcard.
|
||||
Exact(String),
|
||||
}
|
||||
|
||||
/// Support for `paths` of `tsconfig.json`.
|
||||
///
|
||||
/// See https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
|
||||
#[derive(Debug)]
|
||||
pub struct TsConfigResolver<R>
|
||||
where
|
||||
R: Resolve,
|
||||
{
|
||||
inner: R,
|
||||
base_url: PathBuf,
|
||||
base_url_filename: FileName,
|
||||
paths: Vec<(Pattern, Vec<String>)>,
|
||||
}
|
||||
|
||||
impl<R> TsConfigResolver<R>
|
||||
where
|
||||
R: Resolve,
|
||||
{
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// ## base_url
|
||||
///
|
||||
/// See https://www.typescriptlang.org/tsconfig#baseUrl
|
||||
///
|
||||
/// The typescript documentation says `This must be specified if "paths"
|
||||
/// is.`.
|
||||
///
|
||||
/// ## `paths`
|
||||
///
|
||||
/// Pass `paths` map from `tsconfig.json`.
|
||||
///
|
||||
/// See https://www.typescriptlang.org/tsconfig#paths
|
||||
///
|
||||
/// Note that this is not a hashmap because value is not used as a hash map.
|
||||
pub fn new(inner: R, base_url: PathBuf, paths: Vec<(String, Vec<String>)>) -> Self {
|
||||
if cfg!(debug_assertions) {
|
||||
info!(
|
||||
base_url = tracing::field::display(base_url.display()),
|
||||
"jsc.paths"
|
||||
);
|
||||
}
|
||||
|
||||
let paths = paths
|
||||
.into_iter()
|
||||
.map(|(from, to)| {
|
||||
assert!(
|
||||
!to.is_empty(),
|
||||
"value of `paths.{}` should not be an empty array",
|
||||
from,
|
||||
);
|
||||
|
||||
let pos = from.as_bytes().iter().position(|&c| c == b'*');
|
||||
let pat = if from.contains('*') {
|
||||
if from.as_bytes().iter().rposition(|&c| c == b'*') != pos {
|
||||
panic!("`paths.{}` should have only one wildcard", from)
|
||||
}
|
||||
|
||||
Pattern::Wildcard {
|
||||
prefix: from[..pos.unwrap()].to_string(),
|
||||
}
|
||||
} else {
|
||||
assert_eq!(
|
||||
to.len(),
|
||||
1,
|
||||
"value of `paths.{}` should be an array with one element because the src \
|
||||
path does not contains * (wildcard)",
|
||||
from,
|
||||
);
|
||||
|
||||
Pattern::Exact(from)
|
||||
};
|
||||
|
||||
(pat, to)
|
||||
})
|
||||
.collect();
|
||||
|
||||
Self {
|
||||
inner,
|
||||
base_url_filename: FileName::Real(base_url.clone()),
|
||||
base_url,
|
||||
paths,
|
||||
}
|
||||
}
|
||||
|
||||
fn invoke_inner_resolver(
|
||||
&self,
|
||||
base: &FileName,
|
||||
module_specifier: &str,
|
||||
) -> Result<FileName, Error> {
|
||||
let res = self.inner.resolve(base, module_specifier).with_context(|| {
|
||||
format!(
|
||||
"failed to resolve `{module_specifier}` from `{base}` using inner \
|
||||
resolver\nbase_url={}",
|
||||
self.base_url_filename
|
||||
)
|
||||
});
|
||||
|
||||
match res {
|
||||
Ok(resolved) => {
|
||||
info!(
|
||||
"Resolved `{}` as `{}` from `{}`",
|
||||
module_specifier, resolved, base
|
||||
);
|
||||
|
||||
if let FileName::Real(target) = &resolved {
|
||||
// If node_modules is in path, we should return module specifier.
|
||||
if target.components().any(|c| {
|
||||
if let Component::Normal(v) = c {
|
||||
v == "node_modules"
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}) {
|
||||
return Ok(FileName::Real(module_specifier.into()));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(resolved)
|
||||
}
|
||||
|
||||
Err(err) => {
|
||||
warn!("{:?}", err);
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> Resolve for TsConfigResolver<R>
|
||||
where
|
||||
R: Resolve,
|
||||
{
|
||||
fn resolve(&self, base: &FileName, module_specifier: &str) -> Result<FileName, Error> {
|
||||
let _tracing = if cfg!(debug_assertions) {
|
||||
Some(
|
||||
tracing::span!(
|
||||
Level::ERROR,
|
||||
"TsConfigResolver::resolve",
|
||||
base_url = tracing::field::display(self.base_url.display()),
|
||||
base = tracing::field::display(base),
|
||||
src = tracing::field::display(module_specifier),
|
||||
)
|
||||
.entered(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if module_specifier.starts_with('.')
|
||||
&& (module_specifier == ".."
|
||||
|| module_specifier.starts_with("./")
|
||||
|| module_specifier.starts_with("../"))
|
||||
{
|
||||
return self
|
||||
.invoke_inner_resolver(base, module_specifier)
|
||||
.context("not processed by tsc resolver because it's relative import");
|
||||
}
|
||||
|
||||
if let FileName::Real(v) = base {
|
||||
if v.components().any(|c| match c {
|
||||
Component::Normal(v) => v == "node_modules",
|
||||
_ => false,
|
||||
}) {
|
||||
return self.invoke_inner_resolver(base, module_specifier).context(
|
||||
"not processed by tsc resolver because base module is in node_modules",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
info!("Checking `jsc.paths`");
|
||||
|
||||
// https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
|
||||
for (from, to) in &self.paths {
|
||||
match from {
|
||||
Pattern::Wildcard { prefix } => {
|
||||
debug!("Checking `{}` in `jsc.paths`", prefix);
|
||||
|
||||
let extra = module_specifier.strip_prefix(prefix);
|
||||
let extra = match extra {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
if cfg!(debug_assertions) {
|
||||
trace!("skip because src doesn't start with prefix");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
debug!("Extra: `{}`", extra);
|
||||
}
|
||||
|
||||
let mut errors = vec![];
|
||||
for target in to {
|
||||
let mut replaced = target.replace('*', extra);
|
||||
|
||||
let _tracing = if cfg!(debug_assertions) {
|
||||
Some(
|
||||
tracing::span!(
|
||||
Level::ERROR,
|
||||
"TsConfigResolver::resolve::jsc.paths",
|
||||
replaced = tracing::field::display(&replaced),
|
||||
)
|
||||
.entered(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let relative = format!("./{}", replaced);
|
||||
|
||||
let res = self
|
||||
.invoke_inner_resolver(base, module_specifier)
|
||||
.or_else(|_| {
|
||||
self.invoke_inner_resolver(&self.base_url_filename, &relative)
|
||||
})
|
||||
.or_else(|_| {
|
||||
self.invoke_inner_resolver(&self.base_url_filename, &replaced)
|
||||
});
|
||||
|
||||
errors.push(match res {
|
||||
Ok(resolved) => return Ok(resolved),
|
||||
Err(err) => err,
|
||||
});
|
||||
|
||||
if cfg!(target_os = "windows") {
|
||||
replaced = replaced.replace('/', "\\");
|
||||
}
|
||||
|
||||
if to.len() == 1 {
|
||||
info!(
|
||||
"Using `{}` for `{}` because the length of the jsc.paths entry is \
|
||||
1",
|
||||
replaced, module_specifier
|
||||
);
|
||||
return Ok(FileName::Real(replaced.into()));
|
||||
}
|
||||
}
|
||||
|
||||
bail!(
|
||||
"`{}` matched `{}` (from tsconfig.paths) but failed to resolve:\n{:?}",
|
||||
module_specifier,
|
||||
prefix,
|
||||
errors
|
||||
)
|
||||
}
|
||||
Pattern::Exact(from) => {
|
||||
// Should be exactly matched
|
||||
if module_specifier != from {
|
||||
continue;
|
||||
}
|
||||
|
||||
let tp = Path::new(&to[0]);
|
||||
if tp.is_absolute() {
|
||||
return Ok(FileName::Real(tp.into()));
|
||||
}
|
||||
|
||||
if let Ok(res) = self.resolve(&self.base_url_filename, &format!("./{}", &to[0]))
|
||||
{
|
||||
return Ok(res);
|
||||
}
|
||||
|
||||
return Ok(FileName::Real(self.base_url.join(&to[0])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(v) = self.invoke_inner_resolver(&self.base_url_filename, module_specifier) {
|
||||
return Ok(v);
|
||||
}
|
||||
|
||||
self.invoke_inner_resolver(base, module_specifier)
|
||||
}
|
||||
}
|
||||
1
third-party/vendor/swc_ecma_loader/tests/basic_import/node_modules/jquery/index.js
generated
vendored
Normal file
1
third-party/vendor/swc_ecma_loader/tests/basic_import/node_modules/jquery/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
console.log("hello world!");
|
||||
4
third-party/vendor/swc_ecma_loader/tests/basic_import/node_modules/jquery/package.json
generated
vendored
Normal file
4
third-party/vendor/swc_ecma_loader/tests/basic_import/node_modules/jquery/package.json
generated
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "jquery",
|
||||
"main": "index.js"
|
||||
}
|
||||
1
third-party/vendor/swc_ecma_loader/tests/browser_overwrite/node_modules/jquery/browser.js
generated
vendored
Normal file
1
third-party/vendor/swc_ecma_loader/tests/browser_overwrite/node_modules/jquery/browser.js
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
console.log("hello world!");
|
||||
1
third-party/vendor/swc_ecma_loader/tests/browser_overwrite/node_modules/jquery/index.js
generated
vendored
Normal file
1
third-party/vendor/swc_ecma_loader/tests/browser_overwrite/node_modules/jquery/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
console.log("hello world!");
|
||||
7
third-party/vendor/swc_ecma_loader/tests/browser_overwrite/node_modules/jquery/package.json
generated
vendored
Normal file
7
third-party/vendor/swc_ecma_loader/tests/browser_overwrite/node_modules/jquery/package.json
generated
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "jquery",
|
||||
"main": "./index.js",
|
||||
"browser": {
|
||||
"./index.js": "./browser.js"
|
||||
}
|
||||
}
|
||||
1
third-party/vendor/swc_ecma_loader/tests/hoisting/node_modules/jquery/index.js
generated
vendored
Normal file
1
third-party/vendor/swc_ecma_loader/tests/hoisting/node_modules/jquery/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
console.log("hello world!");
|
||||
4
third-party/vendor/swc_ecma_loader/tests/hoisting/node_modules/jquery/package.json
generated
vendored
Normal file
4
third-party/vendor/swc_ecma_loader/tests/hoisting/node_modules/jquery/package.json
generated
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "jquery",
|
||||
"main": "index.js"
|
||||
}
|
||||
0
third-party/vendor/swc_ecma_loader/tests/hoisting/packages/app/file.js
vendored
Normal file
0
third-party/vendor/swc_ecma_loader/tests/hoisting/packages/app/file.js
vendored
Normal file
1
third-party/vendor/swc_ecma_loader/tests/hoisting/packages/app/node_modules/example/index.js
generated
vendored
Normal file
1
third-party/vendor/swc_ecma_loader/tests/hoisting/packages/app/node_modules/example/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
console.log("hello world!");
|
||||
4
third-party/vendor/swc_ecma_loader/tests/hoisting/packages/app/node_modules/example/package.json
generated
vendored
Normal file
4
third-party/vendor/swc_ecma_loader/tests/hoisting/packages/app/node_modules/example/package.json
generated
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "example",
|
||||
"main": "index.js"
|
||||
}
|
||||
4
third-party/vendor/swc_ecma_loader/tests/hoisting/packages/app/package.json
vendored
Normal file
4
third-party/vendor/swc_ecma_loader/tests/hoisting/packages/app/package.json
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "app",
|
||||
"main": "file.js"
|
||||
}
|
||||
107
third-party/vendor/swc_ecma_loader/tests/node_resolver.rs
vendored
Normal file
107
third-party/vendor/swc_ecma_loader/tests/node_resolver.rs
vendored
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
#![deny(warnings)]
|
||||
#![cfg(feature = "node")]
|
||||
|
||||
use std::{
|
||||
env::{current_dir, set_current_dir},
|
||||
path::PathBuf,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use swc_common::FileName;
|
||||
extern crate swc_ecma_loader;
|
||||
use swc_ecma_loader::{resolve::Resolve, resolvers::node::NodeModulesResolver, TargetEnv};
|
||||
|
||||
lazy_static! {
|
||||
static ref UPDATE_DIR_MUTEX: Arc<Mutex<()>> = Arc::new(Mutex::new(()));
|
||||
}
|
||||
|
||||
fn inside_directory(dir: &str, callback: fn()) {
|
||||
let arc = Arc::clone(&UPDATE_DIR_MUTEX);
|
||||
let _lock = arc.lock().expect("could not lock");
|
||||
|
||||
let initial_current_dir = current_dir().unwrap();
|
||||
let new_current_dir = format!("{}{}", initial_current_dir.display(), dir);
|
||||
|
||||
set_current_dir(new_current_dir).unwrap();
|
||||
callback();
|
||||
set_current_dir(initial_current_dir).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn basic_import() {
|
||||
inside_directory("/tests/basic_import", || {
|
||||
// Given
|
||||
let node_resolver = NodeModulesResolver::new(TargetEnv::Node, Default::default(), true);
|
||||
|
||||
// When
|
||||
let resolved = node_resolver
|
||||
.resolve(&FileName::Real(PathBuf::from("jquery")), "jquery")
|
||||
.expect("should resolve");
|
||||
|
||||
// Expect
|
||||
assert_eq!(
|
||||
resolved,
|
||||
FileName::Real(PathBuf::from("node_modules/jquery/index.js"))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hoisting() {
|
||||
inside_directory("/tests/hoisting/packages/app", || {
|
||||
// Given
|
||||
let node_resolver = NodeModulesResolver::new(TargetEnv::Node, Default::default(), true);
|
||||
|
||||
// When
|
||||
let resolved = node_resolver
|
||||
.resolve(&FileName::Real(PathBuf::from("jquery")), "jquery")
|
||||
.expect("should resolve");
|
||||
|
||||
// Expect
|
||||
assert_eq!(
|
||||
resolved,
|
||||
FileName::Real(PathBuf::from("../../node_modules/jquery/index.js"))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builtin_modules() {
|
||||
let node_resolver = NodeModulesResolver::new(TargetEnv::Node, Default::default(), true);
|
||||
|
||||
// When
|
||||
let resolved = node_resolver
|
||||
.resolve(&FileName::Real(PathBuf::from("index.js")), "path")
|
||||
.expect("should resolve");
|
||||
|
||||
// Expect
|
||||
assert_eq!(resolved, FileName::Custom("node:path".to_string()));
|
||||
|
||||
// When
|
||||
let resolved = node_resolver
|
||||
.resolve(&FileName::Real(PathBuf::from("index.js")), "node:path")
|
||||
.expect("should resolve");
|
||||
|
||||
// Expect
|
||||
assert_eq!(resolved, FileName::Custom("node:path".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn browser_overwrite() {
|
||||
inside_directory("/tests/browser_overwrite", || {
|
||||
// Given
|
||||
let node_resolver = NodeModulesResolver::new(TargetEnv::Browser, Default::default(), true);
|
||||
|
||||
// When
|
||||
let resolved = node_resolver
|
||||
.resolve(&FileName::Real(PathBuf::from("jquery")), "jquery")
|
||||
.expect("should resolve");
|
||||
|
||||
// Expect
|
||||
assert_eq!(
|
||||
resolved,
|
||||
FileName::Real(PathBuf::from("node_modules/jquery/browser.js"))
|
||||
);
|
||||
});
|
||||
}
|
||||
89
third-party/vendor/swc_ecma_loader/tests/tsc_resolver.rs
vendored
Normal file
89
third-party/vendor/swc_ecma_loader/tests/tsc_resolver.rs
vendored
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
#![cfg(feature = "tsc")]
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::{anyhow, Error};
|
||||
use swc_common::{collections::AHashMap, FileName};
|
||||
use swc_ecma_loader::{resolve::Resolve, resolvers::tsc::TsConfigResolver};
|
||||
|
||||
#[test]
|
||||
fn base_dir_exact() {}
|
||||
|
||||
#[test]
|
||||
fn base_dir_wildcard() {}
|
||||
|
||||
#[test]
|
||||
fn exact() {
|
||||
let mut map = HashMap::default();
|
||||
map.insert("jquery".to_string(), "fail".to_string());
|
||||
map.insert(
|
||||
"./node_modules/jquery/dist/jquery".to_string(),
|
||||
"success".to_string(),
|
||||
);
|
||||
let r = TsConfigResolver::new(
|
||||
TestResolver(map),
|
||||
".".into(),
|
||||
vec![(
|
||||
"jquery".into(),
|
||||
vec!["node_modules/jquery/dist/jquery".into()],
|
||||
)],
|
||||
);
|
||||
|
||||
{
|
||||
let resolved = r
|
||||
.resolve(&FileName::Anon, "jquery")
|
||||
.expect("should resolve");
|
||||
|
||||
assert_eq!(resolved, FileName::Custom("success".into()));
|
||||
}
|
||||
|
||||
{
|
||||
r.resolve(&FileName::Anon, "unrelated")
|
||||
.expect_err("should not touch error");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pattern_1() {
|
||||
let mut map = HashMap::default();
|
||||
map.insert("./folder1/file1".to_string(), "success-1".to_string());
|
||||
map.insert("./folder1/file2".to_string(), "success-2".to_string());
|
||||
map.insert(
|
||||
"./generated/folder2/file3".to_string(),
|
||||
"success-3".to_string(),
|
||||
);
|
||||
|
||||
let r = TsConfigResolver::new(
|
||||
TestResolver(map),
|
||||
".".into(),
|
||||
vec![("*".into(), vec!["*".into(), "generated/*".into()])],
|
||||
);
|
||||
|
||||
{
|
||||
let resolved = r
|
||||
.resolve(&FileName::Anon, "folder1/file2")
|
||||
.expect("should resolve");
|
||||
|
||||
assert_eq!(resolved, FileName::Custom("success-2".into()));
|
||||
}
|
||||
|
||||
{
|
||||
let resolved = r
|
||||
.resolve(&FileName::Anon, "folder2/file3")
|
||||
.expect("should resolve");
|
||||
|
||||
assert_eq!(resolved, FileName::Custom("success-3".into()));
|
||||
}
|
||||
}
|
||||
|
||||
struct TestResolver(AHashMap<String, String>);
|
||||
|
||||
impl Resolve for TestResolver {
|
||||
fn resolve(&self, _: &FileName, src: &str) -> Result<FileName, Error> {
|
||||
self.0
|
||||
.get(src)
|
||||
.cloned()
|
||||
.map(FileName::Custom)
|
||||
.ok_or_else(|| anyhow!("failed to resolve `{}`", src))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue