Skip to content

Commit

Permalink
fix(stylex_path_resolver): resolve path of pnpm installed package cor…
Browse files Browse the repository at this point in the history
…rectly
  • Loading branch information
Dwlad90 committed Nov 24, 2024
1 parent 3c46136 commit 9db57a9
Show file tree
Hide file tree
Showing 20 changed files with 223 additions and 50 deletions.
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/stylex-path-resolver/fixtures/application/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
"name": "appplication",
"version": "0.1.0",
"dependencies": {
"stylex-lib-pnpm": "*",
"@stylex/lib-exports-pnpm": "*",
"stylex-lib-dist-main": "*",
"stylex-lib-dist-exports-with-main": "*"
}
Expand Down
28 changes: 28 additions & 0 deletions crates/stylex-path-resolver/src/file_system/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use std::{
fs,
path::{Path, PathBuf},
};

pub(crate) fn _check_directory(path: &Path) -> bool {
match fs::metadata(path) {
Ok(metadata) => metadata.is_dir(),
Err(_) => false,
}
}

pub(crate) fn get_directories(path: &Path) -> Result<Vec<PathBuf>, std::io::Error> {
Ok(
fs::read_dir(path)?
.filter_map(|entry| {
entry.ok().and_then(|e| {
let path = e.path();
if path.is_dir() {
Some(path)
} else {
None
}
})
})
.collect::<Vec<_>>(),
)
}
1 change: 1 addition & 0 deletions crates/stylex-path-resolver/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod file_system;
mod package_json;
pub mod resolvers;
mod utils;
Expand Down
8 changes: 4 additions & 4 deletions crates/stylex-path-resolver/src/package_json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ pub struct PackageJsonExtended {
}

