[NodeJs系列]聊一聊 package.json 中的各种 dependency

 阅读约 7 分钟

如果你对NodeJs系列感兴趣,欢迎关注微信公众号:前端神盾局或 github NodeJs系列文章

日常开发中,我们常见到各种dependency,今日得空整理了一下

dependency 与 devDependency

几乎在每个应用中我们都会见到dependencydevDependency的身影。dependency定义的是代码所需要的依赖包,而devDependency给定的是编译/测试等开发时所需依赖包。举个例子:

{
    "name": "project",
    "script": {
        // 代码打包
        "build": "./node_modules/.bin/webpack ..."
    },
    "dependency": {
        "react": "^16.6.3",
        ...
    },
    "devDependency": {
        "webpack": "4.19.1",
        "url-loader": "1.1.1",
        ...
    }
}

理想情况下,当运行npm run build后应该只包含react相关代码而不包括devDependency中的无用代码。当然,在这里dependencydevDependency只是一个规范,最终生成什么代码取决于你引入了什么,比如improt 'url-loader'会把url-loader囊括进你的生产代码,不论它是否定义在dependency中。

现在考虑另外一个场景,我们开发了一个npm(package-a)包,我们希望所有依赖package-a的应用都能有效的运行。这时dependencydevDependency并不仅仅是一个我们可以随意遵守的规范而已,因为项目依赖的devDependency 不会被安装。比如:

├── project
    ├── package-a (dependency)
    │   └── package-a-1 (devDependency)
    └── package-b (devDependency)

在project下执行npm install之后,package-a和package-b 都会被安装,但package-a-1不会被安装,所以你在project的 node_modules文件夹下找不到package-c。

综上所述,在开发一个应用时,我们应该把生产需要的依赖放在dependency
中,把单元测试/编译/打包等这些生产无关依赖放在devDependency

peerDependencies

我们以babel-loader为例子,运行npm install babel-loader -D时,控制台会有两条警告:

npm WARN babel-loader@8.0.4 requires a peer of @babel/core@^7.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN babel-loader@8.0.4 requires a peer of webpack@>=2 but none is installed. You must install peer dependencies yourself.

提示babel-loader需要依赖@babel/core@^7.0.0webpack@>=2。这是因为peerDependencies指定了当前包需要安装的依赖:

"peerDependencies": {
    "@babel/core": "^7.0.0",
    "webpack": ">=2"
 }

那应该在什么情况下使用呢?

一般的,如果我们需要开发针对于某个库的插件而又不需要在代码中引用这个库的时候。就比如babel-loader是webpack的一个插件,但代码中又无需引用webpack,为了保证插件能够运行在webpack环境中,故而使用了peerDependencies

bundledDependencies

又可称为:bundleDependencies

再以一个例子阐述:

{
  "name": "project",
  "dependencies": {
    "react": "^16.6.3",
    "react-dom": "^16.6.3"
  },
  "bundleDependencies": [
    "react",
    "react-dom"
  ],
  "version": "1.0.0"
}

当我们需要使用npm pack打包这个应用时,其最终生成的文件结构如下:

project-1.0.0.tgz
    ├── node_modules
    |       └── react
    |       └── react-dom
    └── package.json

如果不使用bundleDependencies,文件结构如下:

project-1.0.0.tgz
    ├── project-1.0.0.tgz
    |       └── node_modules
    |           └── react
    |           └── react-dom
    └── package.json

so,bundleDependencies的作用是将指定依赖归置于当前项目下,这样你就可以快速的运行你pack后的项目。

optionalDependencies

如果你的应用中依赖了optional-a,而这个依赖又是可有可无的,也就是说如果optional-a找不到或者安装失败,你希望程序依旧运行。这时候optionalDependencies就能很好的满足你的要求。

注意:optionalDependencies会覆盖dependencies中的同名包
try {
  let optionalA = require('optional-a');
} catch (er) {
  optionalA = null
}

参考

  1. What's the difference between dependencies, devDependencies and peerDependencies in npm package.json file?
  2. Peer Dependencies
  3. Package.json

image

阅读 785更新于 2月12日
推荐阅读
前端神盾局
用户专栏

收集一手前端资讯,分享原创文章

656 人关注
11 篇文章
专栏主页
目录