How to "npm install packageX" while respecting package-lock.json - npm

I want to update a dependency (packageX) without changing a locked dependency of that package, (packageY). In my package-lock.json, I have:
"packageX": {
"requires": {
"packageY": "1.0.0",
}
},
Each time I do "npm install packageX," I'd like to update packageX but have packageY stay on the defined version. How can I do that?

There is no way to do this, may be this link can explain better https://dev.to/saurabhdaware/but-what-the-hell-is-package-lock-json-b04
The story about package.json vs package-lock.json is tricky: npm install does not ignore package.json versions, nor does it ignore the package-lock.json. What it does is verify that the package.json and package-lock.json correspond to each other. That is, if the semver versions described in package.json fit with the locked versions in package-lock.json, npm install will use the latter completely, just like npm ci would.
Now, if you change package.json such that the versions in package-lock.json are no longer valid, your npm install will be treated as if you'd done npm install some-pkg#x.y.z, where x.y.z is the new version in the package.json for some-package.

Related

"resolved" and "integrity" go missing in package-lock.json

Ocassionally, when installing an (unrelated) dependency, I lose the resolved values from each of my private nexus repository dependencies, meaning that when my build server runs npm ci it falls back to attempting to install these from the npm repository, which obviously fails.
I am using npm 8.5.5/node 16.15
I am using NPM's workspaces feature to construct a monorepo, meaning that I have several project package.json files as well as a root package.json
My .npmrc (at root level) looks like this:
engine-strict=true
#foo:registry=http://prod-nexus.foo.com/repository/bar/
always-auth=true
After an (unrelated, random) install my package-lock.json will have this change:
"#foo": {
"version": "1.2.3",
- "resolved": "http://prod-nexus.foo.com/repository/bar/#foo/-/lib-1.2.3.tgz,
- "integrity": "sha...",
+ "license": "MIT",
"dependencies": { ....
Note that the resolved and integrity fields have disappeared and the license has been added.
I have run into this problem several times, each time I have solved it by rolling back and some manual editing and eventually it goes away, but I really need to understand what is going on.
What is causing this, why is it random, what can I do to defend against it?
This could be related to the issue https://github.com/npm/cli/issues/4263
clean the npm cache npm cache clean -f
run npm install again
If that doesn't work, try it again while deleting more:
clean the npm cache npm cache clean -f
remove node_modules in project folder
remove package-lock.json file
run npm install again

package-lock.json in npm workspaces

Given an npm workspace with the following structure
workspace
package.json
packages
package-a
package.json
package-b
package.json
When I run an install command in package-a this will generate a package-lock.json file in the root of the workspace but not in the package.json file itself.
Is there a way to also generate it in the packages?
I don't know if this solves your problem, but you can specifie the folder in which you would install with --prefix
npm install --prefix ./install/here
you can use the lerna tool to manage your workspace and install dependencies in each package. you can generate package-lock.json files in each package in your workspace.
The Original Tool for JavaScript Monorepos. Monorepo means a repository with multiple packages.
lerna.js.org
I hope this answer will show you the right direction.
In most cases, running npm install within that package directory should do the job. But as you said that this is creating a global package-lock.json. This might be because the package you are installing might be specifying the global path using the prefix field.
The "prefix" field, specifies the location where the package's dependencies should be installed.
So one thing you can do is to go to the package.json in package-a and then either remove the prefix field from the package.json file OR set its value as following :
{
"name": "my-package",
"version": "1.0.0",
"prefix": "./",
"dependencies": {
...
}
}
Now when you run npm install it should install the packages locally and make a local 'package-lock.json`.

NPM 7/8 is not installing peer dependencies

I'm trying to build a repository/package for my personal ESLint config files. I have all of my configuration files built the way I would like, and now I am trying to install this package to test it.
In this scenario, I have two packages:
#me/eslint-config is the package containing my ESLint config files.
test-package is the package on/in which I am trying to install #me/eslint-config.
When I try to install the #me/eslint-config package, peer dependencies are not installed, nor are they even mentioned during the installation.
Both packages currently only reside locally on my machine, side-by-side, in the same directory:
<parent_dir>:
- eslint-config
- package.json
- ...
- test-package
- package.json
- ...
The package.json file for #me/eslint-config looks as follows:
{
...
"dependencies": {
"#typescript-eslint/parser": "5.29.0"
},
"peerDependencies": {
"eslint": "8.18.0",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-jsdoc": "39.3.3",
"eslint-plugin-prefer-arrow": "1.2.3",
"#typescript-eslint/eslint-plugin": "5.29.0"
}
...
}
I am installing this package in test-package as follows:
$> cd /path/to/test-package
$> npm i ../eslint-config --save-dev
NPM properly installs all other dependencies, including the #me/eslint-config package itself, but does not install the peerDependencies of #me/eslint-config.
This is using NPM v8.1.0.
This article seems to suggest that NPM >7 installs peer dependencies automatically. This is obviously not working for me.
Things I have already tried that have not fixed the problem:
Deleting node_modules/ and package-lock.json from test-package and reinstalling everything.
Pinning all peerDependencies versions in #me/eslint-config.
Adding all peerDependencies in #me/eslint-config as both dependencies and peerDependencies in #me/eslint-config.
tl;dr NPM isn't installing peerDependencies
I had the same error on former version of npm and as you mention, npm ^8 now install peer dependencies.
But here could be ways of fining your problem
1 : estlint is a devDependencies (A guess)
eslint should be devDependencies and not a peerDependencies.
Maybe npm doesn't accept you to install it then.
I search a bit but couldn't find any real thread discussing about this
That said, I wouldn't install it as dependencies since it will be pushed to your production build, what, I think, you do not want.
2 : Being up to date
Try it with the latest version of npm
download the latest version of npm : npm install -g npm#latest
Delet node_modules/ and package-lock.json from test-package and reinstall everything. as you did already
2 : allowJs
If eslint is an js package & you see it being installed in the node_modules folder.
Inside the tsconfig.json file, under the compilerOptions add allowJs: true and set strict: false
"compilerOptions": {
"allowJs": true,
"strict": false,
Close all your instance of vs-code
Restart & retry (No need to remove the package-lock or so)

How to remove an invalid local dependency from package-lock.json and package.json?

Let's say that someone installed an invalid local dependency. (file does not exists locally)
package-lock.json
"mock-framework": {
"version": "file:../../../mock-framework",
package.json:
"dependencies": {
"mock-framework": "file:../../../mock-framework"
}
I need to reinstall the framework, but it's located differently on my machine and does not follow the structure that was provided in the package locks. Because running the npm install command is giving me the error:
Could not install from "../../../mock-framework" as it does not contain a package.json file.
Would it be possible to clean it up through the command line? I tried with npm uinstall and still no luck.
I recently faced similar issue with local dependency integrity in package-lock.json
Ideally npm uninstall should remove the entry in package-lock.json but since it is not and you only have one local framework as changed dependency, you can try following -
Fix the dependency path and run rm package-lock.json && npm i
Hope I'm inline to your problem statement.

NPM: To install a package along with its own devDeps

I am just getting myself familiar with command line tools like npm. I've been searching around for the answer but was not able to find a clear one.
What I am trying to do is to install materialize-css package into my test package, as well as its devDependencies, like "autoprefixer". This is materializeCSS's package.json file.
Here's what I do:
Under my newly created and blank folder "testProject", I use npm init to create a package.json file for my test package:
{
"name": "create_project",
"version": "1.0.0",
"description": "Setting up a project",
"main": "index.html",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "shenk wen",
"license": "MIT"
}
Then, I do
npm install materialize-css
I was expecting the above command would install all the dependencies and devDependencies of materialize-css, but only the dependencies is being installed. I read this question and the accepted answer suggests adding --dev to the command. But that seems not the answer I am looking for because --dev would only make materialize-css a devDependency of my test package, but not installing its own devDependencies. The other answers are not so straightforward. Is there any parameter I can use to achieve this? Or do I have to change the env_variable which I don't know how to?
In older npm versions, 'npm install --dev' installed all devDependencies of all your dependencies. This also used to work in a recursive fashion, so you end up downloading also devDependencies of devDependencies of your dependencies and so on. This resulted in enormously long install time / download size.
Also, the purpose of the feature is questionable: Why should you care about devDeps of your deps? For these reasons --dev was removed from npm:
https://github.com/npm/npm/issues/5554
Current behavior for 'npm install' is: install all deps and devDeps for the 'main' package (the one you 'npm install'-ed in the first place), but when recursing, install only deps (and no devDeps).
If you want to install & save the dependency to your package.json, you should use --save or --save-dev, I don't think --dev does this.
If you want the devDependencies of a module you've installed as a dependency to your project, you almost certainly want to git clone that module's repo or fork it instead. When you run npm install in your cloned repo, that will also install all of the module's devDependencies.
(I'm not a developer by trade and my npm-fu was a bit rusty, so I confused myself about what I was trying to do. Tomas Kulich's question "Why should you care about devDeps of your deps?" helped me realize the error of my ways.)