Does Lerna bump dependency versions when releasing new versions? - npm

If I have a monorepo with packageA and packageB, with the latter having a dependency on the former. If I then run lerna version major, for example, resulting in packageA's version number being bumped, does the listing of the dependency on it in packageB's package.json also get bumped automatically, or should that be done manually?
(I tried setting up a test repository to do this, but then Lerna was complaining it didn't have a remote yet, so I'm hoping someone with experience using Lerna knows the answer.)

For the sake of this answer, I'm going to assume you are not using conventional Commits. Please feel free to respond with more specifics if I assume wrong.
TL;DR
Yes, if you run lerna version major _all packages in your repo will be updated to a new major version and the package.json file for packageB will be updated with the new version number for packageA.
Details
Let's say you have your packageA and packageB packages in your monorepo and they have package.json files that look like this:
# packageA/package.json
{
"name": "packageA",
"version": "1.0.0,"
}
# packageB/package.json
{
"name": "packageB",
"version": "1.0.0",
"dependencies": {
"packageA": "^1.0.0"
}
}
When you run `lerna version major:
The version field in packageA/package.json will update to 2.0.0
The version field in packageB/package.json will update to 2.0.0
The dependencies.packageA field in packageB/package.json will update to ^2.0.0
# packageA/package.json
{
"name": "packageA",
"version": "2.0.0,"
}
# packageB/package.json
{
"name": "packageB",
"version": "2.0.0",
"dependencies": {
"packageA": "^2.0.0"
}
}

Related

Monorepo with npm workspaces - Lerna version fails when inter-package dependency is introduced for existing packages

I am working on a monorepo with 2 packages, say child and parent, initially not dependent on each other and already published to registry.
However, when I add inter-package dependency, lerna version command fails.
npm workspaces was provided in root package.json
useWorkspaces was provided in lerna.json
All was fine, till I decided to add package parent as dependency of package child.
packages/child/package.json was updated like so:
{
"name": "child",
"version": "0.1.13",
"description": "this package is being updated to depend on parent",
"main": "dist/index.js",
"dependencies": {
"parent": "*" // I added this
}
}
I had updates to both child and parent. Lets say published versions of parent was 0.2.13 and child was 0.1.13 prior to update.
npm install and the symlinks worked.
Build was successful.
During version however, after prompting for version bump with conventional-commits, lerna attempts npm install command and fails due to package parent version 0.2.14 being not available in npm remote registry.
It will not be available, as this version is going to be published only now.
On version command (i am using conventional-commits),
Lerna asked if parent -> 0.2.14 and child -> 0.1.14 was okay, it was..
Lerna updated the package.json of package child to be as follows:
{
"name": "child",
"version": "0.1.14", // lerna changed this
"description": "this package is being updated to depend on parent",
"main": "dist/index.js",
"dependencies": {
"parent": "^0.2.14" // lerna changed this
}
}
Lerna updated the package.json of package parent to be as follows:
{
"name": "parent",
"version": "0.2.14", // lerna changed this
"description": "this package will be dependency of child",
"main": "dist/index.js",
}
Lerna tried to do npm install on both child and parent packages
This fails with reason being package parent version 0.2.14 is not yet available to install, since its just going to be published now.
I followed this https://lerna.js.org/docs/getting-started.
It says
The "header": "*" and "footer": "*" tell Lerna to link the contents of the header and footer as if they were published to the registry.
I was expecting the lerna version command to work and create new version commit and tag as it was doing before I added inter-package dependencies using "*".
Should I be publishing parent first with new version 0.2.14 and then update child to point to this ?
If that is the case, should I always publish parent first whenever there are breaking changes. ?
What is the right way to do this ?
PS: Looks like it fails here: https://github.com/lerna/lerna/blob/main/commands/version/index.js#L634
Should I just remove package-lock.json from root ?

Is there a configuration where you can tell NPM to downgrade if package version isn't available?

If a package version, or peer dependency version is unavailable during an npm install, is it possible to configure NPM to ignore the version, and downgrade to the next lower version automatically (perhaps with a warning)?
No matching version found for #babel/generator#^7.18.9.
In most cases you or one of your dependencies are requesting
a package version that doesn't exist.
However, it exists here. While this is a issue probably for babel, we run a private npm-read-group that updates only every few hours, and it can be an issue when downloading packages that have just been updated.
As long as I know you should define "latest" as value. For example:
{
"name": "name",
"private": true,
"description": "",
"dependencies": {
"lodash": "latest"
}
}
I do not recommend doing this, but it should work for what you wish.

Does a published artifact affect npm install?

I have a private, unpublished NPM package. Let's say it's named foo-test:
{
"name": "foo-test",
"version": "0.0.0",
"license": "MIT",
"private": true,
"scripts": {...},
"dependencies": {...}
}
It's not in the NPM registry, and I've marked it private.
I found out via a security audit that this is "vulnerable to dependency confusion attacks", but I don't know how.
If someone later comes along and publishes a real public package called foo-test to the NPM registry, will that affect my local development against my private package?
That is, let's say there's a real package foo-test#1.0.0 available on npmjs. If I run npm install locally against my own unrelated version of foo-test, will there be any side effects arising from the fact that the local package that I'm building has the same name as a public package on the registry?

How to update the dependency of one package which is in package-lock.json

We want to update the lodash version to 4.17.11 but it is dependency of grunt-angular-translate . grunt-angular-translate is in package.json . If i am updating the grunt-angular-translate to 0.3.0 it is not updating the lodash to version 4.7.11 .How can we update the dependency which is in package-lock.json.
package.json:
"devDependencies": {
"grunt": "^1.0.3",
"grunt-angular-translate": "^1.0.0",
"grunt-bump": "^0.8.0",
package-lock.json:
"grunt-angular-translate": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/grunt-angular-translate/-/grunt-angular-translate-0.3.0.tgz",
"integrity": "sha1-vQEYr6JNj1cCMf2NUtgp2AjFEbM=",
"dev": true,
"requires": {
"flat": "^1.2.0",
"json-stable-stringify": "^1.0.0",
"lodash": "~2.4.1"
},
"dependencies": {
"lodash": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
"integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
"dev": true
}
}
},
As per npm docs:
package-lock.json is automatically generated for any operations where
npm modifies either the node_modules tree, or package.json. It
describes the exact tree that was generated, such that subsequent
installs are able to generate identical trees, regardless of
intermediate dependency updates.
This file is intended to be committed into source repositories, and
serves various purposes:
Describe a single representation of a dependency tree such that
teammates, deployments, and continuous integration are guaranteed to
install exactly the same dependencies.
Provide a facility for users to “time-travel” to previous states of
node_modules without having to commit the directory itself.
To facilitate greater visibility of tree changes through readable
source control diffs.
And optimize the installation process by allowing npm to skip repeated
metadata resolutions for previously-installed packages.
In package.json you specify which npm packages you are utilizing in your app. In other words on which you have a specific dependency so your package can function.
package-lock.json is a big "map" of each of the packages your app uses and their dependencies which you can not impact.
In your case grunt-angular-translate has its own dependency on "lodash": "~2.4.1" and you can not change it and should not try to since that package is supposed to work with that version and not with 2 versions higher package where there may be a bunch of breaking changes.
You can upgrade your direct dependency of lodash to its latest version but that would not update grunt-angular-translate dependency to lodash to that version and it really should not.
What should really happen is in your node_modules folder you will get your updated lodash (and you can check by looking at its package.json and the version inside). In that same folder if you go into the grunt-angular-translate folder and look at its own node_modules ... it should have its own lodash folder with lodash 2.4.1 in it.

How to install certain dependencies in package.json

I am trying to optimize my CI build step. I want to install certain dependencies before installing others. How can I achieve that?
For example, suppose my package.json file is:
{
"name": "my-project",
"version": "1.0.0",
"author": "krismath",
"dependencies": {
"lib-a": "^1.5.13",
"lib-b": "^0.7.2",
"lib-c": "^15.0.61"
}
I want to install lib-b first in order to use it in other build steps. If I do
npm install lib-b
this doesn't guarantee that the version of lib-b will be semantically compatible with the one in package.json.