Reputation: 1147
Suppose that somewhere in my package.json
I have:
"dependencies": {
"bower": "1.0.0",
// zillion other dependencies
}
Is there a way to make npm install only [email protected] from my package.json
? Like so: npm install --only bower
.
My goal is to make npm install
and bower install
run simultaneously.
Upvotes: 40
Views: 43760
Reputation: 10386
I see that the most upvoted solution doesn't work for latest node versions. Even though it also provides an alternative solution updated for 2023, I'd rather work around with something simpler, such as:
mv package.json package.json.bkp
npm install --no-save [email protected]
mv package.json.bkp package.json
Upvotes: 5
Reputation: 5912
I recently had a similar requirement – I needed to create a task in a build system that would install a single package and execute its binary, not caring about the rest of the packages. Since this pops up as a first result in Google search, I’m sharing what I’ve learned here.
Because each task runs in isolation in the build system, I could basically do whatever I wanted to when it comes to deleting files. With this in mind, here’s what worked for me:
node_modules
are not present. If they are, just delete them using rm -rf node_modules
.package.json
and package-lock.json
using rm package.json package-lock.json
npm install <package>
Steps 1 and 2 ensure that the created package.json
in step 3 will have no dependencies.
Upvotes: 0
Reputation: 1
You can use the following script to install only one dependency from package.json using pnpm
#!/bin/bash
# Set the package name and dependency type from the command line arguments
PACKAGE_NAME=$1
DEPENDENCY_TYPE=$2
# Get the version of the package from the package.json file
PACKAGE_VERSION="$(node -p "require('./package.json').${DEPENDENCY_TYPE}['${PACKAGE_NAME}']")"
# Print the version for debugging purposes
echo "Installing ${PACKAGE_NAME}@${PACKAGE_VERSION} from ${DEPENDENCY_TYPE}"
# Rename package.json to _package.json
mv package.json _package.json
# Install the package using pnpm
pnpm add "${PACKAGE_NAME}@${PACKAGE_VERSION}"
# Rename _package.json back to package.json
mv _package.json package.json
echo "${PACKAGE_NAME}@${PACKAGE_VERSION} installed successfully from ${DEPENDENCY_TYPE}"
and run it like this:
./scripts/installOnePackage.sh bower dependencies
Upvotes: -1
Reputation: 2082
As @atalantus noted in comment, the accepted answer doesn't work on newer version of NPM. Working solution for newer versions (verified on NPM 6.13.4) is:
npm install --no-package-lock --no-save [email protected]
This will install bower
and all its dependencies, but prevents installation of anything else you might have in package.json
. It also doesn't create or modify existing package-lock.json
.
From npm documentation:
The
--no-package-lock
argument will prevent npm from creating a package-lock.json file. When running with package-lock's disabled npm will not automatically prune your node modules when installing.
--no-save
: Prevents saving todependencies
.
Combining this with Anton Rudeshko's approach to find out version in package.json
, the final solution is:
VERSION_BOWER=`node -p -e "require('./package.json').dependencies.bower"`
npm install --no-package-lock --no-save bower@"$VERSION_BOWER"
Alternative solution I've just used is to temporarily modify package.json
to only keep the dependency you need. That can be done quite easily with help of jq
Given package.json
{
"name": "sample",
"main": "src/index.js",
"dependencies": {
"bower": "1.0.0",
"foo": "^1.2.3",
"bar": "^4.5.6",
},
"devDependencies": {
"baz": "^10.20.30",
}
}
Let's first modify it with jq
to only keep bower
cat package.json| jq 'del(.devDependencies) | .dependencies |= {bower:.bower}'
Gives us
{
"name": "sample",
"main": "src/index.js",
"dependencies": {
"bower": "1.0.0"
}
}
by deleting devDependencies
completely and leaving only bower
in dependencies
.
Next up you would want to overwrite package.json with this new, version, but you can't do it directly like this
cat package.json | jq 'del(.devDependencies) | .dependencies |= {bower:.bower}' > package.json
because the file gets overwritten before it's fully read. Instead you need to buffer the output stream of jq
command, simplest solution just storing it in variable, and then overwriting the original file
updated=`cat package.json | jq 'del(.devDependencies) | .dependencies |= {bower:.bower}'`
echo $updated > package.json
And package.json
now reads:
cat package.json
{
"name": "sample",
"main": "src/index.js",
"dependencies": {
"bower": "1.0.0"
}
}
Run npm install
now and you only install [email protected]
.
Obviously not always we can afford to modify the file, but you could also back-up the original file, etc. Main point is here how to easily modify json file thanks to jq
rather than playing magic tricks with sed
:-)
Upvotes: 21
Reputation:
Seeing as with newer versions of NPM the previous solutions don't work anymore, I came up with this:
npm i -g --prefix=$(pwd) bower # $(pwd) = current directory, UNIX only
node bin/bower
Installing a package globally allows you to specify a "prefix" - a directory where the package will be installed. Here I just put the current directory as the folder I want the package to appear in. In CI, this will probably be your repo root.
Keep in mind this will ignore your package.json version and just download the latest one. If you need a specific version, just use bower@someversion
instead.
An alternative solution is just rm package.json && npm i bower
, or mv package.json _package.json && npm i bower
if you want to restore it later
Upvotes: 3
Reputation: 1147
As a workaround you may use something like:
$ node -pe "require('./package').dependencies.bower"
// → 1.0.0
$ npm install bower@$(node -pe "require('./package').dependencies.bower")
// npm install [email protected]
// or with jq
$ npm install bower@$(< package.json jq -r '.dependencies.bower')
Where -e/--eval
flag evaluates passed string and -p/--print
prints result of eval.
💡 Please consider other answers as well since this one may be outdated.
Upvotes: 14