npm 详解

npm 官方文档https://docs.npmjs.com/cli/v6/commands/npm-install/

npm 模块管理器:http://javascript.ruanyifeng.com/nodejs/npm.html

npm 常用命令详解:https://blog.csdn.net/sxs1995/article/details/80729069

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

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 --savenpm install gulp -S

package.json 文件的 dependencies 字段:

"dependencies": {
    "gulp": "^3.9.1"
}

-D, --save-dev 安装包信息将加入到devDependencies(开发阶段的依赖),所以开发阶段一般使用它。

示例:npm install gulp --save-devnpm install gulp -D  ,package.json 文件的 devDependencies字段:

"devDependencies": {
    "gulp": "^3.9.1"
}

-O, --save-optional 安装包信息将加入到 optionalDependencies(可选阶段的依赖)。

示例:npm install gulp --save-optionalnpm install gulp -O ,package.json 文件的 optionalDependencies 字段:

"optionalDependencies": {
    "gulp": "^3.9.1"
}

-E, --save-exact 精确安装指定模块版本。npm install gulp --save-exactnpm 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 testnpm 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-serverlive-reloadopener,现在只要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,会按下面的顺序执行相应的命令。

  1. pretest
  2. test
  3. 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添加precommitprepush等钩子。

{
    "scripts": {
        "lint": "eslint yourJsFiles.js",
        "precommit": "npm run test && npm run lint",
        "prepush": "npm run test && npm run lint",
        "...": "..."
    }
}

类似作用的模块还有pre-commitprecommit-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 提供了一个有趣的命令 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。请不要将测试或过渡性的依赖放在dependencieshash中。见下文的devDependencies
  • scripts: “scripts” 是一个由脚本命令组成的hash对象,他们在包不同的生命周期中被执行。key是生命周期事件,value是要运行的命令。参考上面的npm startnpm 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.0
  • http://... 见下文'依赖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 命令来取消发布。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值