forked from xiao2mo/web-frontend-practice-handbook
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1db7f5b
commit bd34ab8
Showing
1 changed file
with
132 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
# 依赖管理 | ||
|
||
# peerDependencies | ||
|
||
## 引言 | ||
|
||
想必前端同学对 npm 的 devDependencies 和 dependencies 都比较熟悉,但是对 peerDependencies 可能就有点陌生,尤其是没有写过 npm 包插件的同学,比如之前使用 grunt 自动化工具的相关插件(如 grunt-contrib-jasmine 等)或者目前基于某个框架的 ui 组件库等等,这些都是需要对 peerDependencies 有一定了解的。下面我们就来说说 peerDependencies。 | ||
|
||
## npm2 中 dependencies 与 peerDependencies 区别 | ||
|
||
假设我们当前的项目是 MyProject,项目中有一些依赖,比方其中有一个依赖包**PackageA**,该包的**package.json**文件指定了对**PackageB**的依赖: | ||
|
||
``` | ||
{ | ||
"dependencies": { | ||
"PackageB": "1.0.0" | ||
} | ||
} | ||
``` | ||
|
||
如果我们在我们的 MyProject 项目中执行`npm install PackageA`, 我们会发现我们项目的目录结构会是如下形式: | ||
|
||
``` | ||
MyProject | ||
|- node_modules | ||
|- PackageA | ||
|- node_modules | ||
|- PackageB | ||
``` | ||
|
||
那么在我们的项目中,我们能通过下面语句引入"PackageA": | ||
|
||
``` | ||
var packageA = require('PackageA') | ||
``` | ||
|
||
但是,如果你想在项目中直接引用 PackageB: | ||
|
||
``` | ||
var packageA = require('PackageA') | ||
var packageB = require('PackageB') | ||
``` | ||
|
||
这是不行的,即使 PackageB 被安装过;因为 Node 只会在“MyProject/node_modules”目录下查找 PackageB,它不会在进入 PackageA 模块下的 node_modules 下查找。 | ||
|
||
所以,为了解决这个问题,在 MyProject 项目 package.json 中我们必须直接声明对 PackageB 的依赖并安装。 | ||
|
||
但是,有时我们不用在当前项目中声明对 PackageB 的依赖就可以直接引用,尤其是,PackageA 是一个类似于**grunt**的插件,例如 grunt-contrib-jshint。 | ||
|
||
为什么在项目中不用声明就可以直接使用呢?这就不得不说说 peerDependencies 的作用了。 | ||
|
||
## peerDependencies 的引入 | ||
|
||
为了解决这种问题: | ||
|
||
``` | ||
如果你安装我,那么你最好也安装X,Y和Z. | ||
``` | ||
|
||
于是`peerDependencies`就被引入了。例如上面 PackageA 的**package.json**文件如果是下面这样: | ||
|
||
``` | ||
{ | ||
"peerDependencies": { | ||
"PackageB": "1.0.0" | ||
} | ||
} | ||
``` | ||
|
||
那么,它会告诉 npm:如果某个 package 把我列为依赖的话,那么那个 package 也必需应该有对 PackageB 的依赖。 | ||
|
||
也就是说,如果你`npm install PackageA`,你将会得到下面的如下的目录结构: | ||
|
||
``` | ||
MyProject | ||
|- node_modules | ||
|- PackageA | ||
|- PackageB | ||
``` | ||
|
||
你可能注意到: | ||
|
||
> 在 npm2 中,即使当前项目 MyProject 中没有直接依赖 PackageB,该 PackageB 包依然会安装到当前项目的 node_modules 文件夹中。 | ||
下面的代码现在可以正常工作了,因为两个包在"MyProject/node_modules"中被安装了: | ||
|
||
``` | ||
var packageA = require('PackageA') | ||
var packageB = require('PackageB') | ||
``` | ||
|
||
总结一句话,`peerDependencies`的具体作用: | ||
|
||
> `peerDependencies`的目的是提示宿主环境去安装满足插件 peerDependencies 所指定依赖的包,然后在插件 import 或者 require 所依赖的包的时候,永远都是引用宿主环境统一安装的 npm 包,最终解决插件与所依赖包不一致的问题。 | ||
举个例子,就拿目前基于 react 的 ui 组件库**[email protected]**来说,因该 ui 组件库只是提供一套 react 组件库,它要求宿主环境需要安装指定的 react 版本。具体可以看它[package.json](https://github.com/ant-design/ant-design/blob/master/package.json#L37)中的配置: | ||
|
||
``` | ||
"peerDependencies": { | ||
"react": ">=16.0.0", | ||
"react-dom": ">=16.0.0" | ||
} | ||
``` | ||
|
||
它要求宿主环境安装 react@>=16.0.0 和 react-dom@>=16.0.0 的版本,而在每个 antd 组件的定义文件顶部: | ||
|
||
``` | ||
import * as React from 'react'; | ||
import * as ReactDOM from 'react-dom'; | ||
``` | ||
|
||
组件中引入的 react 和 react-dom 包其实都是宿主环境提供的依赖包。 | ||
|
||
## npm2 和 npm3 中 peerDependencies 的区别 | ||
|
||
正如上一节谈论的,在 npm2 中,PackageA 包中`peerDependencies`所指定的依赖会随着`npm install PackageA`一起被强制安装,所以不需要在宿主环境的 package.json 文件中指定对 PackageA 中`peerDependencies`内容的依赖。 | ||
|
||
但是在 npm3 中,`peerDependencies`的表现与 npm2 不同: | ||
|
||
> npm3 中不会再要求 peerDependencies 所指定的依赖包被强制安装,相反 npm3 会在安装结束后检查本次安装是否正确,如果不正确会给用户打印警告提示。 | ||
就拿上面的例子来说,如果我们 npm install PackageA 安装 PackageA 时,你会得到一个警告提示说: | ||
|
||
``` | ||
PackageB是一个需要的依赖,但是没有被安装。 | ||
``` | ||
|
||
这时,你需要手动的在 MyProject 项目的 package.json 文件指定 PackageB 的依赖。 | ||
|
||
另外,在 npm3 的项目中,可能存在一个问题就是你所依赖的一个 package 包更新了它 peerDependencies 的版本,那么你可能也需要在项目的 package.json 文件中手动更新到正确的版本。否则会出现类似下图所示的警告信息: | ||
|
||
![img](https://s2.ax1x.com/2019/11/13/MGF5kj.png) |