npm 官方文档:npm-install | npm Docs
npm 模块管理器:npm模块管理器 -- JavaScript 标准参考教程(alpha)
npm 常用命令详解:npm 常用命令详解_vue npm停止-CSDN博客
1. 什么是 NPM
NPM 的全称是 Node Package Manager,是随同 NodeJS 一起安装的包管理和分发工具,它很方便让 JavaScript 开发者下载、安装、上传以及管理已经安装的包。
npm 之于 Node.js ,就像 pip 之于 Python, gem 之于 Ruby, pear 之于 PHP 。
npm 是 Node.js 官方提供的包管理工具,他已经成了 Node.js 包的标准发布平台,用于 Node.js 包的发布、传播、依赖控制。
npm 提供了命令行工具,使你可以方便地下载、安装、升级、删除包,也可以让你作为开发者发布并维护包。
2. 为什么要使用 NPM
npm 是随同 Node.js 一起安装的包管理工具,能解决 Node.js 代码部署上的很多问题,常见的场景有以下几种:
- 允许用户从 npm 服务器下载别人编写的第三方包到本地使用。
- 允许用户从 npm 服务器下载并安装别人编写的命令行程序到本地使用。
- 允许用户将自己编写的包或命令行程序上传到 npm 服务器供别人使用。
npm 的背后,是基于 couchdb 的一个数据库,详细记录了每个包的信息,包括作者、版本、依赖、授权信息等。它的一个很重要的作用就是:将开发者从繁琐的包管理工作(版本、依赖等)中解放出来,更加专注于功能的开发。
3. 如何使用 NPM
npm 安装、升级
npm 不需要单独安装。在安装 Node 的时候,会连带一起安装 npm 。但 Node 附带的 npm 可能不是最新版本,最后用下面的命令,更新到最新版本。
-
$ sudo npm install npm@latest -g # Linux 命令
-
npm install npm -g # Window 系统使用这个命令
-
也就是使用 npm 安装自己。之所以可以这样,是因为 npm 本身与 Node 的其他模块没有区别。
-
$ npm help # 查看 npm 命令列表
-
$ npm -l # 查看各个命令的简单用法
-
$ npm -v # 查看 npm 的版本
-
$ npm config list -l # 查看 npm 的配置
注意:npm install npm@latest -g 安装完之后,如果报错( 报找不到 npm ),可以再执行 curl -L https://npmjs.com/install.sh | sh 即可。。。
常用命令:
npm version 查看 npm 和 node 的版本
npm list --depth=0 [-g] 查看[全局]安装的包
npm root [-g] 查看[全局的]包的安装路径
npm install 安装到指定目录时,需要设置目录,例如:npm config set prefix "f:\node" ,然后再执行 npm install 包名
npm install 到指定目录
默认情况下,在哪个文件夹下运行 npm,npm 就在当前目录创建一个文件夹 node_modules,然后将要安装的程序安装到文件夹 node_modules 里面。 这时候其他路径项目无法引用到该目录下的模块!
如果我们需要自主配置的话
- 1. 在目标目录下建立 "node_global" 及 "node_cache" 两个文件夹。
- 2. 在 cmd 中输入
npm config set prefix "F:\14npm\node_global" // 设置 npm 安装程序时的默认位置
npm config set cache "F:\14npm\node_cache" // 设置 npm 安装程序时的缓存位置
但是这时候还是无法 require 这些模块,需要在环境变量中进行设置!!!!! - 3. 在环境变量中添加 模块保存路径的变量 NODE_PATH(告诉系统 用户下载的全局模块在此处)。新建 NODE_PATH 值为 F:\14npm\node_global\node_modules
- 4. 在 PATH 变量里面,添加 nodejs 路径 ;C:\Program Files\nodejs;
-
5. 最后安装程序命令:$ npm install cheerio -g 需要加上 -g,不加 -g 关键字仍会安装在你运行 npm 的文件夹下
nodejs 安装、升级
- window 系统升级 nodejs 。只能到 nodejs 官网下载 window 安装包来覆盖之前的 nodejs。
- linux 系统升级 nodejs。
首先使用 npm 全局安装一个管理node版本的管理模板n,就是n,不用怀疑。
n 的 github地址: https://github.com/tj/n安装命令: npm i -g n 或者 npm i -g n --force
升级 node 版本,管理板块n的命令有很多
n 10.0.0 # "n 版本号" 升级到指定的版本
n latest # 安装最新的版本
n --stable # 安装最近的稳定版本
执行 node -v 查看版本
n 命令 帮助:n help
-
$ n help
-
Usage: n [options] [COMMAND] [args]
-
Commands:
-
n Display downloaded node versions and install selection
-
n latest Install the latest node release (downloading if necessary)
-
n lts Install the latest LTS node release (downloading if necessary)
-
n <version> Install node <version> (downloading if necessary)
-
n run <version> [args ...] Execute downloaded node <version> with [args ...]
-
n which <version> Output path for downloaded node <version>
-
n exec <vers> <cmd> [args...] Execute command with modified PATH, so downloaded node <version> and npm first
-
n rm <version ...> Remove the given downloaded version(s)
-
n prune Remove all downloaded versions except the installed version
-
n --latest Output the latest node version available
-
n --lts Output the latest LTS node version available
-
n ls Output downloaded versions
-
n ls-remote [version] Output matching versions available for download
-
n uninstall Remove the installed node and npm
-
Options:
-
-V, --version Output version of n
-
-h, --help Display help information
-
-p, --preserve Preserve npm and npx during install of node (requires rsync)
-
-q, --quiet Disable curl output (if available)
-
-d, --download Download only
-
-a, --arch Override system architecture
-
--all ls-remote displays all matches instead of last 20
-
--insecure Turn off certificate checking for https requests (may be needed from behind a proxy server)
-
--use-xz/--no-use-xz Override automatic detection of xz support and enable/disable use of xz compressed node downloads.
-
Aliases:
-
which: bin
-
run: use, as
-
ls: list
-
lsr: ls-remote
-
rm: -
-
lts: stable
-
latest: current
-
Versions:
-
Numeric version numbers can be complete or incomplete, with an optional leading 'v'.
-
Versions can also be specified by label, or codename,
-
and other downloadable releases by <remote-folder>/<version>
-
4.9.1, 8, v6.1 Numeric versions
-
lts Newest Long Term Support official release
-
latest, current Newest official release
-
auto Read version from file: .n-node-version, .node-version, .nvmrc, or package.json
-
boron, carbon Codenames for release streams
-
lts_latest node support aliases
-
and nightly, chakracore-release/latest, rc/10 et al
npm init 初始化一个 package.json 文件
在项目中引导创建一个 package.json 文件,安装包的信息可保持到项目的 package.json 文件中,以便后续的其它的项目开发或者他人合作使用,也说 package.json 在项目中是必不可少的。npm init
用来初始化生成一个新的 package.json 文件。它会向用户提问一系列问题,如果你觉得不用修改默认配置,一路回车就可以了。
如果使用了 -f(代表force)、-y(代表yes),则跳过提问阶段,直接生成一个新的 package.json 文件。
-
用法: npm init [-f|--force|-y|--yes]
-
$ npm init -y
package.json 和 package-lock.json 区别
一、package.json
package.json 是在运行 “ npm init ”时生成的,主要记录项目依赖,有以下结构
- name:项目名,也就是在使用npm init 初始化时取的名字,但是如果使用的是npm init -y 快速初始化的话,那这里的名字就是默认存放这个文件的文件名;
- version:版本号;
- private:希不希望授权别人以任何形式使用私有包或未发布的;
- scripts-serve:是vue的项目启动简写配置;
- scripts-build:是vue的打包操作简写配置;
- dependencies:指定了项目运行时所依赖的模块;
- devDependencies:指定项目开发时所需要的模块,也就是在项目开发时才用得上,一旦项目打包上线了,就将移除这里的第三方模块;
二、package-lock.json
package-lock.json 是在运行 “npm install” 时生成的一个文件,用于记录当前状态下项目中实际安装的各个 package 的版本号、模块下载地址、及这个模块又依赖了哪些依赖。
三、总结区别
为什么有了package.json,还需要 package-lock.json 文件呢?
当项目中已有 package-lock.json 文件,在安装项目依赖时,将以该文件为主进行解析安装指定版本依赖包,而不是使用 package.json 来解析和安装模块。
因为 package 只是指定的版本不够具体,而package-lock 为每个模块及其每个依赖项指定了版本,位置和完整性哈希,所以它每次创建的安装都是相同的。
无论你使用什么设备,或者将来安装它都无关紧要,每次都应该给你相同的结果。
npm help 查看命令帮助
查看某条命令的详细帮助 。基础语法:npm help <term> [<terms..>]
例如:输入 npm help install,系统在默认的浏览器或者默认的编辑器中打开本地 nodejs 安装包的文件/nodejs/node_modules/npm/html/doc/cli/npm-install.html
npm root 查看包的安装路径
输出 node_modules 的路径
$ npm root [-g]
npm config 管理npm的配置路径
基础语法
-
npm config set <key> <value> [-g|--global]
-
npm config get <key>
-
npm config delete <key>
-
npm config list
-
npm config edit
-
npm get <key>
-
npm set <key> <value> [-g|--global]
对于 config 这块用得最多应该是设置代理,解决 npm 安装一些模块失败的问题。
将指定的$dir
目录,设为模块的全局安装目录。如果当前有这个目录的写权限,那么运行npm install
的时候,就不再需要sudo
命令授权
$ npm config set prefix $dir
命令使得 npm install --save
和 npm install --save-dev
安装新模块时,允许的版本范围从克拉符号(^
)改成波浪号(~
),即从允许小版本升级,变成只允许补丁包的升级。
$ npm config set save-prefix ~
命令指定使用 npm init
时,生成的 package.json
文件的字段默认值。
-
$ npm config set init.author.name $name
-
$ npm config set init.author.email $email
设置代理示例:在公司内网,因为公司的防火墙原因,无法完成任何模块的安装时,可以执行下面命令
npm config set proxy=http://xxx
又如国内的网络环境问题,某官方的 IP 可能被和谐了,幸好国内有好心人,搭建了镜像,此时我们简单设置镜像
npm config set registry="http://r.cnpmjs.org"
也可以临时配置,如安装淘宝镜像
npm install -g cnpm --registry=https://registry.npm.taobao.org
npm cache 管理模块的缓存
基础语法
-
npm cache add <tarball file>
-
npm cache add <folder>
-
npm cache add <tarball url>
-
npm cache add <name>@<version>
-
npm cache ls [<path>]
-
npm cache clean [<path>]
最常用命令无非清除 npm 本地缓存:npm cache clean
npm start 启动模块
基础语法:npm start [-- <args>]
该命令写在 package.json 文件 scripts 的 start 字段中,可以自定义命令来配置一个服务器环境和安装一系列的必要程序,如
-
"scripts": {
-
"start": "gulp -ws" }
此时在 cmd 中输入 npm start 命令相当于执行 gulpfile.js 文件自定义的 watch 和 server 命令。
如果 package.json 文件没有设置 start,则将直接启动 node server.js
npm stop 停止模块
基础语法:npm stop [-- <args>]
npm restart 重新启动模块
基础语法:npm restart [-- <args>]
npm test 测试模块
基础语法
-
npm test [-- <args>]
-
npm tst [-- <args>]
该命令写在 package.json 文件 scripts 的 test 字段中,可以自定义该命令来执行一些操作,如
-
"scripts": {
-
"test": "gulp release" },
此时在 cmd 中输入 npm test 命令相当于执行 gulpfile.js 文件自定义的 release 命令。
npm version 查看模块版本
基础语法
-
npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]
-
npm [-v | --version] to print npm version
-
npm view <pkg> version to view a package's published version
-
npm ls to inspect current package/dependency versions
查看模块的版本:npm version
npm view 查看模块的注册信息
-
基础语法
-
npm view [<@scope>/]<name>[@<version>] [<field>[.<subfield>]...]
-
aliases: info, show, v
-
npm view gulp dependencies 查看模块 gulp 的依赖关系
-
npm view gulp repository.url 查看模块 gulp 的源文件地址
-
npm view npm contributors 查看模块 npm 的贡献者,包含邮箱地址
npm adduser 用户登录
基础语法:npm adduser [--registry=url] [--scope=@orgname] [--always-auth]
发布模板到 npm 社区前需要先登录,然后再进入发布的操作
npm publish 发布模块
基础语法
-
npm publish [<tarball>|<folder>] [--tag <tag>] [--access <public|restricted>]
-
Publishes '.' if no argument supplied Sets tag 'latest' if no --tag specified
npm access 在发布的包上设置访问级别
基础语法
-
npm access public [<package>]
-
npm access restricted [<package>]
-
npm access grant <read-only|read-write> <scope:team> [<package>]
-
npm access revoke <scope:team> [<package>]
-
npm access ls-packages [<user>|<scope>|<scope:team>]
-
npm access ls-collaborators [<package> [<user>]]
-
npm access edit [<package>]
npm set 用来设置环境变量
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 模块的信息。
-
$ 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 对象,包含了 underscore 模块的详细信息。这个对象的每个成员,都可以直接从 info 命令查询。
-
$ npm info underscore description
-
JavaScript's functional programming helper library.
-
$ npm info underscore homepage
-
http://underscorejs.org
-
$ npm info underscore version
-
1.5.2
npm search 搜索 npm 仓库
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 ls [[<@scope>/]<pkg> ...]
-
aliases: list, la, ll
-
$ npm list # 注意:这个是列出本地( 即当前目录 )安装的模块
-
$ npm list -global # 加上 global 参数,会列出全局安装的模块
-
$ npm ls -g # 查看全局安装的模块及依赖
-
$ npm list underscore # npm list 命令也可以列出单个模块
npm install ( 本地安装、全局安装 )
npm 安装包的命令格式:npm [install/i] [package_name]
-
基础语法:
-
npm install (with no args, in package dir)
-
npm install [<@scope>/]<name>
-
npm install [<@scope>/]<name>@<tag>
-
npm install [<@scope>/]<name>@<version>
-
npm install [<@scope>/]<name>@<version range>
-
npm install <tarball file>
-
npm install <tarball url>
-
npm install <folder> alias:
-
npm i common options: [-S|--save|-D|--save-dev|-O|--save-optional] [-E|--save-exact] [--dry-run]
Node 模块采用 npm install
命令安装,每个模块可以 “全局安装”,也可以 “本地安装”。“全局安装” 指的是将一个模块安装到系统目录中,各个项目都可以调用。
一般来说,
- 全局安装 只适用于工具模块,比如
eslint
和gulp
。 - 本地安装 指的是将一个模块下载到当前项目的
node_modules
子目录,然后只有在项目目录之中,才能调用这个模块。( 本地模式不会注册 PATH 环境变量 )
关于使用全局模式,多数时候并不是因为许多程序都有可能用到了它,而是为了减少多重副本才使用全局模式。同时 本地模式不会注册 PATH 环境变量。
本地模式 和 全局模式 的特点如下:
模式 | 可通过 require 使用 | 注册 PATH |
---|---|---|
本地模式 | 是 | 否 |
全局模式 | 否 | 是 |
本地模式 和 全局模式
npm 在默认情况下会从 http://npmjs.org 搜索或下载包,将包安装到当前目录的 node_modules 子目录下。
如果你熟悉 Ruby 的 gem 或者 Python 的 pip,你会发现 npm 与它们的行为不同,
- gem 或 pip 总是以 全局模式 安装,使包可以供所有的程序使用,
- 而 npm 默认会把包安装到当前目录下,即 本地安装 或者 本地模式。"本地安装" 指的是将一个模块下载到当前项目的 node_modules 子目录,然后只有在项目目录之中,才能调用这个模块。这反映了 npm 不同的设计哲学:如果把包安装到全局,可以提供程序的重复利用程度,避免同样的内容的多分副本,但坏处是难以处理不同的版本依赖。如果把包安装到当前目录,或者说本地,则不会有不同程序依赖不同版本的包的冲突问题,同时还减轻了包作者的 API 兼容性压力,但缺陷则是同一个包可能会被安装许多次。
例如:如果安装 supervisor 的时候使用了 npm install -g supervisor
命令,就是以全局模式安装 supervisor 。这里注意一点的就是,supervisor 必须安装到全局,如果你不安装到全局,错误命令会提示你安装到全局。如果不想安装到默认的全局,也可以自己修改全局路径到当前路径 npm config set prefix "路径"
安装完以后就可以用 supervisor 来启动服务了。supervisor 可以帮助你实现这个功能,它会监视你对代码的驱动,并自动重启 Node.js 。
-
# 本地安装(local)
-
$ npm install <package name>
-
# 全局安装(global),使用 -g 或 --global
-
$ 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
安装不同版本
- nmp 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
使用 npm install 安装模块的模块的时候 ,一般会使用下面这几种命令形式:
- npm install moduleName # 安装模块到项目目录下
- npm install -g moduleName # -g 的意思是将模块安装到全局,具体安装到磁盘哪个位置,要看 npm config prefix 的位置。
- npm install -save moduleName # -save 的意思是将模块安装到项目目录下,并在package文件的dependencies节点写入依赖。
- npm install -save-dev moduleName # -save-dev 的意思是将模块安装到项目目录下,并在package文件的devDependencies节点写入依赖。
下面对这四个命令进行对比,看完后你就不再这么问了。
npm install moduleName 命令
1. 安装模块到项目node_modules目录下。
2. 不会将模块依赖写入devDependencies或dependencies 节点。
3. 运行 npm install 初始化项目时不会下载模块。
npm install -g moduleName 命令
1. 安装模块到全局,不会在项目node_modules目录中保存模块包。
2. 不会将模块依赖写入devDependencies或dependencies 节点。
3. 运行 npm install 初始化项目时不会下载模块。
npm install -save moduleName 命令
1. 安装模块到项目node_modules目录下。
2. 会将模块依赖写入dependencies 节点。
3. 运行 npm install 初始化项目时,会将模块下载到项目目录下。
4. 运行npm install --production或者注明NODE_ENV变量值为production时,会自动下载模块到node_modules目录中。
npm install -save-dev moduleName 命令
1. 安装模块到项目node_modules目录下。
2. 会将模块依赖写入devDependencies 节点。
3. 运行 npm install 初始化项目时,会将模块下载到项目目录下。
4. 运行npm install --production或者注明NODE_ENV变量值为production时,不会自动下载模块到node_modules目录中。
总结
devDependencies 节点下的模块是我们在开发时需要用的,比如项目中使用的 gulp ,压缩css、js的模块。这些模块在我们的项目部署后是不需要的,所以我们可以使用 -save-dev 的形式安装。像 express 这些模块是项目运行必备的,应该安装在 dependencies 节点下,所以我们应该使用 -save 的形式安装。
--save、--save-dev、--save-optional、--save-exact
--save 和 --save-dev
- --save 会把依赖包名称添加到 package.json 文件 dependencies 键下,dependencies 是运行时依赖,
- --save-dev 则添加到 package.json 文件 devDependencies 键下,devDependencies 是开发时的依赖。即 devDependencies 下列出的模块,是开发时用的
比如,我们安装 js的压缩包 gulp-uglify 时,我们采用的是 “npm install --save-dev gulp-uglify ”命令安装,因为我们在发布后用不到它,而只是在我们开发才用到它。dependencies 下的模块,则是我们发布后还需要依赖的模块,譬如像 jQuery库或者 Angular 框架类似的,我们在开发完后后肯定还要依赖它们,否则就运行不了。
install 命令可以使用不同参数,指定所安装的模块属于哪一种性质的依赖关系,即出现在 packages.json 文件的哪一项中。
--save:模块名将被添加到 dependencies,可以简化为参数 -S。
--save-dev:模块名将被添加到 devDependencies,可以简化为参数 -D 。$ npm install sax --save # 或者 npm install sax -S
$ npm install node-tap --save-dev # 或者 npm install node-tap -D
-S, --save 安装包信息将加入到dependencies(生产阶段的依赖)。示例:npm install gulp --save 或 npm install gulp -S
package.json 文件的 dependencies 字段:
-
"dependencies": {
-
"gulp": "^3.9.1"
-
}
-D, --save-dev 安装包信息将加入到devDependencies(开发阶段的依赖),所以开发阶段一般使用它。
示例:npm install gulp --save-dev 或 npm install gulp -D ,package.json 文件的 devDependencies字段:
-
"devDependencies": {
-
"gulp": "^3.9.1"
-
}
-O, --save-optional 安装包信息将加入到 optionalDependencies(可选阶段的依赖)。
示例:npm install gulp --save-optional 或 npm install gulp -O ,package.json 文件的 optionalDependencies 字段:
-
"optionalDependencies": {
-
"gulp": "^3.9.1"
-
}
-E, --save-exact 精确安装指定模块版本。npm install gulp --save-exact 或 npm install gulp -E 。
输入命令 npm install gulp -ES,留意 package.json 文件的 dependencies 字段,以看出版本号中的^消失了
-
"dependencies": {
-
"gulp": "3.9.1"
-
}
模块的依赖都被写入了 package.json 文件后,他人打开项目的根目录(项目开源、内部团队合作),使用 npm install 命令可以根据 dependencies 配置安装所有的依赖包
安装 beta 版本的模块
如果要安装 beta 版本的模块,需要使用下面的命令。
-
# 安装最新的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 uninstall 卸载模块
npm uninstall
命令,卸载已安装的模块。
-
基础语法
-
npm uninstall [<@scope>/]<pkg>[@<version>]... [-S|--save|-D|--save-dev|-O|--save-optional]
-
$ npm uninstall [package name]
-
aliases: remove, rm, r, un, unlink
-
# 卸载全局模块
-
$ npm uninstall [package name] -global
-
如卸载开发版本的模块
-
$ npm uninstall gulp --save-dev
npm update 更新模块
npm update
命令可以更新本地安装的模块。基础语法:npm update [-g] [<pkg>...]
-
# 升级当前项目的指定模块
-
$ npm update [package name]
-
# 升级全局安装的模块
-
$ npm update -global [package name]
它会先到远程仓库查询最新版本,然后查询本地版本。如果本地版本不存在,或者远程版本较新,就会安装。
使用 -S
或 --save
参数,可以在安装的时候更新 package.json
里面模块的版本号。
-
// 更新之前的package.json
-
dependencies: {
-
dep1: "^1.1.1"
-
}
-
// 更新之后的package.json
-
dependencies: {
-
dep1: "^1.2.2"
-
}
注意,从 npm v2.6.1 开始,npm update
只更新顶层模块,而不更新依赖的依赖,以前版本是递归更新的。如果想取到老版本的效果,要使用下面的命令。
$ npm --depth 9999 update
npm outdated 检查模块是否已经过时
基础语法:npm outdated [[<@scope>/]<pkg> ...]
此命令会列出所有已经过时的包,可以及时进行包的更新
避免系统权限
默认情况下,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 run
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 run
如果不加任何参数,直接运行,会列出package.json
里面所有可以执行的脚本命令。- 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 run
-
Available 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/bash
-
cd site/main
-
browserify browser/main.js | uglifyjs -mc > static/bundle.js
假定上面的脚本文件名为 build.sh,并且权限为可执行,就可以在 scripts 属性中引用该文件。
"build-js": "bin/build.sh"
npm run 添加参数
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 脚本命令最佳实践
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服务器,展示指定目录的
index.html
文件,通过该文件加载各种网络资源,这是file://
协议做不到的。 - 添加自动刷新功能。只要指定目录之中,文件有任何变化,它就会刷新页面。
npm run serve
命令执行以后,自动打开浏览器。、
以前,上面三个功能需要三个模块来完成: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 格式的文档。
pre- 和 post- 脚本
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
,会按下面的顺序执行相应的命令。
pretest
test
posttest
如果执行过程出错,就不会执行排在后面的脚本,即如果 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-
脚本。
prepublish
:发布一个模块前执行。postpublish
:发布一个模块后执行。preinstall
:用户执行npm install
命令时,先执行该脚本。postinstall
:用户执行npm install
命令时,安装结束后执行该脚本,通常用于将下载的源码编译成用户需要的格式,比如有些模块需要在用户机器上跟本地的C++模块一起编译。preuninstall
:卸载一个模块前执行。postuninstall
:卸载一个模块后执行。preversion
:更改模块版本前执行。postversion
:更改模块版本后执行。pretest
:运行npm test
命令前执行。posttest
:运行npm test
命令后执行。prestop
:运行npm stop
命令前执行。poststop
:运行npm stop
命令后执行。prestart
:运行npm start
命令前执行。poststart
:运行npm start
命令后执行。prerestart
:运行npm restart
命令前执行。postrestart
:运行npm restart
命令后执行。
对于最后一个 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 的通配符的规则如下。
*
匹配0个或多个字符?
匹配1个字符[...]
匹配某个范围的字符。如果该范围的第一个字符是!
或^
,则匹配不在该范围的字符。!(pattern|pattern|pattern)
匹配任何不符合给定的模式?(pattern|pattern|pattern)
匹配0个或1个给定的模式+(pattern|pattern|pattern)
匹配1个或多个给定的模式*(a|b|c)
匹配0个或多个给定的模式@(pattern|pat*|pat?erN)
只匹配给定模式之一**
如果出现在路径部分,表示0个或多个子目录。
npm link 创建全局链接
npm 提供了一个有趣的命令 npm link
,它的功能是在本地包和全局包之间创建符号链接。我们说过使用全局模式安装的包不能直接通过 require
使用。但通过 npm link
命令可以打破这一限制。举个例子,我们已经通过 npm install -g express
安装了 express,这时在工程的目录下运行命令:
npm link express ./node_modules/express -> /user/local/lib/node_modules/express
我们可以在 node_modules
子目录中发现一个指向安装到全局的包的符号链接。通过这种方法,我们就可以把全局包当做本地包来使用了。
除了将全局的包链接到本地以外,使用 npm link 命令还可以将本地的包链接到全局。使用方法是在包目录(package.json 所在目录)中运行 npm link 命令。如果我们要开发一个包,利用这种方法可以非常方便地在不同的工程间进行测试。
开发 NPM 模块的时候,有时我们会希望,边开发边试用,比如本地调试的时候,require('myModule')
会自动加载本机开发中的模块。Node 规定,使用一个模块时,需要将其安装到全局的或项目的 node_modules
目录之中。对于开发中的模块,解决方法就是在全局的 node_modules
目录之中,生成一个符号链接,指向模块的本地目录。npm link
就能起到这个作用,会自动建立这个符号链接。
请设想这样一个场景,你开发了一个模块 myModule
,目录为 src/myModule
,你自己的项目 myProject
要用到这个模块,项目目录为 src/myProject
。首先,在模块目录(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
npm bin
命令显示相对于当前目录的,Node 模块的可执行脚本所在的目录(即.bin
目录)。
-
# 项目根目录下执行
-
$ npm bin
-
./node_modules/.bin
npm adduser
npm adduser
用于在 npmjs.com 注册一个用户。
-
$ npm adduser
-
Username: YOUR_USER_NAME
-
Password: YOUR_PASSWORD
-
Email: YOUR_EMAIL@domain.com
npm publish
npm publish
用于将当前模块发布到 npmjs.com
。执行之前,需要向 npmjs.com
申请用户名。
$ npm adduser
如果已经注册过,就使用下面的命令登录。
$ npm login
登录以后,就可以使用 npm publish
命令发布。
$ npm publish
如果当前模块是一个beta版,比如1.3.1-beta.3
,那么发布的时候需要使用tag
参数,将其发布到指定标签,默认的发布标签是latest
。
$ 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
,分别写入以下内容。
-
// .npmignore
-
source
-
// .gitignore
-
node_modules
-
distribution
npm deprecate
如果想废弃某个版本的模块,可以使用 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
命令用于管理模块的维护者。
-
# 列出指定模块的维护者
-
$ npm owner ls <package name>
-
# 新增维护者
-
$ npm owner add <user> <package name>
-
# 删除维护者
-
$ npm owner rm <user> <package name>
其他命令
npm home,npm repo
npm home
命令可以打开一个模块的主页,npm repo
命令则是打开一个模块的代码仓库。
-
$ npm home $package
-
$ npm repo $package
这两个命令不需要模块先安装。
npm outdated
npm outdated
命令检查当前项目所依赖的模块,是否已经有新版本。
$ npm outdated
它会输出当前版本(current version)、应当安装的版本(wanted version)和最新发布的版本(latest version)。
npm prune
npm prune
检查当前项目的 node_modules
目录中,是否有 package.json
里面没有提到的模块,然后将所有这些模块输出在命令行。
$ npm prune
npm shrinkwrap
npm shrinkwrap
的作用是锁定当前项目的依赖模块的版本。
$ npm shrinkwrap
运行该命令后,会在当前项目的根目录下生成一个npm-shrinkwrap.json
文件,内容是node_modules
目录下所有已经安装的模块,以及它们的精确版本。
下次运行npm install
命令时,npm
发现当前目录下有npm-shrinkwrap.json
文件,就会只安装里面提到的模块,且版本也会保持一致。
dependencies 依赖
这个可以说是我们 npm 核心一项内容,依赖管理,这个对象里面的内容就是我们这个项目所依赖的 js 模块包。下面这段代码表示我们依赖了 markdown-it
这个包,版本是 ^8.1.0
,代表最小依赖版本是 8.1.0
,如果这个包有更新,那么当我们使用 npm install
命令的时候,npm 会帮我们下载最新的包。当别人引用我们这个包的时候,包内的依赖包也会被下载下来。
-
"dependencies": {
-
"markdown-it": "^8.1.0"
-
}
devDependencies 开发依赖
在我们开发的时候会用到的一些包,只是在开发环境中需要用到,但是在别人引用我们包的时候,不会用到这些内容,放在 devDependencies 的包,在别人引用的时候不会被 npm 下载。
-
"devDependencies": {
-
"autoprefixer": "^6.4.0",0",
-
"babel-preset-es2015": "^6.0.0",
-
"babel-preset-stage-2": "^6.0.0",
-
"babel-register": "^6.0.0",
-
"webpack": "^1.13.2",
-
"webpack-dev-middleware": "^1.8.3",
-
"webpack-hot-middleware": "^2.12.2",
-
"webpack-merge": "^0.14.1",
-
"highlightjs": "^9.8.0"
-
}
当你有了一个完整的 package.json 文件的时候,就可以让人一眼看出来,这个模块的基本信息,和这个模块所需要依赖的包。我们可以通过 npm install 就可以很方便的下载好这个模块所需要的包。
npm install
默认会安装 dependencies 字段和 devDependencies 字段中的所有模块,如果使用 --production
参数,可以只安装 dependencies 字段的模块。
-
$ npm install --production
-
# 或者
-
$ NODE_ENV=production npm install
一旦安装了某个模块,就可以在代码中用 require 命令加载这个模块。
-
var backbone = require('backbone')
-
console.log(backbone.VERSION)
-
# 项目根目录下执行
-
$ npm bin
-
./node_modules/.bin
创建包
包是在模块基础上更深一步的抽象,Node.js 的包类似于 C/C++ 的函数库或者 Java、.Net 的类库。它将某个独立的功能封装起来,用于发布、更新、依赖管理和版本控制。Node.js 根据 CommonJS 规范实现了包机制,开发了 npm 来解决包的发布和获取需求。
Node.js 的包是一个目录,其中包含了一个 JSON 格式的包说明文件 package.json。严格符合 CommonJS 规范的包应该具备以下特征:
- package.json 必须在包的顶层目录下;
- 二进制文件应该在 bin 目录下;
- JavaScript 代码应该在 lib 目录下;
- 文档应该在 doc 目录下;
- 单元测试应该在 test 目录下。
Node.js 对包的要求并没有这么严格,只要顶层目录下有 package.json,并符合一些规范即可。当然为了提高兼容性,我们还是建议你在制作包的时候,严格遵守 CommonJS 规范。
我们也可以把文件夹封装为一个模块,即所谓的包。包通常是一些模块的集合,在模块的基础上提供了更高层的抽象,相当于提供了一些固定接口的函数库。通过定制 package.json,我们可以创建更复杂,更完善,更符合规范的包用于发布。
Node.js 在调用某个包时,会首先检查包中 packgage.json 文件的 main 字段,将其作为包的接口模块,如果 package.json 或 main 字段不存在,会尝试寻找 index.js 或 index.node 作为包的接口。
npm package.json 的语法
英文原版:https://docs.npmjs.com/files/package.json
这块内容好多,国内有好心人整理:《npm的package.json中文文档》,从这份文档拷贝出一些比较常见的,如下:
默认值
npm 会根据包内容设置一些默认值。
-
"scripts": {"start": "node server.js"}
如果包的根目录有
server.js
文件,npm会默认将start
命令设置为node server.js
。 -
"scripts":{"preinstall": "node-waf clean || true; node-waf configure build"}
如果包的根目录有
wscript
文件,npm会默认将preinstall
命令用node-waf进行编译。 -
"scripts":{"preinstall": "node-gyp rebuild"}
如果包的根目录有
binding.gyp
文件,npm会默认将preinstall
命令用node-gyp进行编译。 -
"contributors": [...]
如果包的根目录有
AUTHORS
文件,npm会默认逐行按Name <email> (url)
格式处理,邮箱和url是可选的。#号和空格开头的行会被忽略。
package.json 是 CommonJS 规定的用来描述包的文件,完全符合规范的 package.json 文件应该含有以下字段:
- name: 包的名字,必须是唯一的,由小写英文字母、数字和下划线组成,不能包含空格。
- description: 包的简要说明。放简介,字符串,方便在
npm search
中搜索 - version: 符合语义化版本识别规范的版本字符串。version 必须能被 node-semver 解析,它被包在npm的依赖中。(要自己用可以执行
npm install semver
)可用的“数字”或者“范围”见semver(7).
- keywords: 关键字,数组、字符串,通常用于搜索。方便在
npm search
中搜索 - maintainers: 维护者数组,每个元素要包含 name 、email(可选)、web(可选)字段。
- contributors: 贡献者数组,格式与 maintainers 相同。包的作者应该是贡献者数组的第一个元素。
- bugs: 提交 bug 的地址,可以是网址或者电子邮件地址。
- licenses: 许可证数组,每个元素要包含 type(许可证的名称)和 url(链接到许可证文本的地址)字段。
- repositories: 仓库托管地址数组,每个元素要包含 type(仓库的类型,如 git)、URL(仓库的地址)和 path(相对于仓库的路径,可选)字段。
- dependencies: 包的依赖,一个关联数组,由包名称和版本号组成。依赖是给一组包名指定版本范围的一个hash。这个版本范围是一个由一个或多个空格分隔的字符串。依赖还可以用tarball或者git URL。请不要将测试或过渡性的依赖放在
dependencies
hash中。见下文的devDependencies
- scripts: “scripts” 是一个由脚本命令组成的hash对象,他们在包不同的生命周期中被执行。key是生命周期事件,value是要运行的命令。参考上面的npm start、npm test命令。更多详细请看 npm-scripts(7)
- config:"config" hash可以用来配置用于包脚本中的跨版本参数。在实例中,如果一个包有下面的配置:{ "name" : "foo", "config" : { "port" : "8080" } },然后有一个 “start” 命令引用了
npm_package_config_port
环境变量,用户可以通过npm config set foo:port 8001
来重写他。参见 npm-config(7) 和 npm-scripts(7)。
需要说明的是:json 文件不能有注释
在 package.json 中最重要的就是 name 和 version 字段。他们都是必须的,如果没有就无法 install。name 和 version 一起组成的标识在假设中是唯一的。改变包应该同时改变version。
name是这个东西的名字。注意:
- 不要把node或者js放在名字中。因为你写了package.json它就被假定成为了js,不过你可以用"engine"字段指定一个引擎(见后文)。
- 这个名字会作为在URL的一部分、命令行的参数或者文件夹的名字。任何non-url-safe的字符都是不能用的。
- 这个名字可能会作为参数被传入require(),所以它应该比较短,但也要意义清晰。
- 在你爱上你的名字之前,你可能要去npm registry查看一下这个名字是否已经被使用了。http://registry.npmjs.org/
详见 semver(7).
version
必须完全和version
一致>version
必须比version
大>=version
同上<version
同上<=version
同上~version
大约一样,见semver(7)1.2.x
1.2.0, 1.2.1, 等,但不包括1.3.0http://...
见下文'依赖URL'*
所有""
空,同*
version1 - version2
同>=version1 <=version2
.range1 || range2
二选一。git...
见下文'依赖Git URL'user/repo
见下文'GitHub URLs'
比如下面都是合法的:
-
{ "dependencies" :
-
{ "foo" : "1.0.0 - 2.9999.9999" , "bar" : ">=1.0.2 <2.1.2" , "baz" : ">1.0.2 <=2.3.4" , "boo" : "2.0.1" , "qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0" , "asd" : "http://asdf.com/asdf.tar.gz" , "til" : "~1.2" , "elf" : "~1.2.3" , "two" : "2.x" , "thr" : "3.3.x" } }
包的发布
通过使用 npm init
可以根据交互式回答产生一个符合标准的 package.json。创建一个 index.js
作为包的接口,一个简单的包就制作完成了。
在发布前,我们还需要获得一个账号用于今后维护自己的包,使用 npm adduser
根据提示完成账号的创建。
完成后可以使用 npm whoami
检测是否已经取得了账号。
接下来,在 package.json 所在目录下运行 npm publish
,稍等片刻就可以完成发布了,打开浏览器,访问 http://search.npmjs.org/ 就可以找到自己刚刚发布的包了。现在我们可以在世界的任意一台计算机上使用 npm install neveryumodule
命令来安装它。
如果你的包将来有更新,只需要在 package.json 文件中修改 version 字段,然后重新使用 npm publish
命令就行了。
如果你对已发布的包不满意,可以使用 npm unpublish
命令来取消发布。