package.json 知多少?

在這裏插入圖片描述
Node.js 中,模塊是一個庫或框架,也是一個 Node.js 項目。Node.js 項目遵循模塊化的架構,當我們創建了一個 Node.js 項目,意味着創建了一個模塊,這個模塊必須有一個描述文件,即 package.json。它是我們最常見的配置文件,但是它裏面的配置你真的有詳細瞭解過嗎?配置一個合理的 package.json 文件直接決定着我們項目的質量,本章就帶大家瞭解下 package.json 的各項詳細配置。

必備屬性

package.json 中有非常多的屬性,其中必須填寫的只有兩個:nameversion ,這兩個屬性組成一個 npm 模塊的唯一標識。

npm包命名規則

name 即模塊名稱,其命名時需要遵循官方的一些規範和建議:
包名會成爲模塊url、命令行中的一個參數或者一個文件夾名稱,任何非url安全的字符在包名中都不能使用,可以使用 validate-npm-package-name 包來檢測包名是否合法。
語義化包名,可以幫助開發者更快的找到需要的包,並且避免意外獲取錯誤的包。
若包名稱中存在一些符號,將符號去除後不得與現有包名重複
例如:由於react-native已經存在,react.nativereactnative都不可以再創建。
如果你的包名與現有的包名太相近導致你不能發佈這個包,那麼推薦將這個包發佈到你的作用域下。
例如:用戶名 conard,那麼作用域爲 @conard,發佈的包可以是@conard/react

查看包是否被佔用

name 是一個包的唯一標識,不得和其他包名重複,我們可以執行 npm view packageName 查看包是否被佔用,並可以查看它的一些基本信息:
在這裏插入圖片描述
若包名稱從未被使用過,則會拋出 404錯誤:
在這裏插入圖片描述
另外,你還可以去 https://www.npmjs.com/ 查詢更多更詳細的包信息。

描述信息

{
  "description": "An enterprise-class UI design language and React components implementation",
  "keywords": [
    "ant",
    "component",
    "components",
    "design",
    "framework",
    "frontend",
    "react",
    "react-component",
    "ui"
  ]
}

description用於添加模塊的的描述信息,方便別人瞭解你的模塊。
keywords用於給你的模塊添加關鍵字。
當然,他們的還有一個非常重要的作用,就是利於模塊檢索。當你使用 npm search 檢索模塊時,會到descriptionkeywords 中進行匹配。寫好 descriptionkeywords 有利於你的模塊獲得更多更精準的曝光:
在這裏插入圖片描述

開發人員

描述開發人員的字段有兩個:authorcontributorsauthor 指包的主要作者,一個 author 對應一個人。contributors 指貢獻者信息,一個 contributors 對應多個貢獻者,值爲數組,對人的描述可以是一個字符串,也可以是下面的結構:

{
    "name" : "ConardLi",
    "email" : "[email protected]",
    "url" : "https://github.com/ConardLi"
}

地址

{
  "homepage": "http://ant.design/",
  "bugs": {
    "url": "https://github.com/ant-design/ant-design/issues"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/ant-design/ant-design"
  },
}

homepage 用於指定該模塊的主頁。
repository 用於指定模塊的代碼倉庫。
在這裏插入圖片描述
bugs 指定一個地址或者一個郵箱,對你的模塊存在疑問的人可以到這裏提出問題。

依賴配置

我們的項目可能依賴一個或多個外部依賴包,根據依賴包的不同用途,我們將他們配置在下面幾個屬性下:dependencies、devDependencies、peerDependencies、bundledDependencies、optionalDependencies

配置規則

在介紹幾種依賴配置之前,首先我們來看一下依賴的配置規則,你看到的依賴包配置可能是下面這樣的:

 "dependencies": {
      "antd": "ant-design/ant-design#4.0.0-alpha.8",
      "axios": "^1.2.0",
      "test-js": "file:../test",
      "test2-js": "http://cdn.com/test2-js.tar.gz",
      "core-js": "^1.1.5",
 }

