When to use package-lock.json and shrinkwrap.json [duplicate] - json

With the release of npm#5, it will now write a package-lock.json unless a npm-shrinkwrap.json already exists.
I installed npm#5 globally via:
npm install npm#5 -g
And now, if a npm-shrinkwrap.json is found during:
npm install
a warning will be printed:
npm WARN read-shrinkwrap This version of npm
is compatible with lockfileVersion#1,
but npm-shrinkwrap.json was generated for lockfileVersion#0.
I'll try to do my best with it!
So my take-away is that I should replace the shrinkwrap with the package-lock.json.
Yet why is there a new format for it? What can the package-lock.json do that the npm-shrinkwrap.json cannot?

The files have exactly the same content, but there are a handful of differences in how npm handles them, most of which are noted on the docs pages for package-lock.json and npm-shrinkwrap.json:
package-lock.json is never published to npm, whereas npm-shrinkwrap is by default
package-lock.json files that are not in the top-level package are ignored, but shrinkwrap files belonging to dependencies are respected
npm-shrinkwrap.json is backwards-compatible with npm versions 2, 3, and 4, whereas package-lock.json is only recognized by npm 5+
You can convert an existing package-lock.json to an npm-shrinkwrap.json by running npm shrinkwrap.
Thus:
If you are not publishing your package to npm, the choice between these two files is of little consequence. You may wish to use package-lock.json because it is the default and its name is clearer to npm beginners; alternatively, you may wish to use npm-shrinkwrap.json for backwards compatibility with npm 2-4 if it is difficult for you to ensure everyone on your development team is on npm 5+. (Note that npm 5 was released on 25th May 2017; backwards compatibility will become less and less important the further we get from that date, as most people will eventually upgrade.)
If you are publishing your package to npm, you have a choice between:
using a package-lock.json to record exactly which versions of dependencies you installed, but allowing people installing your package to use any version of the dependencies that is compatible with the version ranges dictated by your package.json, or
using an npm-shrinkwrap.json to guarantee that everyone who installs your package gets exactly the same version of all dependencies
The official view described in the docs is that option 1 should be used for libraries (presumably in order to reduce the amount of package duplication caused when lots of a package's dependencies all depend on slightly different versions of the same secondary dependency), but that option 2 might be reasonable for executables that are going to be installed globally.

Explanation from NPM Developer:
The idea is definitely for package-lock.json to be the Latest and
Greatest in shrinkwrap technology, and npm-shrinkwrap.json to be
reserved for those precious few folks out there who care very much
about their libraries having an exact node_modules -- and for people
who want CI using npm#>=2 to install a particular tree without having
to bump its npm version.
The new lockfile ("package-lock.json") shares basically all of the
same code, the exact same format as npm-shrinkwrap (you can rename
them between one another!). It's also something the community seems to
understand: "it has a lockfile" seems to click so much faster with
people. Finally, having a new file meant that we could have relatively
low-risk backwards-compat with shrinkwrap without having to do weird
things like allow-publication mentioned in the parent post.

I think the idea was to have --save and shrinkwrap happen by default but avoid any potential issues with a shrinkwrap happening where it wasn't wanted. So, they just gave it a new file name to avoid any conflicts. Someone from npm explained it more thoroughly here:
https://www.reddit.com/r/javascript/comments/6dgnnq/npm_v500_released_save_by_default_lockfile_better/di3mjuk/
The relevant quote:
npm publishes most files in your source directory by default, and
people have been publishing shrinkwraps for years. We didn't want to
break compatibility. With --save and shrinkwrap by default, there was
a great risk of it accidentally making it in and propagating through
the registry, and basically render our ability to update deps and
dedupe... null.
So we chose a new name. And we chose a new name kind of all of a
sudden. The new lockfile shares basically all of the same code, the
exact same format

package-lock.json versions are guaranteed with only npm ci (since npm install overwrites package-lock.json if there is a conflict with package.json).
npm-shrinkwrap.json versions are guaranteed with both npm ci and npm install.

Related

Why does Polymer 3.0 require the flat flag?

Not previously familiar with the flat flag, why is it required for a Polymer 3.0 project?
Have searched the web for clues but only found brief hints that the flat flag should be avoided.
... This below from polymer-project's blog, why ?
Bower ➙ npm
Like HTML Imports, Bower has been with us for a long time. Bower's flat dependency tree is ideal for front-end projects. But Bower has never been as widely adopted as npm, and while it's still maintained, it's no longer being actively developed.
Moving to npm will make Polymer packages seamlessly available to the millions of npm users, and allow Polymer packages to easily use other packages from the massive npm ecosystem.
This has been a long requested feature, but we've been waiting until we had good solutions for supporting flat installs of modules and keeping Bower and npm packages in sync.
The Yarn npm client provides support for flat installs, which solves our #1 issue with npm.
After considering a number of approaches to keeping Bower and npm packages in sync, we concluded that maintaining parallel versions was impractical. So we're making a clean break at 3.x and moving to npm exclusively.

Possible to write versions in composer.json similar to npm update --save

Handed a project that has a composer.json that has all package versions listed as "*" and has no composer.lock file
In the original project, running composer show, tells me all versions of everything installed. Excellent.
Running the project on a different machine, running composer install gets all the latest packages, which breaks the project because major updates mess with everything.
I'd love to know if it's possible to trade out all those "*"'s with caret version numbers utilising composer show --save-dev or something similar. Perhaps only possible by running a script or installing something?

How do I find out what version of a bower package is actually installed?

Normally a bower.json file specifies some dependencies, but these are typically expressed so that they allow a range of versions of a bower package to be used (e.g. >=1.0, which means anything higher than version 1.0).
I have an automated process which needs to find what version of a bower package is actually installed on this system right now.
How can I find this out programmatically (just the version itself), ideally using standard Unix command line tools / the bower command?
bower info <thepackagename> does not show this - it shows information about what is currently available from the bower repository (for example, even if I do bower info apackageIdonthaveinstalled it will still show a valid JSON structure containing a version number).
cat bower_components/thepackagename/bower.json | node_modules/json/lib/json.js version works for some packages (assuming the npm package json is installed), but not all (e.g. jquery 2.2.0's bower package does not contain a bower.json).
Here's a grep command to do that:
grep "version\"\:" bower_components/thepackagename/.bower.json
Also, a command to see versions of all bower components for the project - this list can be a handy CI artefact:
grep "version\"\:" bower_components/*/.bower.json
Have you ever tried "bower list --json=0 --offline".
It would list all bower packages info.
The best approach I've now found, which seems to work for every package I've come across so far, is:
cat bower_components/thepackagename/.bower.json | node_modules/json/lib/json.js version
(note the extra . in .bower.json).
It would appear that bower stores some metadata about the installed package in .bower.json, and that includes the installed version.
The best I've come up with so far is:
bower list | grep jquery | perl -pe 's/.*jquery#(.*?) .*$/$1/'
(if, for example, the package I was interested in was jquery).
That's pretty ugly for a variety of reasons:
I have to repeat the package name (although this could probably be improved
with a better Perl script which filters lines too, I'm just being lazy).
bower list gets information about all installed packages, not just the one I'm interested in - the rest of the information is discarded.
bower list seems to require internet connectivity to check the registry, otherwise it fails.
Would be interested to see if this could be improved upon, particularly the last point.

Is there any way to automatic change package.json's latest or asterisk(*) mark to specific version?

I use npm Node Packaged Modules to manage project library,
But I notice unconditional latest update version make me hell.
(Too many unmet dependencies error..)
So I try to find to change all latest version to my local current version. I find the --save flag make some libraries specific version, but not all. Is there any good way to solve this problem?
As per the NPM documentation, you can use a "semver" string to specify how to match the specific version, or how that version number can change, to control your dependencies as follows:
version Must match version exactly
>version Must be greater than version
>=version etc
<version
<=version
~version "Approximately equivalent to version" See semver(7)
^version "Compatible with version" See semver(7)
1.2.x 1.2.0, 1.2.1, etc., but not 1.3.0
It's also worth reading the node-semver documentation which defines in more detail how to specify and control the versions of your dependencies that match.
The other command to investigate is npm shrinkwrap - this prepares a npm-shrinkwrap.json file (which will be used by npm install instead of package.json, if present) which has the specific versions recorded in it, meaning future npm install's should always give those specific versions. See the NPM documentation for shrinkwrap for further information.

Files to commit to repository in a Yeoman project

when you generate a yeoman project, do you commit the node_modules that is generated into your code repository?
It seems like it is necessary for another developer to check out a project and develop from it, but it seems like a lot of files to commit which seem unrelated to a project itself.
You can just run npm install to get the dependencies installed. However there are multiple benefits to committing your dependencies, which you can read about in this blog post:
Checking in front-end dependencies (for Bower, but applies to npm too)