Skip to content

Commit 4869fa7

Browse files
committed
Fix: Inject workspace-local package maps for island node-modules scripts
When scripts run from island workspaces using node-modules linker, NODE_OPTIONS now correctly points to the workspace-local package map (workspace/node_modules/.package-map.json) instead of the root package map. This ensures Node can resolve packages from the island's layout. The fix detects when a script's package is a workspace in an island with node-modules linker, removes any existing root package map from NODE_OPTIONS, and injects the workspace-local map path. Resolves bug where island maps were generated but never used by scripts, causing resolution failures in mixed PnP root + island node-modules setups.
1 parent 6e80271 commit 4869fa7

1 file changed

Lines changed: 34 additions & 0 deletions

File tree

packages/zpm/src/script.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,40 @@ impl ScriptEnvironment {
749749
self.binaries = self.binaries
750750
.with_package(&binaries, &project.project_cwd)?;
751751

752+
// If this package is a workspace in an island with node-modules linker,
753+
// update NODE_OPTIONS to use the workspace-local package map instead of
754+
// the root package map.
755+
if project.config.settings.node_experimental_package_map.value {
756+
if let Ok(workspace) = project.workspace_by_ident(&locator.ident) {
757+
let in_nm_island = project.config.settings.unstable_islands
758+
.values()
759+
.any(|island| {
760+
island.linker.value == zpm_config::IslandLinker::NodeModules
761+
&& island.workspaces.iter().any(|glob| glob.value.check(&workspace.name))
762+
});
763+
764+
if in_nm_island {
765+
let workspace_package_map_path = workspace.path
766+
.with_join_str("node_modules")
767+
.with_join_str(crate::project::PACKAGE_MAP_NAME);
768+
769+
if workspace_package_map_path.if_exists().is_some() {
770+
// Remove any existing package-map option from NODE_OPTIONS
771+
if let Some(Some(node_options)) = self.env.get_mut("NODE_OPTIONS") {
772+
let updated = PACKAGE_MAP_MATCHER.replace_all(node_options, "").to_string();
773+
*node_options = updated;
774+
}
775+
776+
// Add the workspace-local package map
777+
self.append_env("NODE_OPTIONS", ' ', &format!(
778+
"--experimental-package-map={}",
779+
quote_path_if_needed(&workspace_package_map_path.to_file_string())
780+
));
781+
}
782+
}
783+
}
784+
}
785+
752786
Ok(self)
753787
}
754788

0 commit comments

Comments
 (0)