How to upgrade one individual file from node_modules folder instead of upgrading the whole package - npm

I need to upgrade one of the yarn.lock file from node_modules folder to remove the Raven vulnerabilities issue.
The file path is
src/node_modules/form-data/yarn.lock
I know I can use npm install to install a new package. But is there a way that I can keep the whole package to the current version, but upgrade one file in the package?

You can edit the file directly. Or you can fork the package and update just the file, then publish your fork. But no, there is no way to use npm (and presumably not yarn either) to update a file without updating the package. That is by design. There are big debugging and malware possibilities if you run an npm command and have it report back that you are running version 1.2.3 but in reality you are running version 1.2.3 with one or more files modified.
I'm puzzled a bit by your desire to update a yarn.lock file in a package. yarn.lock files don't affect anything if they're inside node_modules. This is true both for npm and yarn. The yarn.lock file is ignored if it is not in your top-level project. Updating yarn.lock inside node_modules won't do anything to your running code. Perhaps the dependency is listed in your top-level yarn.lock file for your project?

Related

package.json and package-lock.json does not reflect node_module's versions

I updated my Angular project with npm and for some reason package.json and package-lock.json was not updated accordingly. So the question is, do I have to update them manually, or is there a way to update these files according to the actual versions in node_modules?
I tried npm init but that gives me a very big package.json containing every package in node_modules. Therefore I would prefer something that updates each entry in package.json according to what is actually installed.
I had a similar problem, where not all of the needed modules in node_modules were "required" (directly or indirectly) by package.json, so every time I installed something using npm install, it also removed a whole bunch of modules.
My solution wasn't a very satisfactory one, but it did the trick:
Renamed my package-lock.json file and package.json files to keep them safe but out of the way.
Used npm init as you mentioned, to create a version of package.json that contained all of the modules in node_modules.
Moved that out of the way but kept it for reference.
Renamed node_modules to something else to keep it safe but out of the way.
Created a brand new package.json file, again using npm init, but which had no dependencies because there was now no node_modules directory.
Went through my source files finding every dependency require statement, and did an npm --save install package#version on each. I got the package name from the require and then found it in the complete package.json (from steps 2 and 3) and used the version number from that to ensure it matched what was there before. (I've got some legacy code with out-of-date modules, which is why I wanted specific versions.)
Now, my package.json file is minimal, but when I run npm install, everything is up to date.

What is the correct use of package.lock.json file, when exactly it works

What is the exact use of package.lock.json file? I have read about it but it's confusing.
Let's say I do npm install so that it will create a package.lock.json file, and the next time when I do npm install, will it retain installation of the same packages as it was mentioned in the package.lock.json file?
Let's say I have a package version defined as "^1.0.0" in my package.json file and a new version becomes available in the npm registry. Will it update the package when I do npm install, or will it keep the same as what was there in the package.json?
Is there any easy way to update the package.json file with the exact no of package version without manually updating it one by one? I want to keep maintain the version of the package the same so that next time anybody does npm install, they should get exactly the same package. It's need for a release branch
Actually I need what was the original definition of package.lock.json file but I found inconsistency in its behavior.
I tried using NPM CI but it fails with error node_gyp needs python https://github.com/nodejs/node-gyp/issues/1977
What is the exact use of package.lock.json file?
Ans: The file is used to describe the exact tree that was generated initially, that is the version of the dependency that was used initially to install (NOTE: It will always be modified if package.json or node_modules are modified by npm)
source: https://docs.npmjs.com/configuring-npm/package-lock-json.html
Now coming to your specific questions :
Let's say I do npm install so that it will create a package.lock.json file, and the next time when I do npm install, will it retain installation of the same packages as it was mentioned in the package.lock.json file?
The simple answer here is: Yes
When you do npm install initially, you specify the package name. npm will create node_modules folder and package-lock.json file and the entry of the package with the version that was used to install will be added. next time when you do npm install, without specifying the package it will not update any of your package even with the caret (^) symbol because this time npm will look at the package-lock.json file (as it is present there) and it will install the same version that is specified in the (package-lock.json) file.
Let's say I have a package version defined as "^1.0.0" in my package.json file and a new version becomes available in the npm registry. Will it update the package when I do npm install, or will it keep the same as what was there in the package.json?
As explained in first question, it will not, if the package-lock.json is present in the directory. Updating of the package will only happen if package-lock.json file and node_modules folder are not present in the directory.
Is there any easy way to update the package.json file with the exact no of package version without manually updating it one by one? I want to keep maintain the version of the package the same so that next time anybody does npm install, they should get exactly the same package. It's need for a release branch
It is a good practice to use npm ci, but you can also use npm update, this will update the dependencies to its latest minor version, and your package.json as well as package-lock.json file will also be updated
For the production, its preferred way to use the same version of dependencies that was used initially. In this case it is better to have package-lock.json file, so in case of dockerizing application when you do npm install it will install the dependencies with versions that are used in package-lock.json

