npm / cli

the package manager for JavaScript
https://docs.npmjs.com/cli/
Other
8.52k stars 3.19k forks source link

fix-npm --workspaces does not update the dependencies #7903

Open kchindam-infy opened 2 weeks ago

kchindam-infy commented 2 weeks ago

This PR addresses an issue where running npm version --workspaces updates the version fields in the package.json files of workspace packages but does not update the internal dependencies (dependencies, devDependencies, etc.) that reference other workspace packages.

Background

In npm workspaces, it's expected that updating the version of workspace packages should also update internal dependencies to match the new version numbers. This ensures consistency across the monorepo and prevents potential issues during installation, publishing, or runtime.

Previously, issue #3403 highlighted this problem, and although a fix was attempted, the issue persists as reported in issue #7843.

Problem with the Current Implementation

Reliance on arborist.reify(): The existing updateWorkspaces function relies on arborist.reify() to update workspaces. However, reify focuses on aligning the node_modules directory with the package tree defined by package.json and package-lock.json, and does not modify the dependencies fields in package.json.

save Option Set to false: The save option is set to false by default to prevent potential race conditions when publishing multiple workspaces. This means that even if reify could update package.json, it would not do so because save is false.

Resulting Issue: As a result, internal dependencies remain pointing to old versions after a version bump, leading to inconsistencies within the workspace.

Solution

To resolve this issue, I've modified the updateWorkspaces function to directly update the package.json files of workspace packages, ensuring that internal dependencies are updated to match the new version numbers.

Changes Made

Modified lib/commands/version.js

Updated changeWorkspaces Method:

Changed the way updated workspaces are collected by including both the package name and its path: updatedWorkspaces.push([name, path]) This provides the necessary information to locate and update each package.json file. Passed Detailed Workspace Information:

The updateWorkspaces function now receives the updatedWorkspaces array containing both names and paths. Updated lib/utils/update-workspaces.js

Removed Reliance on arborist.reify():

Instead of relying on reify, which does not update package.json dependencies, the function now directly reads and writes to package.json files.

Implemented Direct File Manipulation:

Reads Each package.json: Uses fs.promises.readFile to read the contents of each workspace's package.json. Updates Internal Dependencies: Iterates over the dependency fields (dependencies, devDependencies, peerDependencies, optionalDependencies). Checks if any dependencies are workspace packages that have been version-bumped. Updates the version specifier to the new version. Writes Changes Back to Disk: Uses fs.promises.writeFile to save the updated package.json files. Optionally Integrated arborist.reify() to Update node_modules

After updating the package.json files, arborist.reify() is called to update the node_modules directories to match the new dependencies.

This PR provides solution to ensure that npm version --workspaces updates both the version fields and the internal dependencies in package.json files of workspace packages. By directly manipulating the package.json files and updating node_modules and maintain consistency across the workspace and prevent potential issues arising from outdated internal dependencies.

This change resolves the issue reported in Issue #7843 and aligns with the expected behavior discussed in Issue #3403.

References

Related to #7843 Depends on #3403 Blocked by #0 Fixes #7843 Closes #7843