Why removing node_modules is still required to fix some npm problems? - node.js

npm 1.0 was released in May 2011, yet with it's latest release as of today, I still often run into a lot of problematic situations that can only be solved by removing node_modules. Of course sometimes it is enough to reinstall some package, or rebuild another, but as of 2018, the consensus seem to be that the ultimate solution is to remove node_modules and run npm install again. I wonder - why is it the case? I'd imagine that most difficult bugs are already solved since the 1.0 release, does it have something to do with the design? I found that Yarn is free from this problem.

Much like "turning it off and on again", it's a very simple action that in almost all cases will sort out what's wrong with no damage.
Then once it's sorted, there's not much incentive for the user to pursue it, and all evidence of what the problem was will be gone.
The bug remains of low importance (because there's an easy workaround) and high difficulty (no evidence, may be hard to reproduce), so doesn't get fixed.

Related

How can I get a warning-free Node.js build?

When bootstrapping a new Expo project with expo init ..., I see the following warning (among about a dozen others) right off the bat:
warning expo > uuid#3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
OK, great. I understand the concern. Then, I go over here and see that, while there are some possible breakages, I went through and verified that none of the calling code seems to run afoul of them. Then, using Yarn resolutions, I add this to my package.json:
"resolutions": {
"uuid": "7.0.3",
...
}
Next, I delete node_modules and yarn.lock, and yarn install again, and now I get this warning:
warning Resolution field "uuid#7.0.3" is incompatible with requested version "uuid#^3.4.0"
So, essentially, I've traded one warning for another. What I really want here is an error and warning free build. I'm willing to accept responsibility for the breakage I might cause by pinning "incompatible" versions. Or if I could turn these warnings on/off (one by one) somehow, it'd be suboptimal, but I'd probably be fine with that.
I come from a previous life of developing safety-critical systems in C & C++, where we operated under a doctrine of 'warnings are errors waiting to happen; no warnings allowed ever.' I've noticed from looking at many other Node.js projects that many folks working in this ecosystem seem to just say, "Warnings? YOLO!", and I can see why, TBH. When the problematic dependency is a 7 layer deep, transitive dependency (all 7 of which you didn't write, don't "own", and are unlikely to be able to edit/fix, and 6 of which you didn't even explicitly ask for) I can see how it might be easy to say, "Not my problem!" and push onward.
But is it really the case that there's just no hope for a warning free build? I thought resolutions would be the solution to this, and it was helpful for one dependency that was a "compatible" version, but I'm driving myself nuts trying to figure out how to simply get a clean build on an effectively empty (i.e. no code of my own) project. There have to be companies/teams out there with similar desires, so I'm assuming there's some solution I'm not aware of. Does anyone have any hot tips?
I've tried:
yarn resolutions (as described)
npm-force-resolutions (seems like an abomination -- it edits your packages-lock.json, requires 'double installing')
force-resolutions (which looks like just a newer fork of npm-force-resolutions, and has the same issues).
I've read about NPM v8.3's overrides (and it looks promising, TBH), but Expo's cloud building service uses NPM v8.1, so that's off the table until some nebulous moment in the future.
I just can't believe this an unsolvable problem, or that I'm somehow the first person to try to solve it. Thanks!

Is package-lock.json useless in npm 5.6.0? Should I commit it?

I've read a lot about it, there are tons of questions here on SO about how it worked before npm 5.1.0, and some about how it works now, but I can't find a definitive answer to what exactly is its purpose now, and if one should commit it or not.
As I see it, package-lock.json is almost uselss now (node 5.6.0), I can't see any benefit in committing it, it may even be counterproductive because it may lead to merge conflicts.
Official documentation has not been updated to reflect the changes https://docs.npmjs.com/files/package-locks so it's... Useless.
Note that I'm new to node, I might have misunderstood something, if soo please correct me.

How can I check if my code will run in a new (or old) version of Node?

I have a code running in Node 9.8
Node 9 will reach End-of-life soon.
If I switch to node 10, how can I check if my code will run in node 10 without having to execute all paths of the code ?
Or if I go down to 8.11, how can I check if my code will run in node 8.11 ?
There is no test cases written on the code.
This is a good example of why solid unit/integration tests are critical to long-term maintainability. That said, there are a few steps you can take to reduce the risk of breaking things:
Take a look at the change logs pertaining to the versions you're moving to/from. The NodeJS team kindly includes a Notable Changes section in each change log, though I wouldn't rely on that alone as being 100% inclusive of the potentially breaking changes you may be up against.
Consider writing unit/integration tests, both as part of your assurance that things won't break from this version change, as well as that things won't break from later version changes (or everyday changes for that matter).
As much as I hate to say it, Googling around for guides on upgrading (or downgrading?) NodeJS versions may help you identify potential danger zones.
Generally, I'd consider it safer and better practice to upgrade the version than downgrade. For one, you're moving forward to the newer and greater experience the NodeJS team wants you work with, and secondly, future versions are probably more likely to be backwards compatible, whereas the old version may be missing features you're using.