依賴配置遵循下面幾種配置規則:

  • 依賴包名稱:VERSION
    • VERSION是一個遵循SemVer規範的版本號配置,npm install 時將到npm服務器下載符合指定版本範圍的包。
  • 依賴包名稱:DWONLOAD_URL
    • DWONLOAD_URL 是一個可下載的tarball壓縮包地址,模塊安裝時會將這個.tar下載並安裝到本地。
  • 依賴包名稱:LOCAL_PATH
    • LOCAL_PATH 是一個本地的依賴包路徑,例如 file:../pacakges/pkgName。適用於你在本地測試一個npm包,不應該將這種方法應用於線上。
  • 依賴包名稱:GITHUB_URL
    • GITHUB_URLgithubusername/modulename 的寫法,例如:ant-design/ant-design,你還可以在後面指定 tagcommit id
  • 依賴包名稱:GIT_URL
    • GIT_URL 即我們平時clone代碼庫的 git url,其遵循以下形式:
 <protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>]

其中 protocal 可以是以下幾種形式:

  • git://github.com/user/project.git#commit-ish
  • git+ssh://user@hostname:project.git#commit-ish
  • git+ssh://user@hostname/project.git#commit-ish
  • git+http://user@hostname/project/blah.git#commit-ish
  • git+https://user@hostname/project/blah.git#commit-ish

dependencies

dependencies 指定了項目運行所依賴的模塊,開發環境和生產環境的依賴模塊都可以配置到這裏,例如

 "dependencies": {
      "lodash": "^4.17.13",
      "moment": "^2.24.0",
 }

devDependencies

有一些包有可能你只是在開發環境中用到,例如你用於檢測代碼規範的 eslint ,用於進行測試的 jest ,用戶使用你的包時即使不安裝這些依賴也可以正常運行,反而安裝他們會耗費更多的時間和資源,所以你可以把這些依賴添加到 devDependencies 中,這些依賴照樣會在你本地進行 npm install 時被安裝和管理,但是不會被安裝到生產環境:

 "devDependencies": {
     "jest": "^24.3.1",
     "eslint": "^6.1.0",
}

peerDependencies

peerDependencies 用於指定你正在開發的模塊所依賴的版本以及用戶安裝的依賴包版本的兼容性。
上面的說法可能有點太抽象,我們直接拿 ant-design 來舉個例子,ant-designpackage.json 中有如下配置:

  "peerDependencies": {
    "react": ">=16.0.0",
    "react-dom": ">=16.0.0"
  }

當你正在開發一個系統,使用了 ant-design ,所以也肯定需要依賴 React。同時, ant-design 也是需要依賴 React 的,它要保持穩定運行所需要的 React 版本是16.0.0,而你開發時依賴的 React 版本是 15.x:
這時,ant-design 要使用 React,並將其引入:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
這時取到的是宿主環境也就是你的環境中的 React 版本,這就可能造成一些問題。在 npm2 的時候,指定上面的 peerDependencies 將意味着強制宿主環境安裝 react@>=16.0.0react-dom@>=16.0.0 的版本。
npm3 以後不會再要求 peerDependencies 所指定的依賴包被強制安裝,相反 npm3 會在安裝結束後檢查本次安裝是否正確,如果不正確會給用戶打印警告提示。

  "dependencies": {
    "react": "15.6.0",
    "antd": "^3.22.0"
  }

例如,我在項目中依賴了 antd 的最新版本,然後依賴了 react15.6.0版本,在進行依賴安裝時將給出以下警告:
在這裏插入圖片描述

optionalDependencies

某些場景下,依賴包可能不是強依賴的,這個依賴包的功能可有可無,當這個依賴包無法被獲取到時,你希望 npm install 繼續運行,而不會導致失敗,你可以將這個依賴放到 optionalDependencies 中,注意 optionalDependencies 中的配置將會覆蓋掉 dependencies 所以只需在一個地方進行配置。
當然,引用 optionalDependencies 中安裝的依賴時,一定要做好異常處理,否則在模塊獲取不到時會導致報錯。