pub(crate) fn get_package_json(path: &Path) -> (PackageJsonExtended, PackageJsonManager) {
let (package_json_content, manager) = get_package_json_path(path);
let (package_json_path, manager) = get_package_json_path(path);

match package_json_content {
match package_json_path {
Some(file) => {
let data = read_to_string(file.display().to_string().as_str());

Expand Down Expand Up @@ -83,11 +83,11 @@ pub(crate) fn resolve_package_from_package_json(
resolver: &NodeModulesResolver,
file_name: &FileName,
import_path_str: &str,
) -> Option<(swc_core::ecma::loader::resolve::Resolution, String)> {
) -> Option<swc_core::ecma::loader::resolve::Resolution> {
const PATH_SEPARATOR: char = '/';

if let Some(parent) = get_node_modules_path(resolver, file_name, import_path_str) {
return Some((parent, import_path_str.to_string()));
return Some(parent);
}

let parts: Vec<&str> = import_path_str.split(PATH_SEPARATOR).collect();
Expand Down
126 changes: 90 additions & 36 deletions crates/stylex-path-resolver/src/resolvers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ use swc_core::{
use std::fs;

use crate::{
file_system::get_directories,
package_json::{
find_nearest_package_json, get_package_json, get_package_json_with_deps,
resolve_package_from_package_json,
resolve_package_from_package_json, PackageJsonExtended,
},
utils::{contains_subpath, relative_path},
};
Expand Down Expand Up @@ -258,7 +259,7 @@ pub fn resolve_file_path(
root_path: &str,
aliases: &FxHashMap<String, Vec<String>>,
) -> std::io::Result<PathBuf> {
let source_dir = Path::new(source_file_path).parent().unwrap();
let source_file_dir = Path::new(source_file_path).parent().unwrap();
let root_path = Path::new(root_path);

let cwd = if cfg!(feature = "wasm") {
Expand All @@ -270,7 +271,7 @@ pub fn resolve_file_path(
let cwd_path = Path::new(cwd);

let resolved_file_paths: Vec<PathBuf> = if import_path_str.starts_with('.') {
vec![resolve_path(&source_dir.join(import_path_str), root_path).into()]
vec![resolve_path(&source_file_dir.join(import_path_str), root_path).into()]
} else if import_path_str.starts_with('/') {
vec![root_path.join(import_path_str)]
} else {
Expand All @@ -280,37 +281,47 @@ pub fn resolve_file_path(
.map(PathBuf::from)
.collect::<Vec<PathBuf>>();

if let Some((package_resolution, name)) =
find_node_modules_resolution(cwd_path, import_path_str)
if let Ok(mut resolved_node_modules_path_buf) =
resolve_node_modules_path_buff(cwd_path, import_path_str)
{
if let FileName::Real(resolved_node_modules_path_buf) = package_resolution.filename {
let (package_json, _) = get_package_json(&resolved_node_modules_path_buf);

let potential_import_path_segment = import_path_str.split(&name).last().unwrap_or_default();

let import_path_segment = if potential_import_path_segment.is_empty() {
name
} else {
potential_import_path_segment.to_string()
};

let mut potential_package_path = String::default();

if let Some(exports) = &package_json.exports {
resolve_package_json_exports(
&import_path_segment,
exports,
&mut potential_package_path,
&resolved_node_modules_path_buf,
);
}
let (mut package_json, _) = get_package_json(&resolved_node_modules_path_buf);

if !potential_package_path.is_empty() {
aliased_file_paths.push(Path::new(&potential_package_path).to_path_buf().clean());
}
let package_name = package_json.name.clone();

aliased_file_paths.push(resolved_node_modules_path_buf.clean());
if let Some((pnpm_package_json, pnpm_package_path)) =
resolve_package_with_pnpm_path(source_file_dir, &package_name, import_path_str)
{
package_json = pnpm_package_json;
resolved_node_modules_path_buf = pnpm_package_path;
}

let potential_import_path_segment = import_path_str
.split(&package_name)
.last()
.unwrap_or_default();

let import_path_segment = if potential_import_path_segment.is_empty() {
package_name
} else {
potential_import_path_segment.to_string()
};

let mut potential_package_path = String::default();

if let Some(exports) = &package_json.exports {
resolve_package_json_exports(
&import_path_segment,
exports,
&mut potential_package_path,
&resolved_node_modules_path_buf,
);
}

if !potential_package_path.is_empty() {
aliased_file_paths.push(Path::new(&potential_package_path).to_path_buf().clean());
}

aliased_file_paths.push(resolved_node_modules_path_buf.clean());
}

aliased_file_paths.push(Path::new("node_modules").join(import_path_str));
Expand Down Expand Up @@ -364,15 +375,58 @@ pub fn resolve_file_path(
))
}

fn find_node_modules_resolution(
cwd: &Path,
fn resolve_package_with_pnpm_path(
source_file_dir: &Path,
package_name: &String,
import_path_str: &str,
) -> Option<(swc_core::ecma::loader::resolve::Resolution, String)> {
let (resolver, _) = get_package_json_with_deps(cwd);
) -> Option<(PackageJsonExtended, PathBuf)> {
let nearest_package_json_path = find_nearest_package_json(&PathBuf::from(source_file_dir));
if let Some(nearest_package_json_directory) = nearest_package_json_path {
if let Ok(directories) =
get_directories(&nearest_package_json_directory.join("node_modules/.pnpm"))
{
let normalized_name = if package_name.starts_with('@') {
package_name.replace('/', "+")
} else {
package_name.to_string()
};

let file_name = FileName::Real(cwd.to_path_buf());
for path in directories.iter() {
if path.to_string_lossy().contains(&normalized_name) {
if let Ok(resolved_node_modules_path_buff) =
resolve_node_modules_path_buff(path, import_path_str)
{
let (package_json, _) = get_package_json(path);

return Some((package_json, resolved_node_modules_path_buff));
};
}
}
}
};

None
}

resolve_package_from_package_json(&resolver, &file_name, import_path_str)
fn resolve_node_modules_path_buff(
path: &Path,
import_path_str: &str,
) -> Result<PathBuf, std::io::Error> {
let (resolver, _) = get_package_json_with_deps(path);

if let Some(package_resolution) = resolve_package_from_package_json(
&resolver,
&FileName::Real(path.to_path_buf()),
import_path_str,
) {
if let FileName::Real(resolved_node_modules_path_buf) = package_resolution.filename {
return Ok::<PathBuf, std::io::Error>(resolved_node_modules_path_buf);
}
}
Result::Err(std::io::Error::new(
std::io::ErrorKind::NotFound,
"File not found",
))
}

fn possible_aliased_paths(
Expand Down
61 changes: 61 additions & 0 deletions crates/stylex-path-resolver/src/resolvers/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,67 @@ mod resolve_path_tests {
);
}

#[test]
fn resolve_package_with_pnpm_path() {
let test_path = PathBuf::from("application");

let import_path_str = "stylex-lib-pnpm";
let source_file_path = format!(
"{}/src/pages/home.js",
get_root_dir(&test_path).as_path().display()
);
let ext = ".js";
let root_path = get_root_dir(&test_path).display().to_string();
let aliases = FxHashMap::default();

let expected_result =
"node_modules/.pnpm/stylex-lib-pnpm@0.1.0/node_modules/stylex-lib-pnpm/dist/index.jsx";

assert_eq!(
resolve_file_path(
import_path_str,
source_file_path.as_str(),
ext,
root_path.as_str(),
&aliases,
)
.unwrap_or_default()
.display()
.to_string(),
expected_result
);
}

#[test]
fn resolve_organisation_package_with_pnpm_path() {
let test_path = PathBuf::from("application");

let import_path_str = "@stylex/lib-exports-pnpm/dist/colors.stylex";
let source_file_path = format!(
"{}/src/pages/home.js",
get_root_dir(&test_path).as_path().display()
);
let ext = ".js";
let root_path = get_root_dir(&test_path).display().to_string();
let aliases = FxHashMap::default();

let expected_result = "node_modules/.pnpm/@stylex+lib-exports-pnpm@0.1.0/node_modules/@stylex/lib-exports-pnpm/dist/colors.stylex.js";

assert_eq!(
resolve_file_path(
import_path_str,
source_file_path.as_str(),
ext,
root_path.as_str(),
&aliases,
)
.unwrap_or_default()
.display()
.to_string(),
expected_result
);
}

#[test]
fn get_import_path_when_no_aliases() {
assert_eq!(
Expand Down
5 changes: 0 additions & 5 deletions crates/stylex-rs-compiler/dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@

/* auto-generated by NAPI-RS */

export interface TransformOutput {
code: string
map?: string
output?: string
}
export interface StyleXModuleResolution {
type: string
rootDir?: string
Expand Down

0 comments on commit 9db57a9

Please sign in to comment.