npm how to commit package-lock.json if I did not use GitHub

I downloaded NodeJS and installed it on windows 10.
I updated npm using the npm install npm#latest -g command line
I neither used github nor anything else
I get the message "created a lockfile as package-lock.json. You should commit this file".
What should I do to commit the file?
what happens when I commit it?
what happens if I don't commit it?
Please do not quote the npm documentation, as I read it serveral times and did not undestand it.
Thanks
Thank you – jdubjdub & – SilverWolf - Reinstate Monica for your cogent remarks. Yours were the comments that led to my eventual comprehension; years after the fact for you, hours after the fact for me.
I know this is an old post and the OP and OC's are likely to never see this answer; I am dealing with this problem for the first time and have typed into the browser a reformulation of this very question many times today. I was near to trying the patience of some of the genuinely gifted people on Stack Overflow, attempting clarification for my own elementary version of the question.
I have finally come to recognise the term "commit" is not as alien as we thought. It is what we thought it might have been. It's the same as on github as when we commit anything that we have changed and want other contributors (or authors) to see.
I have a github account and git installed on my computer. After about an hour of docs and man pages I did not put all the dots together until I read the comments on this page and then it all finally just became so perfectly clear. Commit is the same concept on github as is being referenced in my terminal: npm notice created a lockfile as package-lock.json. You should commit this file. And since I am not actively working on a project I can disregard the warning. Also, some argue the merit of ignoring it even if I were on production. But that's beyond the scope of this post.
Those whom only rarely use git or gitHub, have only the vaguest grasp on how one performs version control. The term "commit", even when mentioned frequently in answer, does not necessarily obviate all but the one meaning or action.
Our friends may not fully appreciate our incomprehension of the term "commit" in this context. We were thinking (in my naivete, at least I was) that there may be more than the one meaning to "commit" we are familiar with i.e. from github.
I guess these are just such a common abstract for anyone doing version control they assume since we've gotten this far we must grasp the nomenclature and are really puzzled by the deeper fundamental aspects of the underlying processes and procedures.
If you would like a more robust definition on exactly how (and why) to commit check this out: github:https://help.github.com/en/desktop/contributing-to-projects/committing-and-reviewing-changes-to-your-project.
I should note there are many free and paid version control tools available. Here is not an exhaustive list containing 15: https://www.softwaretestinghelp.com/version-control-software/.
And here the github desktop app:
https://desktop.github.com/.

Should I keep all sub-packages on a single version in package.json?

There is a 3rd-party library my project uses that has split its functionality into multiple imported packages so that a project can install just what it needs. In package.json, several entries are present for the different sub-packages, like...
"dependencies": {
"#lib/dogs": "^1.0.3",
"#lib/cats": "^1.0.3",
"#lib/iguanas": "^1.0.3"
...lots more of the same...
}
I don't want to spend time thinking about compatibility issues if one of the sub-packages installs a different version# than the others through semver-range-picking or another developer fixing a problem by incrementing the version on just one sub-package. I suspect there is some risk of bugs if the sub-package versions get out of sync, even if the intent of the package maintainers is to respect the meaning of breaking changes in their versioning. It seems simpler to just have all the sub-packages on the same version by default.
Should I try to enforce (or at least promote) that the sub-packages have the same version?
Promote, but don't enforce.
Your current set-up, which uses Caret Ranges is the default used when installing with the --save flag for a reason: it's the most flexible and robust range to use for dependencies that correctly follow the semver conventions. This means that whenever someone update's your module as a dependency to theirs, it will automatically bump their sub-dependencies to the latest version that is backwards-compatible with the one explicitly specified after the ^.
Because of this, and the fact that scoped packages don't have interdependencies since they behave identically to normal dependencies, leaving identical caret ranges for each of them should already be sufficient enough to avoid compatibility issues by default.
Don't protect developers from themselves
A good methodology to follow when considering how to deal with compatibility issues is to avoid the antipattern of "protecting developers from themselves." In this situation, you propose to put a lock in place that prevents 3rd parties from editing the relative versions of your dependencies, to avoid compatibility issues. This is a very vague goal since you haven't actually run into any problems yet, as you've pointed out.
Sometimes, yes, developers might not know what they're doing, in which case they'll probably avoid tampering with your default dependency versions, but sometimes they do know, and it can be frustrating when a developer knows they can resolve a bug and are unnecessarily prevented from doing so. So hold their hand, don't cuff them.
npm already chose to avoid this antipattern, you should too.
If a 3rd-party developer chooses to use your module as a dependency, they should have the default amount of freedom available to manage their sub-dependencies through npm by using features like package-lock.json, which unlocks a very clean pattern for precisely managing sub-dependency versions without editing the source code of their dependencies.
In conclusion, what you have now is a very clean and flexible approach, following common conventions and not going out of the way to constrain 3rd-party developers.

Resources