npm: how to have duplicate dependencies in dev and non-dev - node.js

I have a repo that is a dependency of all my main projects. In this repo I have a dev branch which we develop on. Can I use this when the production flag isn't set?
I have a package.json that looks like this:
{
"dependencies": {
"repo": "git+ssh://git#git.example.com:pack/repo.git"
},
"devDependencies": {
"repo": "git+ssh://git#git.example.com:pack/repo.git#dev"
}
}
npm WARN The package repo is included as both a dev and production dependency.
When I do an npm install, it installs the one from the dependencies. Is there a way to install the one from devDependencies when the production flag isn't set?

Related

Local path dependencies not installing their own dependencies

Following this answer, I installed my local dependency like this:
{
"private": true,
"dependencies": {
"my_dependency": "../relative/path/to/my_dependency"
}
}
my_dependency depends on ESLint and its plugins:
{
"name": "my_dependency",
"dependencies": {
"#typescript-eslint/eslint-plugin": "5.25.0",
"#typescript-eslint/parser": "5.25.0",
"eslint": "8.16.0",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-node": "11.1.0"
},
If I install my_dependency as a path, eslint and it's plugins are not installed in ./node_modules, therefore eslint CLI is not available.
However, if I publish my_dependency on npm and install it as package name and version,
{
"private": true,
"dependencies": {
"my_dependency": "0.0.0"
}
}
eslint and all plugins will be added in ./node_modules.
How to get the same effect for the local dependency?
I don't want to pollute npm registry with versions just for experiment each time I make changes in my_dependency.
The issue
Unfortunately those local path packages don't get their dependencies installed.
note: Packages linked by local path will not have their own dependencies installed when npm install is ran in this case. You must run npm install from inside the local path itself.
Source: docs.npmjs.com/...
The workaround
There are quite a few ways around it but in my opinion the best one is to use a GitHub repo and optionally a branch.
So just push your code to a github repo, let's say my-npm-playground, assuming your use your Github username is ada_lovelace, you can link the repo like so,
{
"private": true,
"dependencies": {
"my_dependency": "ada_lovelace/my-npm-playground"
}
}

With nestjs / node / npm project how to override a transitive dependency

I have a nestjs / node / npm project and trying to override a transitive dependency due to security vulnerability.
The project that seems to include it is:
"#nestjs/common": "7.6.18",
And that project includes axios 0.21.1, I want to upgrade to axios 0.21.2
In my package.json I tried using the overrides feature with the following.
},
"overrides": {
"axios": "0.21.2"
},
"jest": {
But then I get this entry when I run npm list.
npm list --depth=4
│ ├─┬ axios#0.21.1 invalid: "0.21.2" from node_modules/#nestjs/common
And only seems to include axios 0.21.2.
How do I upgrade a transitive dependency?
I am mostly using the nest wrappers:
nest build, etc
npm --version - 8.3.1
node --version - v17.4.0
You can try resolutions in npm -
{
"resolutions": {
"axios": "0.21.2"
}
}
And then force to install it using preinstall.
"scripts": {
"preinstall": "npx npm-force-resolutions"
}
https://www.npmjs.com/package/npm-force-resolutions

Change package.json file dependency on the basis of production and development

I want to change my electron version in package.json file on the basis of the production and development stage.
If my project in the development phase then it will take electron 11.2.0 version and in production my electron version must be electron 3.1.1. Is there any way to do this task or apply this condition on my package.json file?
Yeah.
You can add a devDependencies object to your package.json. Also when you install packages to your project you can install them with the --save-dev flag to automatically do that.
It will look like this:
"name": "my_package",
"version": "1.0.0",
"dependencies": {
"my_dep": "^1.0.0",
"another_dep": "~2.2.0"
},
"devDependencies" : {
"my_test_framework": "^3.1.0".
"another_dev_dep": "1.0.0 - 1.2.0"
}
More information can be found in the official documentation for npm.
https://docs.npmjs.com/specifying-dependencies-and-devdependencies-in-a-package-json-file

NPM 7 workspaces - how to install new package in workspace?

If I have a NPM 7 workspace like this:
root
- submodule0
- submodule1
- submodule2
and I navigate to the submodule0 directory and run npm i somepackage it seems to "break" the workspace by creating a new package-lock.json in the submodule0 directory and installing all the dependencies there. In other words, it just does the old behavior that existed before I created the workspace.
I was hoping for a command similar to lerna where I can install a new package in submodule0 from the root. Something like:
npm i somepackage --scope submodule0
So far, the only workaround I can find is to edit the submodule0 package.json and add the somepackage manually. Then run npm i from the root. Obviously this is not ideal because I need to look up the #latest version, navigate to the subdirectory, open the package.json, etc. etc. as opposed to just typing one line in the root.
Workspace support for npm install and npm uninstall was added in npm v7.14.0. You can now just do:
npm i somepackage --workspace=submodule0
Uninstalling modules has been the biggest pain, so this is really exciting. The npm team seems to be slowly adding support to commands one by one. Follow updates here: https://github.com/npm/cli/blob/latest/CHANGELOG.md.
I'm also baffled with why npm workspaces has been released without this functionality.
My current workaround uses the add-dependencies package, which adds dependencies to a declared package.json file, whilst skipping the installation process.
npm i add-dependencies -g
Then, from top level of the monorepo, you can run:
npx add-dependencies ./submodule0/package.json somepackage && npm i
Hopefully a --workspace argument will be added to npm i soon to avoid this faff.
Please refer to the answer of mattwad above if you have NPM v7.14.0 or above
Original answer
I wasn't quite happy with the suggestions, but combined all of them to use it in a npm script without any dependencies:
{
"add": "npm install --package-lock-only --no-package-lock --prefix",
"postadd": "npm install"
}
This can be used like following: npm run add -- submodule0 somepackage
Add only into package.json
U can use this to install package only into package.json ( you don't need external dependencies )
npm i --prefix packages/test --save --package-lock-only --no-package-lock express
followed by npm i to install specified dependency into mono repository root node_modules
Lerna
Also can use lerna to use workspace name to install dependency into
package.json
{
"name": "mono",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"wsi": "function workspaceinstall() { ( scope=$1; shift; lerna exec --scope \"$scope\" -- npm install --package-lock-only --no-package-lock \"$#\") }; workspaceinstall"
},
"author": "",
"license": "ISC",
"workspaces": {
"packages": [
"packages/**"
]
}
}
lerna.json
{
"version": "1.0.0",
"npmClient": "npm",
"packages": ["packages/**"]
}
npm run wsi [workspace name] [dependency name to install]
npm run wsi #workspace/test express
npm run wsi #workspace/test express --save-prod
npm run wsi #workspace/test #types/express --save-dev
wsi script only modify package.json for provided workspace name, to actually install dependencies u have to run npm i
In my case, which is similar to yours, I deleted all dependencies from all the inner projects, deleted also the package-lock.json, and installed everything in the root.
/
node_modules
package.json >> all dependencies
package-lock.json >> the only lock file that exists in the repo
/packages
/A
package.json >> no dependencies
-- no package-lock.json
/B
package.json >> no dependencies
-- no package-lock.json
/C
package.json >> no dependencies
-- no package-lock.json
This way, the node_modules folder ONLY resides on the root, and also the package-lock.json file is in the root.
If I allowed to have each project it's own package-lock.json I started seeing installation and runtime errors (because each project could have its own node_modules and its own version of a dependency).
This is the best way I see it works.
After trying to use the npm install with the --prefix --save --package-lock-only --no-package-lock options, npm always give the the error E404 - Not Found for my own packages of the monorepo that are not yet published to a registry. So even when trying to install external packages it fails because of my current dependencies in the package.json.
To workaround this issue I ended up with a mix of the previous suggestions:
"scripts": {
"add": "add-dependencies $npm_config_scope/package.json",
"postadd": "npm i",
},
"devDependencies": {
"add-dependencies": "^1.1.0"
},
Then I can do:
npm run add --scope=packages/app express
npm run add --scope=packages/core eslint jest -D
This works fine for installing external packages. To install my own packages that lives inside the monorepo, I still have to manually edit the package.json, otherwise I get the package not found error.

Prepublish not working as expected

I am testing on npm scripts to build my project dependency.
My idea comes from https://github.com/ParsePlatform/parse-server which impressed me by code in repository doesn't mean code in node_modules after npm install.
Below is my testmodule structure
src/index.js
package.json
and this is my package.json content
{
"name": "testmodule",
"version": "1.0.0",
"description": "",
"main": "lib/index.js",
"scripts": {
"build": "babel src/ -d lib/",
"prepublish": "npm run build"
},
"devDependencies": {
"babel-cli": "^6.18.0",
"babel-core": "^6.18.2"
}
}
and this is structure I expect after run npm install testmodule
node_modules/testmodule/lib/index.js
node_modules/testmodule/package.json
which is src folder should not be here.
But after I run npm install, it is exactly the same as when I push to my git repository.
Please take note that I am using GitLab in my own server.
So my questions are:
Is there anything that i'm missing to make prepublish run?
Which part of parse-server code makes the src folder and other files not there after install?
How are you running npm install?
According to the documentation on npm scripts, the prepublish script is run "BEFORE the package is published. (Also run on local npm install without any arguments.)". It seems clear that the prepublish script is only run on npm publish or npm install <local directory>.
If you are trying to install directly from your local gitlab server via a URL, this will not work - the script will not be run. The solution would be to install locally unless you're willing to open source your package & push it to the npm repository or pay for a private npm repository. This is what I have done during development of packages before they're ready to be made public.

Resources