NPM 依赖
依赖项是应用程序运行所依赖的包或库。例如,如果您正在创建 React 项目,则需要将 React 列为依赖项并下载才能使项目正常运行。
一般我们要在项目中添加一个依赖项,只需要输入并执行以下命令:
npm install name-of-package
上面的命令将从指定的 npm 源中下载包,并将内容添加到创建的 node_modules/ 目录中,然后再将下载的包信息添加到应用程序的 package.json 中。目前 package.json 中共有 5 种关于依赖的配置项:
- dependencies**(default)**
- devDependencies
- peerDependencies
- bundledDependencies
- optionalDependencies
针对这几种配置项,除了 bundledDependencies 是数组的形式配置,其他几种均是对象形式,结构大致如下:
{
"dependencies": {
"pkg01": "2.0.1"
},
"devDependencies": {
"pkg02": "~1.6.3"
},
"peerDependencies": {
"pkg03": "2.x"
},
"peerDependenciesMeta": {
"pkg04": {
"optional": true
}
},
"bundleDependencies": ["renderized", "super-streams"],
"optionalDependencies": {
"pkg05": "2.x"
}
}
接下来,将对上述几个配置项做一一讲解。
基于 npm doc 中对 dependencies 的描述:
Please do not put test harnesses or transpilers or other "development" time tools in your
dependenciesobject. SeedevDependencies, below.请不要将测试工具或转译器或其他“开发阶段”需要的工具放入依赖项对象中。
具体请查阅
devDependencies的说明。
故而我们先从 devDependencies 着手了解。
devDependencies
If someone is planning on downloading and using your module in their program, then they probably don't want or need to download and build the external test or documentation framework that you use.
如果有人计划在他们的程序中下载和使用您的模块,那么他们可能不想或不需要下载和构建您使用的外部测试或文档框架。
In this case, it's best to map these additional items in a
devDependenciesobject.在这种情况下,最好将这些附加项映射到 devDependency 对象中。
基于上面的描述,devDependencies 用于注册一些 “开发阶段” 用到的 “工具”。
举个例子,eslint 用于开发过程中对项目业务代码的格式校验、格式修正,但其并不跟着项目业务代码的一起运行,那么 eslint 就需要注册到 devDependencies 中,如下:
{
"devDependencies": {
"eslint": "^8.23.0"
}
}
用更通俗的话来举例,假设现在做一张 “桌子”,制作过程中需要 “锤子” 这个工具。“锤子” 在 “桌子” 加工完成之后就不需要了,“锤子” 就是 devDependency 。
到现在为止,概念已经很清晰了,我总结为以下描述:
“开发阶段” 需要但 “完成阶段” 不需要的依赖,就是 devDependency ,需要注册到 devDependencies 中。
dependencies
由于文档中只是指明了 请不要将测试工具或转译器或其他“开发阶段”需要的工具放入依赖项对象中 ,那 “非开发阶段的依赖” (完成阶段的依赖)就是dependency ,即可以注册到 dependencies 中。
同样举个例子,eslint 用于开发阶段的代码检查、格式化,vuejs 用于业务代码的模块化渲染,依赖注册必须是这样的:
{
"devDependencies": {
"eslint": "^8.23.0"
},
"dependencies": {
"vue": "^2.5.16"
}
}
总结一下就是:
“开发阶段” 和 “完成阶段” 都需要的依赖,就是 dependency ,需要注册到 dependencies 中。
peerDependencies
peerDependencies 用于防止 “项目与子依赖” 或 “子依赖与子依赖” 中引入 “多个不同版本或多个相同版本” 的依赖,解决重复依赖、版本冲突等问题。
In npm versions 3 through 6,
peerDependencieswere not automatically installed, and would raise a warning if an invalid version of the peer dependency was found in the tree. As of npm v7, peerDependencies are installed by default.在 npm 版本 3 到 6 中,peerDependency 不会自动安装(即安装全靠当前项目来手动引入并安装),如果在树中发现项目中引入的版本与 peerDependency 声明的版本存在冲突,则会发出警告。从 npm v7 开始,默认安装 peerDependency(如果项目中没有手动引入,则自动下载安装,如果项目中引入的版本和 peerDependency声明的版本存在冲突,则直接报错,并终止 npm install 执行)。
总结一下就是:
为防止项目中引入 “多个不同版本或多个相同版本” 的依赖包,可以在项目中手动引入该依赖包,并在子依赖中添加 peerDependencies 配置。
补充说明:npm package.json 中还存在一个与 peerDependencies 捆绑的配置项——peerDependenciesMeta,其主要是为了控制某个 peerDependency 存在版本冲突或项目未手动引入时,是否要告警。具体配置如下:
{
"peerDependencies": {
"pkg": "2.x"
},
"peerDependenciesMeta": {
"pkg": {
"optional": true
}
}
}
上面将 pkg 配置为可选,则不会产生告警。
bundledDependencies
This defines an array of package names that will be bundled when publishing the package.
这定义了发布包时将捆绑的包名称数组。
In cases where you need to preserve npm packages locally or have them available through a single file download, you can bundle the packages in a tarball file by specifying the package names in the
bundleDependenciesarray and executingnpm pack.如果你需要在本地保留 npm 包或通过单个文件下载获得它们,您可以通过在 bundleDependency 数组中指定包名称并执行 npm pack 将包捆绑在 tarball 文件中。
举个例子:
{
"name": "awesome-web-framework",
"version": "1.0.0",
"bundleDependencies": ["renderized", "super-streams"]
}
我们可以通过运行npm pack获得awesome-web-framework-1.0.0.tgz文件。该文件包含 renderized和super-streams依赖包,可以通过执行 npm install Awesome-web-framework-1.0.0.tgz 将其安装在新项目中。
当然,bundledDependencies 也可以被声明为一个 Boolean 值,当设为 true 时,会将所有的依赖都进行捆绑,如果设为 false ,没有任一一个依赖被捆绑。
以上信息总结一下就是:
bundledDependencies 用于声明发布包时的捆绑依赖,其值可以是一个数组,也可以是一个布尔值。
optionalDependencies
If a dependency can be used, but you would like npm to proceed if it cannot be found or fails to install, then you may put it in the
optionalDependenciesobject. This is a map of package name to version or url, just like thedependenciesobject. The difference is that build failures do not cause installation to fail. Runningnpm install --omit=optionalwill prevent these dependencies from being installed.如果可以使用依赖项,但你希望 npm 在无法找到或安装失败时继续进行,那么你可以将其放入 optionalDependencies 对象中。配置项是包名称到版本或 url 的映射,就像 dependencies 对象一样。不同之处在于构建失败不会导致安装失败。运行 npm install --omit=optional 将阻止安装这些依赖项。
上面的描述,总结来说就是:
通过将某些依赖项注册到 optionalDependencies 中,可以保证在 npm install 时即使 npm 包无法找到/npm 包安装失败,命令依然会继续执行下去。
具体使用例如:
{
"optionalDependencies": {
"clone": "0.0.21"
}
}
总结
- dependencies**(default):“开发阶段” 和 “完成阶段” 都需要的依赖,就是 dependency ,需要注册到 dependencies 中。**
- devDependencies:“开发阶段” 需要但 “完成阶段” 不需要的依赖,就是 devDependency ,需要注册到 devDependencies 中。
- peerDependencies:为防止项目中引入 “多个不同版本或多个相同版本” 的依赖包,可以在项目中手动引入该依赖包,并在子依赖中添加 peerDependencies 配置。
- bundledDependencies:bundledDependencies 用于声明发布包时的捆绑依赖,其值可以是一个数组,也可以是一个布尔值。
- optionalDependencies:通过将某些依赖项注册到 optionalDependencies 中,可以保证在 npm install 时即使 npm 包无法找到/npm 包安装失败,命令依然会继续执行下去。
补充说明:从配置效果的来看,dependencies 与 devDependencies 本质上并没有什么区别,用于bundle构建的npm包也可以放到 devDependencies 中。之所以拆分成 dependencies 和devDependencies 这两块,主要是为了归类,方便维护。
版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证)