Reputation: 6805
I have a project that I work on with two different laptops. Sometimes I add extra packages to my project, so I have to use npm install <package-name>
(duh). When I do that, I git push
up the new package.json
and package-lock.json
files, and when I switch computers I have to git pull
those changes, then run npm install
again to get that package onto the other computer.
I recently noticed and started caring that one laptop kept adding carets (^
) to the beginning of every package version number. For example:
One computer set package version #s to look like this:
"regexpu-core": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
"integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
"requires": {
"regenerate": "1.4.0",
"regjsgen": "0.2.0",
"regjsparser": "0.1.5"
}
},
The other set package version #s to look like this:
"regexpu-core": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
"integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
"requires": {
"regenerate": "^1.2.1",
"regjsgen": "^0.2.0",
"regjsparser": "^0.1.4"
}
},
I understand that carets (^
) mean the version is not 100% precise, but I'm trying to figure out WHY my different laptops create different formats for package versions! I checked this SO question which has some great explanations for the differences between ~
and ^
, but I didn't find anything explaining why npm
would sometimes add and sometimes remove carets (^
) altogether. I also looked at this npm issue on Github which recommended looking at npm
config settings, but both of my laptops have the same settings:
npm config get save
= true
(both computers)npm config get save-prefix
= ^
(both computers)npm config get save-exact
= false
(both computers)One laptop was running npm
version 5.6.0
, but I just updated it to 6.5.0
. The other computer was running version 6.4.1
, but I also updated it to 6.5.0
. I tried running npm install
in my project on both computers, but still I find that one computer always removes ^
and the other always adds ^
.
Please let me know if there's something I'm missing. Thanks for any help!
Upvotes: 9
Views: 7142
Reputation: 25032
Edit: According to the discussion in issue #20434 this occurs by design using npm >=6.0.0
.
Why does this happen? @rarkins elaborately explains the reasoning for why this happens (and it’s advantages) in this comment. For convenience his comment is quoted below (verbatim):
Let's say that you use pinned versions of dependencies 'aaa', 'bbb' and 'ccc'. Let's say they each depend on 'zzz' like so:
- aaa depends on zzz@^1.0.0
- bbb depends on zzz@^1.1.0
- ccc depends on zzz@^1.0.1
i.e. all three of them depend on a range of zzz, and not an exact version.
And let's say that the latest version of zzz is 1.5.0.
Both before and after this change, it's pretty obvious that the resolved version of zzz should be 1.5.0, so the only difference is how the
package-lock.json
is structured and documents this sub-dependency.Before, the lock file would show that all three of them depend on [email protected], and the resolved version of z is 1.5.0.
Now, it documents the actual "original" dependency versions (e.g. ^1.0.0, ^1.1.0, etc) for each dependency, but still shows the resolved version of z as 1.5.0.
Then consider what happens when [email protected] is released:
Before, the lock file would need to update from [email protected] to [email protected] in all four places.
Now, the lock file only needs to update the resolved version of z to 1.5.1 while the dependencies can keep the ^1.0.0, ^1.1.0, and ^1.0.1 because they haven't changed.
As I mentioned previously in the thread, you still get the exact same node_modules in both cases. The advantages of the new approach are:
You get to see what the dependencies actually require (e.g. a range, and not an exact version). before, you could not tell if aaa actually required exactly [email protected] or that it was instead zzz@^1.0.0.
Instead of four lines changing in the lock file, you get only one. It's less churn, and it's more clear what's happened.
As an aside,
yarn
uses a similar concept withyarn.lock
. e.g. here's an example where@sindresorhus/is
is pinned, but it's sub-dependency symbol-observable is not:"@sindresorhus/[email protected]": version "0.10.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.10.0.tgz#f42dd6a9d12cd79fa6f53b27cf5bea3a30d2cafa" dependencies: symbol-observable "^1.2.0"
Original Answer:
After you git pull
the revised package.json and package-lock.json onto computer two try deleting the node_modules directory before installing the packages again.
For example:
Firstly cd
to your project directory on computer 2.
Delete the existing node_modules directory by running: rm -rf node_modules
.
Then run: npm install
Or you can chain the two aforementioned commands using the &&
operator:
rm -rf node_modules && npm install
Upvotes: 3