-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix-npm --workspaces does not update the dependencies
- Loading branch information
1 parent
780afc5
commit 2abe05a
Showing
2 changed files
with
52 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,74 @@ | ||
'use strict' | ||
|
||
const reifyFinish = require('../utils/reify-finish.js') | ||
const fs = require('fs') | ||
const path = require('path') | ||
const Arborist = require('@npmcli/arborist') | ||
|
||
async function updateWorkspaces ({ | ||
config, | ||
flatOptions, | ||
localPrefix, | ||
npm, | ||
workspaces, | ||
}) { | ||
if (!flatOptions.workspacesUpdate || !workspaces.length) { | ||
return | ||
} | ||
|
||
// default behavior is to not save by default in order to avoid | ||
// race condition problems when publishing multiple workspaces | ||
// that have dependencies on one another, it might still be useful | ||
// in some cases, which then need to set --save | ||
const save = config.isDefault('save') | ||
? false | ||
: config.get('save') | ||
// collect updated workspace package versions | ||
const workspacePackages = new Map() | ||
|
||
// runs a minimalistic reify update, targeting only the workspaces | ||
// that had version updates and skipping fund/audit/save | ||
// get the updated versions of workspace packages | ||
for (const [, workspacePath] of workspaces) { | ||
const pkgPath = path.join(workspacePath, 'package.json') | ||
const pkgData = await fs.promises.readFile(pkgPath, 'utf8') | ||
const pkg = JSON.parse(pkgData) | ||
workspacePackages.set(pkg.name, pkg.version) | ||
} | ||
|
||
// update dependencies in all workspace packages | ||
for (const [, workspacePath] of workspaces) { | ||
const pkgPath = path.join(workspacePath, 'package.json') | ||
const pkgData = await fs.promises.readFile(pkgPath, 'utf8') | ||
const pkg = JSON.parse(pkgData) | ||
|
||
// list of dependency fields to update | ||
const depFields = [ | ||
'dependencies', | ||
'devDependencies', | ||
'peerDependencies', | ||
'optionalDependencies', | ||
] | ||
|
||
let updated = false | ||
|
||
for (const field of depFields) { | ||
if (pkg[field]) { | ||
for (const depName of Object.keys(pkg[field])) { | ||
if (workspacePackages.has(depName)) { | ||
// update the version spec to match the new version | ||
pkg[field][depName] = workspacePackages.get(depName) | ||
updated = true | ||
} | ||
} | ||
} | ||
} | ||
|
||
if (updated) { | ||
// write the updated package.json back to disk | ||
const updatedPkgData = JSON.stringify(pkg, null, 2) + '\n' | ||
await fs.promises.writeFile(pkgPath, updatedPkgData, 'utf8') | ||
} | ||
} | ||
|
||
// after done with updating package.json files, use arborist.reify() to update node_modules | ||
const opts = { | ||
...flatOptions, | ||
audit: false, | ||
fund: false, | ||
path: localPrefix, | ||
save, | ||
save: false, // since the package.json is already updated, so no need to save changes again | ||
} | ||
const Arborist = require('@npmcli/arborist') | ||
const arb = new Arborist(opts) | ||
|
||
await arb.reify({ ...opts, update: workspaces }) | ||
await reifyFinish(npm, arb) | ||
await arb.reify() | ||
} | ||
|
||
module.exports = updateWorkspaces |