We have a legacy app and it's been using Angular 2.4 since the beginning. Currently package.json is having overrides for many packgages and for our build, we are using npm install --force because of multiple conflicting peer dependency, cannot resolve dependency of some packages, etc. I can foresee that we would keep using override for other dependency update and expanding the package.json.
I'd like to understand:
the risks if we don't upgrade Angular version and keep using Angular 2.4?
Is it okay to use npm install --force in build/release pipeline in production?
Short answer is no
Older versions of packages "decay" over time.
Sometimes because a version of a package had dependencies which are no longer maintained
or (the worse) because their n-th level dependency is no longer maintained.
once a version is out of the LTS terms (or deprecated like angular v2 and older are) you also start to loose its documentation.
Then there is the unknowns of having your locked version of a package having to run with newer versions of its dependencies. And you would having to provide some of the fixes yourself.
There are plenty of security issues that the 100's of dependencies a package like angular has and can only be addressed by upgrading.
Your app might still work with forcing dependencies to update. But it would certainly be exposed to a fair bit of know issues which newer versions have already addressed.
Related
Whenever I install any packages through npm I keep getting this warning:
npm WARN deprecated fsevents#2.1.3: Please update to v 2.2.x
I tried various methods to update it. But all failed.
So my question is, is this important for Node.js?
Can I uninstall it, if possible?
Or is there any other ways to update or remove the warning?
Some package you are using is apparently using the v2.1.3 version of the fsevents module, yet that has been specifically deprecated (usually because of known problems or vulnerabilities) and it is recommended to use v2.2.x instead. If you aren't yourself directly using the fsevents package, then you can grep your node_modules directory and find out which package is using fsevents. You can then try several things:
First, make sure you have the latest version of all the packages you are specifically using in case it's already been fixed in one of those.
See if there's an update to the package that is using it that fixes the warning.
Contact the maintainer of the package that is using it to see if they have an update coming that fixes the warning.
Fork that package and modify their package.json to update to the latest version of fsevents and then test things to see if it all works appropriately and go with that until the maintainer of the package fixes the core.
File a bug/issue with the maintainer and wait until hey fix it.
I downloaded nodejs from its official website, and npm with it.
When I tried to run Gatsby:
npm install --save gatsby
npm WARN deprecated core-js#2.6.11: core-js#<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js#3.
npm WARN deprecated chokidar#2.1.8: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.
...and so on
I can reinstall them one by one. But it makes me wonder why official website installation gives deprecated warnings. Is there something I'm missing?
Is there something I'm missing?
Let me turn the question around: can you 100% guarantee that for every project you have ever published, every dependency of your project is up-to-date, every dependency of every dependency of your project is up-to-date, every dependency of every dependency of every dependency of every project is up-to-date, and so on, and so forth?
I know I can't! In fact, I know that some of my projects have dependencies that in turn have dependencies that are no longer maintained. The problem is simply that I do those projects in my free time and re-designing the project to use a different dependency would take too much time that I don't have. I even know that some of my projects have dependencies that have unfixed security holes! But, the version which fixes that security hole has a backwards-incompatible API change, and I simply don't have the time to do the necessary re-write.
Remember that most of those projects are open source community projects, so, as a member of the community, it is in some sense even your job to fix those issues.
Gatsby has 85 direct dependencies. The transitive closure of dependencies, i.e. the set of Gatsby's dependencies, the dependencies of those dependencies, the dependencies of the dependencies of those dependencies, and so on, is 787 packages. Now, isn't it possible that the developers of Gatsby simply don't have time to constantly track every single one of those 787 packages to make sure that every single one is up-to-date?
Inside a Node.js project, it's not clear to me what is the correct workflow to ugpgrade a package to a major release.
Let's suppose I'm istalling stylelint: npm install --save stylelint by default puts inside my package.json the string "stylelint": "^8.4.1" which means that if I want to update it with npm update, I will get only minor and patch releases (8.4.2 is ok, 8.5.0 in ok, 9.0.0 is not).
If I check with npm outdated and it comes out that I could update to 9.0.0, npm update wouldn't work because of the restriction depicted above.
So, if I want to upgrade, what am I supposed to do?
Have I to manually modify my package.json to stylelint version ^9.0.0, delete node_modules directory and re-run npm install?
Or maybe I have just to remove the ^ character to let npm update do its job?
What is the common/best practice to adopt?
Thanks
Say you have "the-package" installed at version 3.x and want to upgrade to 5.x
You would do this:
npm install the-package#5
it will update package.json and package-lock.json as well.
You can also update multiple packages in one command like npm install package1#5 package2#16
To check which packages need updates, run npm outdated
So, if I want to upgrade, what am I supposed to do?
In order to update major releases you can use the npm-check-updates.
See this great answer.
Or maybe I have just to remove the ^ character to let npm update do its job?
What is the common/best practice to adopt?
The most common/best practice is to never allow automatic updates to versions that have potentially breaking changes. Workflows are all over the map, from; manual test and then update packages.json, to fully automated detect, test, update and submission of packages.json.
Many Java/JavaScript environments are particularly sensitive to transitive dependency changes due to the lack of side by side versioning support. If your package brings in a breaking change of one of its own dependencies, then your package has introduced a breaking change to the system. If your 1.y.z causes an update of one of its dependencies from X.Y.Z to X+1.Y.Z it introduces a breaking change and is therefore not a stable version 1.y.z. Other packages that depend on the same package name as yours could potentially be broken whenever the developers of that package released a breaking change. Never let the world get into that state!
I recommend you study the Diamond Dependency Problem and take to heart. You should always carefully test breaking changes and never try to force them on your customers.
As pointed out by #ShaharShokrani, this answer gives a good workflow for manually updating your package. And to remain in compliance with SemVer 2.0.0 #8, don't forget to bump your own major version number.
You can also remove and install the package.
npm rm package
npm i package
tl;dr
Is there is a reason that I shouldn't do the following; Install and manage packages with a version of npm that is different (much newer) from the npm version that comes with the node version I am going to be using to run my app.
longer
Some context why I am asking. I have to work with a service that supports only node 0.10.32 (I know, don't ask) and an app that was written some time ago. We need to add some functionality and unfortunately when I try to run the codebase locally it does not because some dependency of some dependency updated the minor version and they introduced const or fat arrow notation (=>). We had used shrinkwrap to lock down the versions but something must have slipped.
I have spent days on this and at some point it came to me that the problem lies with the package manager not doing what I want. So I managed to install the packages I wanted and shrinkwrapped it using npm#3.10.10 which is what I get when I use node#6.12.3 (nvm use 6.12.3). And when I want to run the app I just switch to the node#0.10.32 to make sure that is going to work on the service.
Can anyone think of any problems with this solution or a reason I shouldn't do that?
Side question
I noticed that when installing node versions using nvm, they usually come with a specific version of npm? What is the relation of those versions? How are they decided? Was it the latest npm version along with that node version when it was released? Is it the latest version of npm that can run with that specific version of node?
As node is deprecating old Buffer usages, and unfortunately I'm using it in one of my packages. I'd love to rollout a new version to fix this before too late.
I rolled out a version that drops node < 4 support with patch version number increment, and someone complaints the breakage a few hours later.
As npm install --save always includes full semver in package.json. Which makes it impossible for deployment machines that runs a different version of node to resolve the package to an earlier version.
If I increase minor version or major version, the users will face the same issue after using npm install --save.
I know that the user should use the same version for dev and production, and npm will do the right thing for them. But this is not a perfect world. Is there a way to make this rollout transparent to end users by using some npm features?