= npm
npm 的全称是 node package manager,即是 Node.js 环境下的包管理工具, 该工具随着 Node.js 安装时自动安装。
如果参照 Java 生态，npm 的作用相当于 maven, gradle, ivy 等工具的包管理功能, 通过 npm 我们可以采用统一的模式管理 Node.js 项目中依赖的包。
主要包括:

. 下载依赖包
. 发布自己的包

== npm package.json 文件
项目中依赖的包主要放置在 package.json 文件中，涉及包依赖的内容以以下三种形式表达。

. devDependencies(开发时依赖)
. dependencies(发布时依赖)
. peerDependencies(同辈依赖)

=== devDependencies(开发时依赖)
开发环境所需要的依赖，例如:我们需要 webpack 打包，那么就需要在 devDependencies 部分定义 webpack。

NOTE::devDependencies 中的依赖是不会打包到最终发布的包中。

=== dependencies(运行时依赖)
发布环境所需要的依赖，例如: 我们使用了 vue 框架，那么就需要在 dependencies 部分定义 vue。

=== peerDependencies(同辈依赖)
通常是在包开发的场景下，你的包需要某些依赖的支持，但是你又没必要去安装，因为你的包的宿主（使用者）会去安装这些依赖，你就可以用 peerDependencies 去声明一下需要依赖的包和版本，如果出问题 npm 就会有警告来提醒使用者去解决版本冲突问题。用简单的一句话来说明就是：如果你安装我，那么你最好也安装X,Y和Z。

假如你是 ant-design-vue 包的开发者，你在开发 ant-design-vue 包时需要用到 vue 包，此时你就可以将对 vue 包的依赖放到 peerDependencies 中，
因为当其他人使用你开发的 ant-design-vue 包时，一定也会用到 vue 包的，所以你在开发 ant-design-vue 包时就告诉使用者安装 vue 包。

我们思考一下 peerDependencies(同辈依赖) 这个名称的含义是如何体现的呢？

假设我们当前的项目是 MyProject，项目中有一对包 PackageA 的依赖，而 PackageA 又依赖了 PackageB。那么我们在 MyProject 项目中执行 npm install 后，项目的目录结构如下:

[source,bash]
----
MyProject
|- node_modules
   |- PackageA
      |- node_modules
         |- PackageB
----

此时，如果我们还想在 MyProject 项目中直接使用 PackageB 中的功能，类似以下代码：

[source,javascript]
----
var packageA = require('PackageA')
var packageB = require('PackageB')
----

这是不行的，即使 PackageB 被安装过；因为 Node 只会在 “MyProject/node_modules” 目录下查找 PackageB，它不会在进入 PackageA 模块下的 node_modules 下查找。

这就是 peerDependencies(同辈依赖) 名称隐含的意义，将 PackageA 对 PackageB 的依赖提升到 MyProject，使得 PackageA 和 PackageB 处于同级，这样 PackageA 可以使用 PackageB，
同时 MyProject 也可以使用 PackageA 和 PackageB。


== 常用命令
[source%nowrap,bash]
----
# 查看所有配置
npm config ls -l

# 查看某一个参数配置
npm config get 参数名称

# 设置某个参数配置
npm config set 参数名称 参数值

# 查看 registry
npm config get registry

# 设置 registry
npm config set registry http://developer.gbicc.net:8000/repository/npm-public/

# 查看已经安装的所有全局包
npm list -g --depth 0

# 安装全局包
npm install -g 包名

# 卸载全局包
npm uninstall -g 包名

# 安装本地包
npm install 包名
----

== npm 切换 repository
既然 npm 作为 node.js 环境下的包管理工具，和 java 领域的 maven 类似，npm 除了可以用于安装本地包以外，同样可以将本地开发的库发布到仓库中，
通常用于下载包和发布包的仓库是不同的，所以在开发过程中（特别是组件库开发）需要进行 npm 仓库的切换，以下通过实际进行开发本地库并发布到私服中的过程进行解释其实操过程。

=== 配置 nexus 私服，支持 npm 包的管理

=== 开发本地 js 库

=== 切换到可发布的本地私服
[source,bash]
----
vi ~/.npmrc

# 内容如下
# 当前采用本地私服作为 npm 仓库，用于 npm install 等操作时从私服中下载响应的依赖包
registry=http://developer.gbicc.net:8000/repository/npm-public/

# 如果需要 publish 本地库，需要切换仓库地址
# 将第一地址通过 // 注释,添加可发布的私服地址
//registry=http://developer.gbicc.net:8000/repository/npm-public/
registry=http://developer.gbicc.net:8000/repository/npm-hosted/

# 登录本地私服
npm login

# 需要输入用户名、密码和邮箱地址

# 当登录成功后,会显示以下信息
Logged in as wangshaoping on http://developer.gbicc.net:8000/repository/npm-hosted/.

# 查看当前登录用户信息
npm whoami

# 如果想登出系统，执行
npm logout


# 如果需要再切回依赖下载的私服地址，重新修改 vi ~/.npmrc 文件
vi ~/.npmrc

# 通过注释切换
registry=http://developer.gbicc.net:8000/repository/npm-public/
//registry=http://developer.gbicc.net:8000/repository/npm-hosted/

# 保存退出
----
