I maintain over 200 repositories on GitHub and one of the most common PRs that I receive is someone adding package-lock.json or yarn.lock. These PR...
For further actions, you may consider blocking this person and/or reporting abuse
Not again :(
This is incorrect, the lockfiles should always be committed. This isn't about you, but about your external contributors and project archival. The lockfile ensures that we never lose track of the last known good state.
Previous discussion: twitter.com/arcanis/status/1164229...
The state of dependencies should be described in package.json. That's what the dependencies field is for. Package-lock.json is unnecessary.
Not that this is common, but what about the dependencies that your dependencies rely on? What if they change?
You have not read the article.
I did. And working on package managers is part of my daily job, so it's not the first time I think about this.
My thread is a good explanation of the problems in your reasoning, and I'd be happy to go into more details if you have a specific point you'd like to challenge.
I am not advocating against using package-lock.json for programs designed to be consumed by the end consumer. I do suggest not to use lock files in packages that will be dependencies of other packages.
I have read comments of the multiple people who are suggesting to use package-lock.json because it locks down dev dependencies. This is not a valid use case for the same reasons that I outline in the article. If you need to lock down dev dependencies, use semver range that meets your requirements.
Exact semver range isn't locking. Transitive dependencies are still free to change unless you use a proper lockfile.
This isn't to say that exact dependencies are useless (some of my codebases use them), but they solve a different problem and it shouldn't impact at all whether the lockfiles are meant to be committed or not.
This is the part I'm objecting to. To quote myself:
I understand your argument (using lock files ensures smooth deployments and development cycles). However, unlike others in this thread, I do not put as much value on this argument compared to the downsides I have described in this article. In practise, I have found it extremely rare that dependencies or transitive dependencies break or introduce bugs within semver changes that prevent me from working or that would have been prevented using lock files. Happened, maybe 3 times over the last 5 years that my work was interrupted for longer than an hour.
It could have been 0 times, if you used a lockfile. Just saying.
I get it - similar idea expressed in this article yehudakatz.com/2010/12/16/clarifyi.... But from experience
npm
packages are fragile, what you were able to install today (based onpackage.json
) doesn't guarantee you would be able to install in a month. How do you deal with fragility? I gave up and commit lock files.You can always use exact version number dependencies in package.json. Package-lock.json is unnecessary.
Your "exact version number dependencies" have other dependencies which most likely are not "exact version number dependencies", so case described by @stereobooster still applies. You will most likely get different packages in time when you use npm install on your project without package-lock file, and your project may break because of that. I agree it's a pain to maintain it but sometimes there is no other way.
If the package-lock.json has a dependency outside a range defined in package.json, the lock file will be updated with the exact version used. Therefore, they always match.
I tried not using a package-lock.json. After the second instance of a dependency's dependency breaking my build, it became obvious that the lock file is there for a reason... I always use it now so everyone gets the exact same versions.
The headline is misleading, there are as you already told different use cases.
c l i c k b a i t
There is only so much information that can be contained in the title. Do you have suggestions how to rephrase the title?
"When not to use package-lock.json"
Thank you for the suggestion. I have updated article title.
Not everyone adheres to semver. That's where this falls apart.
Most popular package that disregards semver: typescript
It doesn't matter if you are developing in a team or solo. The package lock provides a clear vision which version of dependencies and dependencies of dependencies are being used,and sets them to a fixed version. You do not have any control of deeper dependencies without a package lock which can be reviewed.
npm i
updates dependencies without you noticing, that's why you use anpm ci
when you want to rebuild your node modules.When updating all packages you can create a specific feature and check those changes. Or automate it if you have decent test
Aren't you mixing up two things here; committing to a source code repository, and publishing to a registry?
npm pack
strips outpackage-lock.json
for publishing. But I believe that even if there werepackage-lock.json
files in dependencies,npm install
ignores any but the top-level one, anyway. It wouldn't make sense conceptually to consider them, because if you successfully lock down your dependency versions from your root, you implicitly lock them for all dependencies further down the tree, as well.On the other hand, nothing speaks against publishing
package-lock.json
with the source code. In fact, that's half of the reasons for its existence. Because it only has an effect if it's the top-level package, it will help library developers with its intended purpose, while not affecting library consumers.Please correct me if I'm misunderstanding something here!
Always commit your lock files, it speeds up CI builds because npm/composer wont have to locale the packages again since it caches the locations of them in the lock file, there is no place where you should not do this, unless you are inherently a bad programmer and don't like to follow industry practice.
I agree that your lockfile must not be packaged and shipped within the library.
However, when developing libraries you probably have a set of development dependencies and/or normal dependencies. Here is where I disagree, because these should actually be in a lockfile (in my opinion). You are still pulling dependencies there, even ones not included in the publishes library.
The alternative of using exact versions is also possible. Although, for me, the tradeoffs of messy commit to update patches and losing the ability of quick updates (remove lockfile/npm update) is a no-go for me.
I understand that even if you have the package-lock it will have no effect on any
npm install
ran on you machine, docker or CI/CD. That's why it is always updated after annpm install
.It only makes a difference if you ran
npm ci
, right?Almost,
npm i
always reproduces the same build from package-lock.json. Unless the dependencies are changed. Then it will update the package-lock.json to reflect those changes. It does not ignore the package-lock.json, as that would change your dependencies every time some nested dependency releases a new (patch?) version that satisfies its dependency requirement.As far as I know, yes. (Although I'm aware you wanted the author to answer you).
npm ci
is has been very useful for consistent development and ci-build environments, for me at least.This is more of your own opinion Gajus than a best practice.
Mael has pointed out good reasons to use lockfiles.
2 articles I wrote to provide more context on lockfiles are:
Doesn't make any sense to me, we as a Library produce code, our code will be consumed by others so what?
Our code is not publishing the package-lock.json , that correct cause it's been used to build the code.
What is not ideal is when the CI break because of a 3r'd party and we invest 2-3 days of manpower to find the cause of this....
For example:
I had committed fix for a defect in my code and got a build error because of a 3r'd party changed, can't see any logic.
Libraries produce code that is used in other places so it's not matter is the code used by people or computers, the documentation on NPM documentation is correct and you need to put the package-lock.json in your source control it's there for a reason, and the reason is: stable software is SOLID
Once you don't have reproducible builds your software is not SOLID anymore.
I am not using lock file on modules, I am now facing a hard issue accross many projects. Terser is breaking on production build of my documentation, having lock file accross the chain of dependencies would have prevented that.
Keep pushing, I think this is an important improvement.
I'm maintaining PHP packages and we have the same debate about composer.lock in libraries.
I'm lucky to live in the same city as one of the two authors of composer (npm's counterpart in php world) so once I could have a personal discussion about the topic with him.
He also suggested to commit the lock file with the package (which I don't do either) but he also suggested to do this in the CI pipeline:
Here I can see the benefit of the lockfile, albeit I haven't started doing it yet
Dependency lock files are for fast tracking your dependencies via a file cache, so it doesn't have to look through npm again to find them again, you are meant to commit it yes and i don''t think there is a case for not commiting it?
It also works the same on composer.
Why ignore his advise about that from the author? your PI pipeline versions will eventually mess up because you don't commit it...
I think this is like a double edge sword if some dependency in my package's tree is updated with a vulnerable package. That would directly affect my package. The same thing that happened with event-stream snyk.io/blog/malicious-code-found-...
This is an odd way to put it :) Rather, you probably mean that you want to know when there is a breakage, not that you want to have to drop everything and fix it right now and it is blocking you from your original task at hand. No one wants that kind of interruption.
There are a couple responses:
The same reasoning applies to both dependencies and devDependencies, because both are very much used during development.
You described it as "wanting your development environment to not break", but realize this applies to both the build and the tests, and dependencies are used in tests.
I think package-lock.json for security purpose.
When a user hit npm install package-lock.json created commit the package-lock.json changes to version control. They must be insecure network.
Once the package-lock.json generated from true (secure) network and your other machine network might under attack and hacker might change npm registry DNS/Route/IP in that case npm will check the integrity with npm install.
The solution for the stated problem is not not using lock files. It should be choosing pinned dependencies vs ranges.
No, it's not, because pinning dependencies doesn't pin their dependencies. The only way to do this properly in an application is with a lockfile (NOT pinning anything). The only way to do this properly in a package is to use
^
, always.Thanks for the clarification.
This is false.
On the other hand, wouldn't you like to lock versions of devDependencies, leverage faster builds in ci, etc?
This is basically what a lockfile does... why not just use a lockfile?
I agree with your arguments about why it should be a developer/maintainer responsibility to keep their dependencies at the latest versions and solve any issue related to some broken/buggy dependency version.
Perhaps npm needs to use a different approach to help us identify when an end-user runs ´npm install´ vs when a developer runs it.
To make this distinction viable we would propose two different kind of lock files. One for development usage and another for final usage (like packages that are themselves dependencies of other packages.).
Instead it's better to set npm with --save-exact (in .npmrc or on every install).
I did not understand how not commiting package-lock solves this issue? won't package.json will update sub-dependencies anyway?
Thanks i was not aware of this.
"but it was archived without an action."- probably they just act like you, closing PRs without any notice 😅
I do provide explanation to every PR I close.