ディレクトリ
npm には 2 つの意味があります。最初の層の意味は、Node.js のオープン モジュール登録および管理システムであり、Web サイトのアドレスは http://npmjs.org です。もう 1 つの意味は、Node.js のデフォルトのモジュール マネージャーです。これは、ノード モジュールのインストールと管理に使用されるコマンド ライン ソフトウェアです。
npm を個別にインストールする必要はありません。ノードをインストールすると、npmも一緒にインストールされます。ただし、node に付属の npm は最新バージョンではない可能性があります。次のコマンドを使用して最新バージョンに更新することをお勧めします。
$ npm install npm@latest -g
上記のコマンドの最後のパラメータが npm であるのは、npm 自体も Node.js のモジュールであるためです。
Node をインストールした後、次のコマンドを使用して npm ヘルプ ファイルを表示できます。
# npm命令列表$ npm help# 各个命令的简单用法$ npm -l
次のコマンドは、npm のバージョンと構成をそれぞれ表示します。
$ npm -v$ npm config list -l
npm init は、新しい package.json ファイルを初期化して生成するために使用されます。デフォルト設定を変更する必要がないと思われる場合は、Enter キーを押し続けてください。
-f (強制を表す) または -y (はいを表す) を使用すると、質問フェーズがスキップされ、新しい package.json ファイルが直接生成されます。
$ npm init -y
npm set は環境変数を設定するために使用されます。
$ npm set init-author-name 'Your name'$ npm set init-author-email 'Your email'$ npm set init-author-url 'http://yourdomain.com'$ npm set init-license 'MIT'
上記のコマンドは、今後 npm init が実行されるときに、npm init の作成者名、電子メール、ホームページ、およびライセンスのフィールドのデフォルト値を設定するのと同じです。 package.json はデフォルト値を自動的に書き込みます。この情報はユーザーのホーム ディレクトリの ~/.npmrc ファイルに保存されるため、ユーザーは項目ごとに情報を入力する必要がありません。プロジェクトに異なる設定がある場合は、そのプロジェクトに対して npm config を実行できます。
$ npm set save-exact true
上記のコマンドがモジュールを追加するように設定されている場合、package.json はオプションのバージョン範囲ではなく、モジュールの正確なバージョンを記録します。
npm info コマンドは、各モジュールの固有の情報を表示できます。たとえば、アンダースコアモジュールに関する情報を表示します。
$ npm info underscore{ name: 'underscore', description: 'JavaScript\'s functional programming helper library.', 'dist-tags': { latest: '1.5.2', stable: '1.5.2' }, repository: { type: 'git', url: 'git://github.com/jashkenas/underscore.git' }, homepage: 'http://underscorejs.org', main: 'underscore.js', version: '1.5.2', devDependencies: { phantomjs: '1.9.0-1' }, licenses: { type: 'MIT', url: 'https://raw.github.com/jashkenas/underscore/master/LICENSE' }, files: [ 'underscore.js', 'underscore-min.js', 'LICENSE' ], readmeFilename: 'README.md'}
上記のコマンドは、アンダースコア モジュールの詳細を含む JavaScript オブジェクトを返します。このオブジェクトの各メンバーは、info コマンドから直接クエリできます。
$ npm info underscore descriptionJavaScript's functional programming helper library.$ npm info underscore homepagehttp://underscorejs.org$ npm info underscore version1.5.2
npm search コマンドは、npm リポジトリを検索するために使用されます。このコマンドの後に文字列または正規表現を続けることができます。
$ npm search <搜索词>
これが例です。
$ npm search node-gyp// NAME DESCRIPTION// autogypi Autogypi handles dependencies for node-gyp projects.// grunt-node-gyp Run node-gyp commands from Grunt.// gyp-io Temporary solution to let node-gyp run `rebuild` under…// ...
npm list コマンドは、現在のプロジェクトによってインストールされたすべてのモジュールと、それらが依存するモジュールをツリー構造でリストします。
$ npm list
グローバルにインストールされているモジュールを一覧表示するグローバル パラメーターを追加します。
$ npm list -global
npm list コマンドでは、個々のモジュールを一覧表示することもできます。
$ npm list underscore
Node モジュールは、npm install コマンドを使用してインストールされます。
各モジュールは、「グローバルにインストール」または「ローカルにインストール」できます。 「グローバル インストール」とは、各プロジェクトから呼び出すことができるモジュールをシステム ディレクトリにインストールすることを指します。一般に、グローバル インストールは、npm や grunt などのツール モジュールに対してのみ機能します。 「ローカル インストール」とは、現在のプロジェクトの node_modules サブディレクトリにモジュールをダウンロードすることを指します。その後、モジュールはプロジェクト ディレクトリ内でのみ呼び出すことができます。
# 本地安装$ npm install <package name># 全局安装$ sudo npm install -global <package name>$ sudo npm install -g <package name>
npm install は、Github コード リポジトリ アドレスの直接入力もサポートしています。
$ npm install git://github.com/package/path.git$ npm install git://github.com/package/path.git#0.1.0
インストール前に、npm install はまず、指定されたモジュールが node_modules ディレクトリに既に存在するかどうかを確認します。存在する場合、リモート リポジトリにすでに新しいバージョンがある場合でも、再インストールされません。
以前にモジュールがインストールされているかどうかに関係なく、npm でモジュールの再インストールを強制したい場合は、-f または --force パラメーターを使用できます。
$ npm install <packageName> --force
すべてのモジュールを強制的に再インストールしたい場合は、node_modules ディレクトリを削除し、npm install を再度実行します。
$ rm -rf node_modules$ npm install
インストール コマンドでは、常に最新バージョンのモジュールがインストールされます。特定のバージョンのモジュールをインストールする場合は、次のようにすることができます。モジュール名とバージョン番号の後に @ を追加します。
$ npm install sax@latest$ npm install sax@0.1.1$ npm install sax@">=0.1.0 <0.2.0"
--save-exact パラメーターを使用すると、インストールされたモジュールの正確なバージョンが package.json ファイルで指定されます。
$ npm install readable-stream --save --save-exact
install コマンドは、さまざまなパラメーターを使用して、インストールされるモジュールの依存関係の性質、つまり、packages.json ファイルにどの項目が表示されるかを指定できます。
$ npm install sax --save$ npm install node-tap --save-dev# 或者$ npm install sax -S$ npm install node-tap -D
モジュールのベータ版をインストールする場合は、次のコマンドを使用する必要があります。
# 安装最新的beta版$ npm install <module-name>@beta (latest beta)# 安装指定的beta版$ npm install <module-name>@1.3.1-beta.3
npm install默认会安装dependencies字段和devDependencies字段中的所有模块,如果使用production参数,可以只安装dependencies字段的模块。
$ npm install --production# 或者$ NODE_ENV=production npm install
一旦安装了某个模块,就可以在代码中用require命令调用这个模块。
var backbone = require('backbone')console.log(backbone.VERSION)
默认情况下,Npm全局模块都安装在系统目录(比如 /usr/local/lib/),普通用户没有写入权限,需要用到 sudo命令。这不是很方便,我们可以在没有root权限的情况下,安装全局模块。
首先,在主目录下新建配置文件 .npmrc,然后在该文件中将 prefix变量定义到主目录下面。
prefix = /home/yourUsername/npm
然后在主目录下新建 npm子目录。
$ mkdir ~/npm
此后,全局安装的模块都会安装在这个子目录中,npm也会到 ~/npm/bin目录去寻找命令。
最后,将这个路径在 .bash_profile文件(或 .bashrc文件)中加入PATH变量。
export PATH=~/npm/bin:$PATH
npm update命令可以更新本地安装的模块。
# 升级当前项目的指定模块$ npm update [package name]# 升级全局安装的模块$ npm update -global [package name]
它会先到远程仓库查询最新版本,然后查询本地版本。如果本地版本不存在,或者远程版本较新,就会安装。
使用 -S或 --save参数,可以在安装的时候更新 package.json里面模块的版本号。
// 更新之前的package.jsondependencies: { dep1: "^1.1.1"}// 更新之后的package.jsondependencies: { dep1: "^1.2.2"}
注意,从npm v2.6.1 开始, npm update只更新顶层模块,而不更新依赖的依赖,以前版本是递归更新的。如果想取到老版本的效果,要使用下面的命令。
$ npm --depth 9999 update
npm uninstall命令,卸载已安装的模块。
$ npm uninstall [package name]# 卸载全局模块$ npm uninstall [package name] -global
npm不仅可以用于模块管理,还可以用于执行脚本。 package.json文件有一个 scripts字段,可以用于指定脚本命令,供npm直接调用。
{ "name": "myproject", "devDependencies": { "jshint": "latest", "browserify": "latest", "mocha": "latest" }, "scripts": { "lint": "jshint **.js", "test": "mocha test/" }}
上面代码中, scripts字段指定了两项命令 lint和 test。命令行输入 npm run-script lint或者 npm run lint,就会执行 jshint **.js,输入 npm run-script test或者 npm run test,就会执行 mocha test/。 npm run是 npm run-script的缩写,一般都使用前者,但是后者可以更好地反应这个命令的本质。
npm run命令会自动在环境变量 $PATH添加 node_modules/.bin目录,所以 scripts字段里面调用命令时不用加上路径,这就避免了全局安装NPM模块。
npm内置了两个命令简写, npm test等同于执行 npm run test, npm start等同于执行 npm run start。
npm run会创建一个Shell,执行指定的命令,并临时将 node_modules/.bin加入PATH变量,这意味着本地模块可以直接运行。
举例来说,你执行ESLint的安装命令。
$ npm i eslint --save-dev
运行上面的命令以后,会产生两个结果。首先,ESLint被安装到当前目录的 node_modules子目录;其次, node_modules/.bin目录会生成一个符号链接 node_modules/.bin/eslint,指向ESLint模块的可执行脚本。
然后,你就可以在 package.json的 script属性里面,不带路径的引用 eslint这个脚本。
{ "name": "Test Project", "devDependencies": { "eslint": "^1.10.3" }, "scripts": { "lint": "eslint ." }}
等到运行 npm run lint的时候,它会自动执行 ./node_modules/.bin/eslint .。
如果直接运行 npm run不给出任何参数,就会列出 scripts属性下所有命令。
$ npm runAvailable scripts in the user-service package: lint jshint **.js test mocha test/
下面是另一个 package.json文件的例子。
"scripts": { "watch": "watchify client/main.js -o public/app.js -v", "build": "browserify client/main.js -o public/app.js", "start": "npm run watch & nodemon server.js", "test": "node test/all.js"},
上面代码在 scripts项,定义了四个别名,每个别名都有对应的脚本命令。
$ npm run watch$ npm run build$ npm run start$ npm run test
其中, start和 test属于特殊命令,可以省略 run。
$ npm start$ npm test
如果希望一个操作的输出,是另一个操作的输入,可以借用Linux系统的管道命令,将两个操作连在一起。
"build-js": "browserify browser/main.js | uglifyjs -mc > static/bundle.js"
但是,更方便的写法是引用其他 npm run命令。
"build": "npm run build-js && npm run build-css"
上面的写法是先运行 npm run build-js,然后再运行 npm run build-css,两个命令中间用 &&连接。如果希望两个命令同时平行执行,它们中间可以用 &连接。
下面是一个流操作的例子。
"devDependencies": { "autoprefixer": "latest", "cssmin": "latest"},"scripts": { "build:css": "autoprefixer -b 'last 2 versions' < assets/styles/main.css | cssmin > dist/main.css"}
写在 scripts属性中的命令,也可以在 node_modules/.bin目录中直接写成bash脚本。下面是一个bash脚本。
#!/bin/bashcd site/mainbrowserify browser/main.js | uglifyjs -mc > static/bundle.js
假定上面的脚本文件名为build.sh,并且权限为可执行,就可以在scripts属性中引用该文件。
"build-js": "bin/build.sh"
npm run命令还可以添加参数。
"scripts": { "test": "mocha test/"}
上面代码指定 npm test,实际运行 mocha test/。如果要通过 npm test命令,将参数传到mocha,则参数之前要加上两个连词线。
$ npm run test -- anothertest.js# 等同于$ mocha test/ anothertest.js
上面命令表示,mocha要运行所有 test子目录的测试脚本,以及另外一个测试脚本 anothertest.js。
npm run本身有一个参数 -s,表示关闭npm本身的输出,只输出脚本产生的结果。
// 输出npm命令头$ npm run test// 不输出npm命令头$ npm run -s test
scripts字段的脚本命令,有一些最佳实践,可以方便开发。首先,安装 npm-run-all模块。
$ npm install npm-run-all --save-dev
这个模块用于运行多个 scripts脚本命令。
# 继发执行$ npm-run-all build:html build:js# 等同于$ npm run build:html && npm run build:js# 并行执行$ npm-run-all --parallel watch:html watch:js# 等同于$ npm run watch:html & npm run watch:js# 混合执行$ npm-run-all clean lint --parallel watch:html watch:js# 等同于$ npm-run-all clean lint$ npm-run-all --parallel watch:html watch:js# 通配符$ npm-run-all --parallel watch:*
(1)start脚本命令
start脚本命令,用于启动应用程序。
"start": "npm-run-all --parallel dev serve"
上面命令并行执行 dev脚本命令和 serve脚本命令,等同于下面的形式。
$ npm run dev & npm run serve
如果start脚本没有配置, npm start命令默认执行下面的脚本,前提是模块的根目录存在一个server.js文件。
$ node server.js
(2)dev脚本命令
dev脚本命令,规定开发阶段所要做的处理,比如构建网页资源。
"dev": "npm-run-all dev:*"
上面命令用于继发执行所有 dev的子命令。
"predev:sass": "node-sass --source-map src/css/hoodie.css.map --output-style nested src/sass/base.scss src/css/hoodie.css"
上面命令将sass文件编译为css文件,并生成source map文件。
"dev:sass": "node-sass --source-map src/css/hoodie.css.map --watch --output-style nested src/sass/base.scss src/css/hoodie.css"
上面命令会监视sass文件的变动,只要有变动,就自动将其编译为css文件。
"dev:autoprefix": "postcss --use autoprefixer --autoprefixer.browsers \"> 5%\" --output src/css/hoodie.css src/css/hoodie.css"
上面命令为css文件加上浏览器前缀,限制条件是只考虑市场份额大于5%的浏览器。
(3)serve脚本命令
serve脚本命令用于启动服务。
"serve": "live-server dist/ --port=9090"
上面命令启动服务,用的是 live-server模块,将服务启动在9090端口,展示 dist子目录。
live-server模块有三个功能。
以前,上面三个功能需要三个模块来完成: http-server、 live-reload和 opener,现在只要 live-server一个模块就够了。
(4)test脚本命令
test脚本命令用于执行测试。
"test": "npm-run-all test:*","test:lint": "sass-lint --verbose --config .sass-lint.yml src/sass/*"
上面命令规定,执行测试时,运行 lint脚本,检查脚本之中的语法错误。
(5)prod脚本命令
prod脚本命令,规定进入生产环境时需要做的处理。
"prod": "npm-run-all prod:*","prod:sass": "node-sass --output-style compressed src/sass/base.scss src/css/prod/hoodie.min.css","prod:autoprefix": "postcss --use autoprefixer --autoprefixer.browsers "> 5%" --output src/css/prod/hoodie.min.css src/css/prod/hoodie.min.css"
上面命令将sass文件转为css文件,并加上浏览器前缀。
(6)help脚本命令
help脚本命令用于展示帮助信息。
"help": "markdown-chalk --input DEVELOPMENT.md"
上面命令之中, markdown-chalk模块用于将指定的markdown文件,转为彩色文本显示在终端之中。
(7)docs脚本命令
docs脚本命令用于生成文档。
"docs": "kss-node --source src/sass --homepage ../../styleguide.md"
上面命令使用 kss-node模块,提供源码的注释生成markdown格式的文档。
npm run为每条命令提供了 pre-和 post-两个钩子(hook)。以 npm run lint为例,执行这条命令之前,npm会先查看有没有定义prelint和postlint两个钩子,如果有的话,就会先执行 npm run prelint,然后执行 npm run lint,最后执行 npm run postlint。
{ "name": "myproject", "devDependencies": { "eslint": "latest" "karma": "latest" }, "scripts": { "lint": "eslint --cache --ext .js --ext .jsx src", "test": "karma start --log-leve=error karma.config.js --single-run=true", "pretest": "npm run lint", "posttest": "echo 'Finished running tests'" }}
上面代码是一个 package.json文件的例子。如果执行 npm test,会按下面的顺序执行相应的命令。
如果执行过程出错,就不会执行排在后面的脚本,即如果prelint脚本执行出错,就不会接着执行lint和postlint脚本。
下面是一个例子。
{ "test": "karma start", "test:lint": "eslint . --ext .js --ext .jsx", "pretest": "npm run test:lint"}
上面代码中,在运行 npm run test之前,会自动检查代码,即运行 npm run test:lint命令。
下面是一些常见的 pre-和 post-脚本。
对于最后一个 npm restart命令,如果没有设置 restart脚本, prerestart和 postrestart会依次执行stop和start脚本。
另外,不能在 pre脚本之前再加 pre,即 prepretest脚本不起作用。
注意,即使Npm可以自动运行 pre和 post脚本,也可以手动执行它们。
$ npm run prepublish
下面是 post install的例子。
{ "postinstall": "node lib/post_install.js"}
上面的这个命令,主要用于处理从Git仓库拉下来的源码。比如,有些源码是用TypeScript写的,可能需要转换一下。
下面是 publish钩子的一个例子。
{ "dist:modules": "babel ./src --out-dir ./dist-modules", "gh-pages": "webpack", "gh-pages:deploy": "gh-pages -d gh-pages", "prepublish": "npm run dist:modules", "postpublish": "npm run gh-pages && npm run gh-pages:deploy"}
上面命令在运行 npm run publish时,会先执行Babel编译,然后调用Webpack构建,最后发到Github Pages上面。
以上都是npm相关操作的钩子,如果安装某些模块,还能支持Git相关的钩子。下面以 husky模块为例。
$ npm install husky --save-dev
安装以后,就能在 package.json添加 precommit、 prepush等钩子。
{ "scripts": { "lint": "eslint yourJsFiles.js", "precommit": "npm run test && npm run lint", "prepush": "npm run test && npm run lint", "...": "..." }}
类似作用的模块还有 pre-commit、 precommit-hook等。
scripts字段可以使用一些内部变量,主要是package.json的各种字段。
比如,package.json的内容是 {"name":"foo", "version":"1.2.5"},那么变量 npm_package_name的值是foo,变量 npm_package_version的值是1.2.5。
{ "scripts":{ "bundle": "mkdir -p build/$npm_package_version/" }}
运行 npm run bundle以后,将会生成 build/1.2.5/子目录。
config字段也可以用于设置内部字段。
"name": "fooproject", "config": { "reporter": "xunit" }, "scripts": { "test": "mocha test/ --reporter $npm_package_config_reporter" }
上面代码中,变量 npm_package_config_reporter对应的就是reporter。
npm的通配符的规则如下。
开发Npm模块的时候,有时我们会希望,边开发边试用。但是,常规情况下,使用一个模块,需要将其安装到 node_modules目录之中,这对于开发中的模块,显然非常不方便。 npm link就能起到这个作用,建立一个符号链接,在全局的 node_modules目录之中,生成一个符号链接,指向模块的本地目录。
为了理解 npm link,请设想这样一个场景。你开发了一个模块 myModule,目录为 src/myModule,你自己的项目 myProject要用到这个模块,项目目录为 src/myProject。每一次,你更新 myModule,就要用 npm publish命令发布,然后切换到项目目录,使用 npm update更新模块。这样显然很不方便,如果我们可以从项目目录建立一个符号链接,直接连到模块目录,就省去了中间步骤,项目可以直接使用最新版的模块。
首先,在模块目录( src/myModule)下运行 npm link命令。
src/myModule$ npm link
上面的命令会在Npm的全局模块目录内,生成一个符号链接文件,该文件的名字就是 package.json文件中指定的文件名。
/path/to/global/node_modules/myModule -> src/myModule
这个时候,已经可以全局调用 myModule模块了。但是,如果我们要让这个模块安装在项目内,还要进行下面的步骤。
切换到项目目录,再次运行 npm link命令,并指定模块名。
src/myProject$ npm link myModule
上面命令等同于生成了本地模块的符号链接。
src/myProject/node_modules/myModule -> /path/to/global/node_modules/myModule
然后,就可以在你的项目中,加载该模块了。
var myModule = require('myModule');
这样一来, myModule的任何变化,都可以直接反映在 myProject项目之中。但是,这样也出现了风险,任何在 myProject目录中对 myModule的修改,都会反映到模块的源码中。
如果你的项目不再需要该模块,可以在项目目录内使用 npm unlink命令,删除符号链接。
src/myProject$ npm unlink myModule
npm bin命令显示相对于当前目录的,Node模块的可执行脚本所在的目录(即 .bin目录)。
# 项目根目录下执行$ npm bin./node_modules/.bin
npm adduser用于在npmjs.com注册一个用户。
$ npm adduserUsername: YOUR_USER_NAMEPassword: YOUR_PASSWORDEmail: YOUR_EMAIL@domain.com
npm publish用于将当前模块发布到 npmjs.com。执行之前,需要向 npmjs.com申请用户名。
$ npm adduser
如果已经注册过,就使用下面的命令登录。
$ npm login
登录以后,就可以使用 npm publish命令发布。
$ npm publish
如果当前模块是一个beta版,比如 1.3.1-beta.3,那么发布的时候需要使用 tag参数。
$ npm publish --tag beta
如果发布私有模块,模块初始化的时候,需要加上 scope参数。只有npm的付费用户才能发布私有模块。
$ npm init --scope=<yourscope>
如果你的模块是用ES6写的,那么发布的时候,最好转成ES5。首先,需要安装Babel。
$ npm install --save-dev babel-cli@6 babel-preset-es2015@6
然后,在 package.json里面写入 build脚本。
"scripts": { "build": "babel source --presets babel-preset-es2015 --out-dir distribution", "prepublish": "npm run build"}
运行上面的脚本,会将 source目录里面的ES6源码文件,转为 distribution目录里面的ES5源码文件。然后,在项目根目录下面创建两个文件 .npmignore和 .gitignore,分别写入以下内容。
// .npmignoresource// .gitignorenode_modulesdistribution
如果想废弃某个版本的模块,可以使用 npm deprecate命令。
$ npm deprecate my-thing@"< 0.2.3" "critical bug fixed in v0.2.3"
运行上面的命令以后,小于 0.2.3版本的模块的 package.json都会写入一行警告,用户安装这些版本时,这行警告就会在命令行显示。
模块的维护者可以发布新版本。 npm owner命令用于管理模块的维护者。
# 列出指定模块的维护者$ npm owner ls <package name># 新增维护者$ npm owner add <user> <package name># 删除维护者$ npm owner rm <user> <package name>