mirror of
https://github.com/hanzoai/unrs-resolver.git
synced 2026-09-24 17:03:52 +00:00
240 lines
8.5 KiB
Rust
240 lines
8.5 KiB
Rust
//! Test resolving real-world packages from pnpm node_modules.
|
|
|
|
use std::{env, path::PathBuf};
|
|
|
|
use unrs_resolver::{ModuleType, ResolveError, ResolveOptions, Resolver};
|
|
|
|
fn dir() -> PathBuf {
|
|
env::current_dir().unwrap()
|
|
}
|
|
|
|
#[test]
|
|
fn styled_components() {
|
|
let dir = dir();
|
|
let path = dir.join("fixtures/pnpm");
|
|
let module_path = dir
|
|
.join("node_modules")
|
|
.join(".pnpm")
|
|
.join("[email protected][email protected][email protected][email protected]")
|
|
.join("node_modules")
|
|
.join("styled-components");
|
|
let specifier = "styled-components";
|
|
|
|
// cjs
|
|
let options =
|
|
ResolveOptions { alias_fields: vec![vec!["browser".into()]], ..ResolveOptions::default() };
|
|
let resolution = Resolver::new(options).resolve(&path, specifier);
|
|
assert_eq!(
|
|
resolution.map(unrs_resolver::Resolution::into_path_buf),
|
|
Ok(module_path.join("dist").join("styled-components.browser.cjs.js"))
|
|
);
|
|
|
|
// esm
|
|
let options = ResolveOptions {
|
|
alias_fields: vec![vec!["browser".into()]],
|
|
main_fields: vec!["module".into()],
|
|
..ResolveOptions::default()
|
|
};
|
|
let resolution = Resolver::new(options).resolve(&path, specifier);
|
|
assert_eq!(
|
|
resolution.map(unrs_resolver::Resolution::into_path_buf),
|
|
Ok(module_path.join("dist").join("styled-components.browser.esm.js"))
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn axios() {
|
|
let dir = dir();
|
|
let path = dir.join("fixtures/pnpm");
|
|
let module_path = dir.join("node_modules/.pnpm/[email protected]/node_modules/axios");
|
|
let specifier = "axios";
|
|
|
|
// default
|
|
let options = ResolveOptions::default();
|
|
let resolution = Resolver::new(options).resolve(&path, specifier);
|
|
assert_eq!(
|
|
resolution.map(unrs_resolver::Resolution::into_path_buf),
|
|
Ok(module_path.join("index.js"))
|
|
);
|
|
|
|
// browser
|
|
let options = ResolveOptions {
|
|
condition_names: vec!["browser".into(), "require".into()],
|
|
..ResolveOptions::default()
|
|
};
|
|
let resolution = Resolver::new(options).resolve(&path, specifier);
|
|
assert_eq!(
|
|
resolution.map(unrs_resolver::Resolution::into_path_buf),
|
|
Ok(module_path.join("dist/browser/axios.cjs"))
|
|
);
|
|
|
|
// cjs
|
|
let options = ResolveOptions {
|
|
condition_names: vec!["node".into(), "require".into()],
|
|
..ResolveOptions::default()
|
|
};
|
|
let resolution = Resolver::new(options).resolve(&path, specifier);
|
|
assert_eq!(
|
|
resolution.map(unrs_resolver::Resolution::into_path_buf),
|
|
Ok(module_path.join("dist/node/axios.cjs"))
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn postcss() {
|
|
let dir = dir();
|
|
let path = dir.join("fixtures/pnpm");
|
|
let module_path = path.join("node_modules/postcss");
|
|
let resolver = Resolver::new(ResolveOptions {
|
|
alias_fields: vec![vec!["browser".into()]],
|
|
symlinks: false,
|
|
..ResolveOptions::default()
|
|
});
|
|
|
|
// should ignore "path"
|
|
let resolution = resolver.resolve(&module_path, "path");
|
|
assert_eq!(resolution, Err(ResolveError::Ignored(module_path.clone())));
|
|
|
|
// should ignore "./lib/terminal-highlight"
|
|
let resolution = resolver.resolve(&module_path, "./lib/terminal-highlight");
|
|
assert_eq!(resolution, Err(ResolveError::Ignored(module_path.join("lib/terminal-highlight"))));
|
|
}
|
|
|
|
#[test]
|
|
fn ipaddr_js() {
|
|
let dir = dir();
|
|
let path = dir.join("fixtures/pnpm");
|
|
let module_path =
|
|
dir.join("node_modules/.pnpm/[email protected]/node_modules/ipaddr.js/lib/ipaddr.js");
|
|
|
|
let resolvers = [
|
|
// with `extension_alias`
|
|
Resolver::new(ResolveOptions {
|
|
extension_alias: vec![(".js".into(), vec![".js".into(), ".ts".into(), ".tsx".into()])],
|
|
..ResolveOptions::default()
|
|
}),
|
|
// with `extensions` should still resolve to module main
|
|
Resolver::new(ResolveOptions {
|
|
extensions: vec![(".ts".into())],
|
|
..ResolveOptions::default()
|
|
}),
|
|
// default
|
|
Resolver::default(),
|
|
];
|
|
|
|
for resolver in resolvers {
|
|
let resolution = resolver.resolve(&path, "ipaddr.js").map(|r| r.full_path());
|
|
assert_eq!(resolution, Ok(module_path.clone()));
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn decimal_js() {
|
|
let dir = dir();
|
|
let path = dir.join("fixtures/pnpm");
|
|
let module_path =
|
|
dir.join("node_modules/.pnpm/[email protected]/node_modules/decimal.js/decimal.mjs");
|
|
|
|
let resolvers = [
|
|
// with `extension_alias`
|
|
Resolver::new(ResolveOptions {
|
|
extension_alias: vec![(".js".into(), vec![".js".into(), ".ts".into(), ".tsx".into()])],
|
|
condition_names: vec!["import".into()],
|
|
..ResolveOptions::default()
|
|
}),
|
|
// default
|
|
Resolver::new(ResolveOptions {
|
|
condition_names: vec!["import".into()],
|
|
..ResolveOptions::default()
|
|
}),
|
|
];
|
|
|
|
for resolver in resolvers {
|
|
let resolution = resolver.resolve(&path, "decimal.js").map(|r| r.full_path());
|
|
assert_eq!(resolution, Ok(module_path.clone()));
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn decimal_js_from_mathjs() {
|
|
let dir = dir();
|
|
let path = dir.join("node_modules/.pnpm/[email protected]/node_modules/mathjs/lib/esm");
|
|
let module_path =
|
|
dir.join("node_modules/.pnpm/[email protected]/node_modules/decimal.js/decimal.mjs");
|
|
|
|
let resolvers = [
|
|
// with `extension_alias`
|
|
Resolver::new(ResolveOptions {
|
|
extension_alias: vec![(".js".into(), vec![".js".into(), ".ts".into(), ".tsx".into()])],
|
|
condition_names: vec!["import".into()],
|
|
..ResolveOptions::default()
|
|
}),
|
|
// default
|
|
Resolver::new(ResolveOptions {
|
|
condition_names: vec!["import".into()],
|
|
..ResolveOptions::default()
|
|
}),
|
|
];
|
|
|
|
for resolver in resolvers {
|
|
let resolution = resolver.resolve(&path, "decimal.js").map(|r| r.full_path());
|
|
assert_eq!(resolution, Ok(module_path.clone()));
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn minimatch() {
|
|
let dir = dir();
|
|
let path = dir.join("fixtures/pnpm");
|
|
let esm_resolver = Resolver::new(ResolveOptions {
|
|
condition_names: vec!["import".into()],
|
|
module_type: true,
|
|
..ResolveOptions::default()
|
|
});
|
|
let resolution = esm_resolver.resolve(&path, "minimatch").unwrap();
|
|
assert_eq!(
|
|
resolution.full_path(),
|
|
dir.join("node_modules/.pnpm/[email protected]/node_modules/minimatch/dist/esm/index.js")
|
|
);
|
|
assert_eq!(resolution.module_type(), Some(ModuleType::Module));
|
|
|
|
let cjs_resolver = esm_resolver.clone_with_options(ResolveOptions {
|
|
condition_names: vec!["require".into()],
|
|
module_type: true,
|
|
..ResolveOptions::default()
|
|
});
|
|
let resolution = cjs_resolver.resolve(&path, "minimatch").unwrap();
|
|
assert_eq!(
|
|
resolution.full_path(),
|
|
dir.join(
|
|
"node_modules/.pnpm/[email protected]/node_modules/minimatch/dist/commonjs/index.js"
|
|
)
|
|
);
|
|
assert_eq!(resolution.module_type(), Some(ModuleType::CommonJs));
|
|
}
|
|
|
|
// NOTE: pnpm v10 shortens windows directory path.
|
|
// `virtualStoreDirMaxLength: 1024` is set in pnpm-workspace.yaml to keep the long name.
|
|
#[test]
|
|
fn windows_symlinked_longfilename() {
|
|
let dir = dir();
|
|
let path = dir.join("fixtures/pnpm");
|
|
let module_path = dir.join("node_modules")
|
|
.join(".pnpm")
|
|
.join("@oxc-resolver+test-longfilename-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@file+fixtures+pnpm+longfilename")
|
|
.join("node_modules")
|
|
.join("@oxc-resolver")
|
|
.join("test-longfilename-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
|
|
.join("index.js");
|
|
|
|
// Note: dunce::canonicalize seems to only trim \\?\ when the path is shorter than 260 chars.
|
|
// Our implementation should mitigate that.
|
|
// <https://gitlab.com/kornelski/dunce/-/blob/1ee29a83526c9f4c3618e1335f0454c878a54dcf/src/lib.rs#L176-180>
|
|
assert!(module_path.as_os_str().len() > 260, "Windows path must be super long.");
|
|
|
|
let specifier = "@oxc-resolver/test-longfilename-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
|
let resolution =
|
|
Resolver::new(ResolveOptions::default()).resolve(&path, specifier).map(|r| r.full_path());
|
|
assert_eq!(resolution, Ok(module_path));
|
|
}
|