bundledDependencies

和以上幾個不同,bundledDependencies 的值是一個數組,數組裏可以指定一些模塊,這些模塊將在這個包發佈時被一起打包。

"bundledDependencies": ["package1" , "package2"]

協議

{
    "license": "MIT"
}

license 字段用於指定軟件的開源協議,開源協議裏面詳盡表述了其他人獲得你代碼後擁有的權利,可以對你的的代碼進行何種操作,何種操作又是被禁止的。同一款協議有很多變種,協議太寬鬆會導致作者喪失對作品的很多權利,太嚴格又不便於使用者使用及作品的傳播,所以開源作者要考慮自己對作品想保留哪些權利,放開哪些限制。

軟件協議可分爲開源和商業兩類,對於商業協議,或者叫法律聲明、許可協議,每個軟件會有自己的一套行文,由軟件作者或專門律師撰寫,對於大多數人來說不必自己花時間和精力去寫繁長的許可協議,選擇一份廣爲流傳的開源協議就是個不錯的選擇。

以下就是幾種主流的開源協議:
在這裏插入圖片描述

  • MIT:只要用戶在項目副本中包含了版權聲明和許可聲明,他們就可以拿你的代碼做任何想做的事情,你也無需承擔任何責任。
  • Apache:類似於 MIT,同時還包含了貢獻者向用戶提供專利授權相關的條款。
  • GPL:修改項目代碼的用戶再次分發源碼或二進制代碼時,必須公佈他的相關修改

如果你對開源協議有更詳細的要求,可以到 https://choosealicense.com/ 獲取更詳細的開源協議說明。
在這裏插入圖片描述

目錄、文件相關

程序入口

{
  "main": "lib/index.js",
}

main 屬性可以指定程序的主入口文件,例如,上面 antd 指定的模塊入口 lib/index.js ,當我們在代碼用引入 antd 時:import { notification } from 'antd'; 實際上引入的就是 lib/index.js 中暴露出去的模塊。
在這裏插入圖片描述

命令行工具入口

當你的模塊是一個命令行工具時,你需要爲命令行工具指定一個入口,即指定你的命令名稱和本地可指定文件的對應關係。如果是全局安裝,npm 將會使用符號鏈接把可執行文件鏈接到 /usr/local/bin,如果是本地安裝,會鏈接到 ./node_modules/.bin/

{
    "bin": {
    "conard": "./bin/index.js"
  }
}

例如上面的配置:當你的包安裝到全局時:npm 會在 /usr/local/bin下創建一個以 conard 爲名字的軟鏈接,指向全局安裝下來的 conard 包下面的 "./bin/index.js"。這時你在命令行執行 conard 則會調用鏈接到的這個js文件。

這裏不再過多展開,更多內容在我後續的命令行工具文章中會進行詳細講解。

發佈文件配置

{
   "files": [
     "dist",
     "lib",
     "es"
   ]
}

files 屬性用於描述你 npm publish 後推送到 npm 服務器的文件列表,如果指定文件夾,則文件夾內的所有內容都會包含進來。我們可以看到下載後的包是下面的目錄結構:
在這裏插入圖片描述

另外,你還可以通過配置一個 .`npmignore` 文件來排除一些文件, 防止大量的垃圾文件推送到 npm, 規則上和你用的 `.gitignore` 是一樣的。`.gitignore` 文件也可以充當.`npmignore` 文件。

man

man 命令是 Linux 下的幫助指令,通過 man 指令可以查看 Linux 中的指令幫助、配置文件幫助和編程幫助等信息。
如果你的 node.js 模塊是一個全局的命令行工具,在 package.json 通過 man 屬性可以指定 man 命令查找的文檔地址。
man 文件必須以數字結尾,或者如果被壓縮了,以 .gz 結尾。數字表示文件將被安裝到 man 的哪個部分。如果 man 文件名稱不是以模塊名稱開頭的,安裝的時候會給加上模塊名稱前綴。
例如下面這段配置:

