跳转至

安装

npm install

基本用法

npm install命令用于安装模块。npm i是该命令的别名。

$ npm install lodash

上面命令在当前目录中安装了lodash模块。

默认安装的是最新版本(即latest标签指向的版本),但是你可以 semver 表达式指定安装的版本。

# 等同于 npm install lodash
$ npm install lodash@latest

# 指定确定的版本
$ npm install lodash@4.17.4

# 指定版本范围
$ npm install sax@">=4.15.0 <4.18.0"

# 指定大版本
$ npm install lodash@^4.0.0

上面最后一行命令,指定安装最新的4.x版。

默认情况下,npm install不会修改package.json--save-S参数,将模块写入package.jsondependencies字段,--save-dev-D,将模块加入package.jsondevDependencies字段。

# 将模块写入 package.json 的 dependencies 字段
$ npm install lodash --save
$ npm install lodash -S

# 将模块写入 package.json 的 devDependencies 字段
$ npm install lodash --save-dev
$ npm install lodash -D

上面命令将模块写入package.json的时候,如果npm install没有指定版本,npm 会在安装的版本号前面添加^。比如,假定 lodash 的最新版是4.17.4,那么执行npm install -S lodash以后,package.json将写入的版本范围如下。

  "dependencies": {
    "lodash": "^4.17.4",
    ...
  },

上面的^4.17.4,表示兼容 4.17.4 以后的 4.x 版。

如果不希望出现这种默认行为,可以使用--save-exact指定只将当前确定的版本号,写入package.json

$ npm install lodash --save --save-exact
# 或者
$ npm install lodash --save-dev --save-exact

执行上面的命令以后,package.json里面的版本号将是固定的。

  "dependencies": {
    "lodash": "4.17.4",
    ...
  },

注意,--save-exact单独使用是无效的,必须与--save--save-dev一起使用。

npm install也支持直接输入 Github 代码库地址。

$ npm install git://github.com/package/path.git
$ npm install git://github.com/package/path.git#0.1.0

全局安装

npm 还可以将模块安装在全局,供所有项目使用。注意,一般情况下,全局安装只适用于一些命令行工具。

全局安装,要使用--global-g参数。此时,加上--save--save-exact--save-dev都是无效的。

$ npm install create-react-app --global
# 或者
$ npm install create-react-app -g

上面命令全局安装create-react-app模块。

安装机制与重装

本地安装后,模块将存放在当前项目的node_modules子目录,然后只有在项目目录之中,才能调用这个模块。全局安装后,模块将存放在全局目录之中(通常是/usr/local/lib/),所有项目都可以调用这个模块,但是不应该这样做。

安装之前,npm install会先检查,node_modules目录之中是否已经存在指定模块。如果存在,就不再重新安装了,即使远程仓库已经有了一个新版本,也是如此。

如果你希望,一个模块不管是否安装过,npm 都要强制重新安装,可以使用-f--force参数。

$ npm install lodash --force

如果所有模块都要强制重新安装,那就删除node_modules目录,重新执行npm install

$ rm -rf node_modules
$ npm install

安装项目依赖

不使用任何参数时,只使用npm install,会默认安装package.json里面的dependencies字段和devDependencies字段列出的所有模块。

$ npm install

如果使用--production参数,可以只安装dependencies字段的模块。

$ npm install --production
# 等同于
$ NODE_ENV=production npm install

避免安装权限

默认情况下,npm 全局模块都安装在系统目录(比如/usr/local/lib/),普通用户没有写入权限,需要用到sudo命令。这不是很方便,我们可以在没有 root 权限的情况下,安装全局模块。

首先,在主目录下新建配置文件.npmrc,在该文件中将prefix变量定义到一个你的个人目录下面(假定该目录是~/my-npm-modules)。

prefix = /home/yourUsername/my-npm-modules

此后,全局安装的模块都会安装在这个子目录中,npm也会到~/my-npm-modules/bin目录去寻找命令。

最后,将这个路径在.bash_profile文件(或.bashrc文件)中加入PATH变量。

export PATH=~/my-npm-modules/bin:$PATH

npm update

npm update命令可以更新本地安装的模块到最新版本(符合 semver 的设置),如果该模块没有安装,则会安装该模块。npm upnpm upgrade是该命令的缩写。

# 升级当前项目的某个模块
$ npm update lodash

# 升级全局安装的某个模块
$ npm update -g lodash

不使用任何参数时,将更新当前项目的所有dependencies字段里面的模块。如果有模块没有安装,也将一起安装。

$ npm update

--dev参数会连带安装和更新devDependencies字段里面的模块。

$ npm update --dev

更新时,会先到远程仓库查询最新版本,然后查询本地版本。如果本地版本不存在,或者远程版本较新,就会安装最新版本。

使用-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

注意,如果已经安装的模块版本比 semver 指定的版本更加新时,npm update有降级效果。

npm uninstall

npm uninstall命令,用来卸载已安装的模块。npm removenpm rmnpm rnpm unnpm unlink,都是该命令的别名。

# 卸载项目模块
$ npm uninstall lodash

# 卸载全局模块
$ npm uninstall lodash --global
$ npm uninstall lodash -g

使用--save参数(或-S),该模块将会从package.jsondependencies字段中移除。使用--save-dev参数(或-D)时,该模块将会从package.jsondevDependencies字段中移除。

$ npm uninstall lodash --save
$ npm uninstall lodash --save-dev

package-lock.json

从 npm 5.0 版本开始,npm 模块默认会锁版本。在npm install命令安装依赖时,会自动生成package-lock.json文件,如果该文件已存在,则会更新该文件。下面是package-lock.json的一个例子。

{
  "name": "react-example",
  "version": "1.0.0",
  "lockfileVersion": 1,
  "dependencies": {
    "has-flag": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
      "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
    },
    "supports-color": {
      "version": "3.2.3",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
      "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY="
    },
    "duplexify": {
      "version": "3.5.0",
      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.0.tgz",
      "integrity": "sha1-GqdzAC4VeEV+nZ1KULDMquvL1gQ=",
      "dependencies": {
        "end-of-stream": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz",
          "integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4="
        }
      }
    }
  }
}

这个文件不仅指定了每个模块的精确版本,而且还指定了node_modules目录的结构(即哪些模块要安装在目录的顶层)。也就是说,哪怕你使用不同版本的 npm,只要有这个文件,最后得到的总是同样的node_modules目录。可以理解成,这个文件是node_modules目录的一个快照。

上面的例子中可以看到,每个目录不仅有精确版本(version字段),还有下载地址(resolved字段)、哈希值(integrity字段)和依赖模块(dependencies字段)。

package-lock.json文件的lockfileVersion字段目前固定为1,以前的npm-shrinkwrap.json文件对应的lockfileVersion为0。这表明,前者实际上是后者的升级版。之所以叫一个新名字,是因为想表明这是一种全新的锁版本设计。

package-lock.jsonnpm-shrinkwrap.json有一些区别。首先,npm 在任何情况下,都不会将package-lock.json加入发布的代码之中。然后,在一个有package-lock.json的目录之中,执行npm shrinkwrap命令时,npm 会自动将package-lock.json改名为npm-shrinkwrap.json

如果同一个目录之中,同时存在package-lock.jsonnpm-shrinkwrap.json两个文件。这时,npm 会忽略package-lock.json,只使用npm-shrinkwrap.json