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

日常開發中,我們常見到各種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 [email protected] requires a peer of @babel/core@^7.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章