npminstall
Make npm install
fast and handy.
Node.js and Python required
- Node.js >= 14.x
- Python >= 3.x
Use as Cli
Install
$ npm install npminstall -g
Usage
In cnpm
It is integrated in cnpm.
$ npm install cnpm -g
# will use npminstall
$ cnpm install
npminstall
Usage:
npminstall
npminstall <pkg>
npminstall <pkg>@<tag>
npminstall <pkg>@<version>
npminstall <pkg>@<version range>
npminstall <alias>@npm:<name>
npminstall <folder>
npminstall <tarball file>
npminstall <tarball url>
npminstall <git:// url>
npminstall <github username>/<github project>
Can specify one or more: npm install ./foo.tgz bar@stable /some/folder
If no argument is supplied, installs dependencies from ./package.json.
Options:
--production: won't install devDependencies
--save, --save-dev, --save-optional: save installed dependencies into package.json
-g, --global: install devDependencies to global directory which specified in `$ npm config get prefix`
-r, --registry: specify custom registry
-c, --china: specify in china, will automatically using chinese npm registry and other binary's mirrors
-d, --detail: show detail log of installation
--trace: show memory and cpu usages traces of installation
--ignore-scripts: ignore all preinstall / install and postinstall scripts during the installation
--no-optional: ignore optionalDependencies during the installation
--forbidden-licenses: forbit install packages which used these licenses
--engine-strict: refuse to install (or even consider installing) any package that claims to not be compatible with the current Node.js version.
--flatten: flatten dependencies by matching ancestors dependencies
--registry-only: make sure that all packages are installed from registry. Any package that is installed from remote(e.g.: git, remote url) will lead to a failure of installation.
--cache-strict: use disk cache even on production env
npmuninstall
Usage:
npmuninstall <pkg>
npmuninstall <pkg>@<version>
npmuninstall <pkg>@<version> [<pkg>@<version>]
npminstall <alias>@npm:<name>
npmlink
Usage:
npmlink <folder>
Use as Lib
Install
$ npm install npminstall --save
Usage
const npminstall = require('npminstall');
(async () => {
await npminstall({
// install root dir
root: process.cwd(),
// optional packages need to install, default is package.json's dependencies and devDependencies
// pkgs: [
// { name: 'foo', version: '~1.0.0' },
// ],
// install to specific directory, default to root
// targetDir: '/home/admin/.global/lib',
// link bin to specific directory (for global install)
// binDir: '/home/admin/.global/bin',
// registry, default is https://registry.npmjs.org
// registry: 'https://registry.npmjs.org',
// debug: false,
// storeDir: root + 'node_modules',
// ignoreScripts: true, // ignore pre/post install scripts, default is `false`
// forbiddenLicenses: forbit install packages which used these licenses
});
})().catch(err => {
console.error(err);
});
Support Features
- <input checked="" disabled="" type="checkbox"> all types of npm package
- <input checked="" disabled="" type="checkbox"> a) a folder containing a program described by a package.json file (
npm install file:eslint-rule
) - <input checked="" disabled="" type="checkbox"> b) a gzipped tarball containing (a) (
npm install ./rule.tgz
) - <input checked="" disabled="" type="checkbox"> c) a url that resolves to (b) (
npm install https://github.com/indexzero/forever/tarball/v0.5.6
) - <input checked="" disabled="" type="checkbox"> d) a <name>@<version> that is published on the registry with (c)
- <input checked="" disabled="" type="checkbox"> e) a <name>@<tag> (see npm-dist-tag) that points to (d)
- <input checked="" disabled="" type="checkbox"> f) a <name> that has a "latest" tag satisfying (e)
- <input checked="" disabled="" type="checkbox"> g) a <git remote url> that resolves to (a) (
npm install git://github.com/timaschew/cogent#fix-redirects
)
- <input checked="" disabled="" type="checkbox"> a) a folder containing a program described by a package.json file (
- <input checked="" disabled="" type="checkbox"> All platform support
- <input checked="" disabled="" type="checkbox"> global install (
-g, --global
) - <input checked="" disabled="" type="checkbox">
preinstall
,install
,postinstall
scripts - <input checked="" disabled="" type="checkbox"> node-gyp@9, only support Python@3
- <input checked="" disabled="" type="checkbox"> node-pre-gyp
- <input checked="" disabled="" type="checkbox"> bin (yo@1.6.0, fsevents@1.0.6)
- <input checked="" disabled="" type="checkbox"> scoped package
- <input checked="" disabled="" type="checkbox"> bundleDependencies / bundledDependencies (node-pre-gyp@0.6.19, fsevents@1.0.6)
- <input checked="" disabled="" type="checkbox"> optionalDependencies (pm2@1.0.0)
- <input checked="" disabled="" type="checkbox"> peerDependencies (co-defer@1.0.0, co-mocha@1.1.2, estraverse-fb@1.3.1)
- <input checked="" disabled="" type="checkbox"> deprecate message
- <input checked="" disabled="" type="checkbox">
--production
mode - <input checked="" disabled="" type="checkbox">
save
,save-dev
,save-optional
- <input checked="" disabled="" type="checkbox"> support
ignore-scripts
- <input checked="" disabled="" type="checkbox"> uninstall
- <input checked="" disabled="" type="checkbox"> resolutions
- <input checked="" disabled="" type="checkbox"> npm alias
- <input checked="" disabled="" type="checkbox"> npm workspaces
Different with NPM
This project is inspired by pnpm, and has a similar store structure like pnpm. You can read pnpm vs npm to see the different with npm.
Limitations
- You can't install from shrinkwrap(and don't want to support for now).
- Peer dependencies are a little trickier to deal with(see rule 1 below).
- You can't publish npm modules with bundleDependencies managed by npminstall(because of rule 2 below).
npminstall
will collect all postinstall scripts, and execute them until all dependencies installed.- If last install failed, better to cleanup node_modules directory before retry.
node_modules
directory
Two rules:
- The latest version of modules will link at
options.storeDir
'snode_modules
. - Module's dependencies will link at module's
node_modules
.
e.g.:
- app:
{ "dependencies": { "debug": "2.2.0" } }
(root) - debug@2.2.0:
{ "dependencies": { "ms": "0.7.1" } }
app/
├── package.json
└── node_modules
├── _debug@2.2.0@debug
│ ├── node_modules
│ │ └── ms -> ../../_ms@0.7.1@ms
├── _ms0.7.1@ms
├── debug -> _debug@2.2.0@debug
└── ms -> _ms@0.7.1@ms # for peerDependencies
flattened vs nested
npminstall will always try to install the maximal matched version of semver:
root/
koa@1.1.0
mod/
koa@~1.1.0
# will install two different version of koa when use npminstall.
you can enable flatten mode by --flatten
flag, in this mod, npminstall will try to use ancestors' dependencies to minimize the dependence-tree.
root/
koa@1.1.0
mod/
koa@~1.1.0
root/
koa@1.1.0
mod/
koa@^1.1.0
# both the same version: 1.1.0
root/
koa@~1.1.0
mod/
koa@^1.1.0
# both the same version: 1.1.2
root/
mod/
koa@^1.1.0
moe/
koa@~1.1.0
# two different versions
npminstall will always treat n.x
and n.m.x
as flattened
root/
koa@1.1.0
mod/
koa@1.1.x
both the same version: 1.1.0
root/
koa@~1.1.0
mod/
koa@1.x
both the same version: 1.1.2
Resolutions
support selective version resolutions like yarn. which lets you define custom package versions inside your dependencies through the resolutions field in your package.json
file.
resolutions also supports npm alias. It's a workaround feature to fix some archived/inactive/ package by uploading your own bug-fixed version to npm registry.
see use case at unittest package.json.
Benchmarks
https://github.com/cnpm/npminstall-benchmark
cnpmjs.org install
cli | real | user | sys |
---|---|---|---|
npminstall | 0m10.908s | 0m8.733s | 0m4.282s |
npminstall with cache | 0m8.815s | 0m7.492s | 0m3.644s |
npminstall --no-cache | 0m10.279s | 0m8.255s | 0m3.932s |
pnpm | 0m13.509s | 0m11.650s | 0m4.443s |
npm | 0m28.171s | 0m26.085s | 0m8.219s |
npm with cache | 0m20.939s | 0m19.415s | 0m6.302s |
pnpm benchmark
see https://github.com/pnpm/pnpm#benchmark
npminstall babel-preset-es2015 browserify chalk debug minimist mkdirp
real 0m8.929s user 0m5.606s sys 0m2.913s
pnpm i babel-preset-es2015 browserify chalk debug minimist mkdirp
real 0m12.998s user 0m8.653s sys 0m3.362s
npm i babel-preset-es2015 browserify chalk debug minimist mkdirp
real 1m4.729s user 0m55.589s sys 0m23.135s
License
Contributors
This project follows the git-contributor spec, auto updated at Sat Mar 25 2023 22:23:53 GMT+0800
.