Install other package.json dependencies

Simple question : Is it possible, in a package.json, to reference another package.json, and install its dependencies ?
Thank you.
Yes, this is possible, and this is automatically done by npm install.
If you have pkg-a that depends on pkg-b, including pkg-a in your dependencies will install both pkg-a and pkg-b when running npm install. That is because dependencies are actually references to the package.json of other packages. NPM, upon running install, builds a dependency tree of all the packages that are indirectly required by your current project, and installs all of them in the node_modules directory, and keeps track of them all in package-lock.json.
Good question! but this is not possible as you cannot internally reference one json document from another (json is just a document format, it lacks any ability to process logic, import files etc), npm is configured to run using a single package.json file so your best best would be to put all your dependencies in a single package.json file or split your project into two directories with two separate package.json files, two npm installs etc, if for some reason you require your dependencies to be separate. You could then run your two node projects separately and connect via http if you wish.
The only way that you could come close to doing this would be to write an npm start script in the package.json that cds to another directory with a package.json and runs npm install, this would however only install the dependencies in the second directory node-modules/ folder

How to prevent nested node_modules inside node_modules

I've created my own npm package, let's call it XYZ, it has #material-ui dependency in it's package.json file.
When I install it in project A I have nested node_modules inside of XYZ folder(so it's A\node_modules\XYZ\node_modules\#material-ui), but when I install it in project B I don't have nested node_modules folder. Both project A and B has #material-ui in their package.json files with same versions.
How to force my XYZ package to use #material-ui from A\node_modules?
There are upside of having less nested folders and downside having more folders in node_modules folder directly and version control problems.
Use correct npm version
Correct yarn and npm (ie: npm v3) should not have such structure issue. It should always flatten the whole structure where possible and only have nested node_modules if the versions are incompatible with the one at top.
Check versions
So if you have it working properly on one project and not on another, its probably due to version. Check out if the #material-ui is same version on both. Maybe two different packages are conflicting with each other at some point.
Check how you are installing them
From your question, it says it's same version. However, you did not mention how you installed your package on both project. If you install with yarn link or npm link it should install dependencies properly as expected.
Check if you are using different packages
If you check the package, recently material-ui has been deprecated, and the notice says to upgrade to #material-ui/core instead. It might be some packages inside that folder is not same. Either way, it's like this whenever there is some dependency conflict. Check inside the #material-ui folder.
Flatten them manually (dangerous)
There are several packages to forcefully resolve this issue. They will go thru the nested node_modules folders and flatten them into single folder.
flatten-packages
Install with, npm install -g flatten-packages.
Run executable flatten-packages to rearrange all packages in node_modules folder in the project directory.
Flatten will delete older version of a package. You should take care of version breaking changes related errors.
You can use npm dedupe command to accomplish this.
You can put the command in postinstall script in package.json, and every time NPM installs package, the npm dedupe command will flatten all the duplicated packages in same version for you.
For more information, see https://docs.npmjs.com/cli/dedupe
npm postinstall script
I had the same issue in a React Native app with my NPM package.
The problem was that in project A the version of React Native used was (0.59.5) below the version used in my package (0.59.8).
Installing the package in a brand new project (B), of course was using the latest version of React Native in that moment, that was the same of my package (0.59.8).
I have another addition to the accepted answer:
Clear Local node_modules folder Cache
rm -rf node_modules
Handle with care: Sometimes migrating projects to new npm modules can cause weird cache issues inside a node_modules folder, especially those that have been around for a while, or happened to have newer versions of packages installed in sub-dependencies that differed from the installed version in root.
Once you remove direct dependencies via the package.json dependencies, the packages will be removed from the <root>/node_modules. This can cause a bug where the new modules are still nested under your dependency instead of being moved to root as expected.
So by wiping out your local node_modules, you can do a clean reinstall and let the flattening to its work.

Deleting project folder

Let's say i want to delete project folders with a bunch of localy installed npm packages such as gulp, gulp-sass or/and other package managers maybe bower with it's own packages.
Is it an easier way to just manualy shift+del whole folder and, well, I don't know, don't leave behind some conflicts or something?
Or maybe npm has a command to proper uninstall all packages, "uninit" folder, etc?
I got this problem.
At first, I copied all of packages from packages.json and run command like:
npm uninstall #typescript-eslint/eslint-plugin #typescript-eslint/parser #vue/cli-plugin-babel #vue/cli-plugin-eslint (... etc.) --save
Then, I tried to delete folder by hands, but it is deny permitions.
I open my project from VSCode and delete node_modules from tree by hands:
Delete node_modules from tree by hands from VSCode
It was delete successfully!
p.s.: The remaining files are deleted without problems manually...