{
  "man" : [
    "/Users/isaacs/dev/npm/cli/man/man1/npm-access.1",
    "/Users/isaacs/dev/npm/cli/man/man1/npm-audit.1"
  ]
}

在命令行輸入 man npm-audit
在這裏插入圖片描述

規範項目目錄

一個 node.js 模塊是基於 CommonJS 模塊化規範實現的,嚴格按照 CommonJS 規範,模塊目錄下除了必須包含包描述文件 package.json 以外,還需要包含以下目錄:

  • bin:存放可執行二進制文件的目錄
  • lib:存放js代碼的目錄
  • doc:存放文檔的目錄
  • test:存放單元測試用例代碼的目錄

在模塊目錄中你可能沒有嚴格按照以上結構組織或命名,你可以通過在 package.json 指定 directories 屬性來指定你的目錄結構和上述的規範結構的對應情況。除此之外 directories 屬性暫時沒有其他應用。

{
  "directories": {
    "lib": "src/lib/",
    "bin": "src/bin/",
    "man": "src/man/",
    "doc": "src/doc/",
    "example": "src/example/"
  }
}
不過官方文檔表示,雖然目前這個屬性沒有什麼重要作用,未來可能會整出一些花樣出來,例如:doc 中存放的 markdown 文件、example 中存放的示例文件,可能會友好的展示出來。

腳本配置

script

{
  "scripts": {
    "test": "jest --config .jest.js --no-cache",
    "dist": "antd-tools run dist",
    "compile": "antd-tools run compile",
    "build": "npm run compile && npm run dist"
  }
}

scripts 用於配置一些腳本命令的縮寫,各個腳本可以互相組合使用,這些腳本可以覆蓋整個項目的生命週期,配置後可使用 npm run command 進行調用。如果是 npm 關鍵字,則可以直接調用。例如,上面的配置制定了以下幾個命令:npm run testnpm run distnpm run compilenpm run build

{
  "config" : { "port" : "8080" }
}

發佈配置

preferGlobal

如果你的 node.js 模塊主要用於安裝到全局的命令行工具,那麼該值設置爲 true ,當用戶將該模塊安裝到本地時,將得到一個警告。這個配置並不會阻止用戶安裝,而是會提示用戶防止錯誤使用而引發一些問題。

private

如果將 private 屬性設置爲 truenpm將拒絕發佈它,這是爲了防止一個私有模塊被無意間發佈出去。
在這裏插入圖片描述

publishConfig

  "publishConfig": {
    "registry": "https://registry.npmjs.org/"
  },

發佈模塊時更詳細的配置,例如你可以配置只發布某個tag、配置發佈到的私有 npm 源。更詳細的配置可以參考 npm-config

os

假如你開發了一個模塊,只能跑在 darwin 系統下,你需要保證 windows 用戶不會安裝到你的模塊,從而避免發生不必要的錯誤。
使用 os 屬性可以幫助你完成以上的需求,你可以指定你的模塊只能被安裝在某些系統下,或者指定一個不能安裝的系統黑名單:

"os" : [ "darwin", "linux" ]
"os" : [ "!win32" ]

例如,我把一個測試模塊指定一個系統黑名單:“os” : [ “!darwin” ],當我在此係統下安裝它時會爆出如下錯誤:
在這裏插入圖片描述

在node環境下可以使用 process.platform 來判斷操作系統。

cpu

和上面的 os 類似,我們可以用 cpu 屬性更精準的限制用戶安裝環境:

"cpu" : [ "x64", "ia32" ]
"cpu" : [ "!arm", "!mips" ]
在node環境下可以使用 process.arch 來判斷 cpu 架構。

參考

http://caibaojian.com/npm/files/package.json.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章