全方位解讀 package-json

來自:知乎,作者:Derrick

鏈接:https://zhuanlan.zhihu.com/p/384484213

前言

平常在工作中,對package.json這個文件的接觸非常非常少。

由淺入深 - 核心內容

準備工作

手摸手新建一個空的 package.json

  1. npm init

  2. 上萬個回車

或者直接執行

  1. npm init -y

  2. 其意思就是全部都略過,和我們上面的無數個回車的效果一樣

先看看上面有的東西。

{
  "name""package.json"# 項目名稱
  "version""1.0.0", # 項目版本(格式:大版本.次要版本.小版本)
  "description"""# 項目描述
  "main""index.js"# 入口文件
  "scripts"{ # 指定運行腳本命令的 npm 命令行縮寫
    "test""echo \"Error: no test specified\" && exit 1"
  },
  "keywords"[]# 關鍵詞
  "author"""# 作者
  "license""ISC" # 許可證
}

scripts(快捷腳本)

"scripts": {
  "start": "node index.js"
},
複製代碼

dependencies & devDependencies(項目依賴)

這裏重點談一下這些版本號直接的差異

~1.1.1

^1.1.1

允許不修改[major, minor, patch]元組中最左邊的非零元素的更改 。換句話說,這允許版本1.0.0及以上版本的補丁和次要更新,版本的補丁更新0.X >=0.1.0,以及版本的_不_更新0.0.X

許多作者將0.x版本視爲x主要的 “重大變化” 指標。

當作者可能在發行版0.2.40.3.0發行版之間進行重大更改時,插入符範圍是理想的,這是一種常見做法。但是,它假定和之間_不會_有重大變化 。根據通常觀察到的做法,它允許進行假定爲附加(但不會破壞)的更改。0.2.4``0.2.5

解析插入符範圍時,缺失patch值會被減爲數字0,但即使主要版本和次要版本都是0.

缺失值minorpatch值將脫糖爲零,但也允許在這些值內具有靈活性,即使主要版本爲零。

1.1.x

任何的Xx*可被用來 “立場在” 在數字值中的一個[major, minor, patch]元組。

部分版本範圍被視爲 X 範圍,因此特殊字符實際上是可選的。

1.1.1 - 1.1.2

指定一個包含集。

如果部分版本作爲包含範圍中的第一個版本提供,則缺失的部分將替換爲零。

如果部分版本作爲包含範圍中的第二個版本提供,則接受以元組提供的部分開頭的所有版本,但不會大於提供的元組部分。

engines(指定項目 node 版本)

"engines": {
   "node": ">= 8.16.0"
},
複製代碼
"engines": {
   "npm": ">= 6.9.0"
 },
複製代碼

os(模塊適用系統)

"os" : [ "darwin", "linux" ] # 適用系統
"os" : [ "!win32" ] # 黑名單
複製代碼

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

cpu(指定模塊適用 cpu 架構)

"cpu" : [ "x64", "ia32" ] # 適用 cpu
"cpu" : [ "!arm", "!mips" ] # 黑名單
複製代碼

Tips:在 node 環境下可以使用 process.arch 來判斷 cpu 架構。

private(定義私有模塊)

次重要(可以當百科全書)

name(項目名稱)

名字就是你的東西叫什麼。(name 名稱)和(version 版本號)構成一個唯一的標識符。

名稱的一些規則:

一些技巧:

如果模塊存在,可以查看該模塊的一些基本信息:

如果該模塊名從未被使用過,則會拋出 404 錯誤:

version(版本號)

npm view <packageName> version # 查看某個模塊的最新版本
npm view <packageName> versions # 查看某個模塊的所有歷史版本

description(項目描述)

此文檔是您需要了解的有關 package.json 文件中所需內容的全部信息。它必須是實際的 JSON,而不僅僅是 JavaScript對象文字。

本文檔中描述的許多行爲受 中描述的配置設置的影響config

keywords

把關鍵字放進去。它是一個字符串數組。這有助於人們發現您的包裹,因爲它在 中列出npm search

homepage(項目主頁)

項目主頁的url

例子:

"homepage" :“https://github.com/owner/project#readme”

bugs(問題追蹤)

項目問題跟蹤器的 url 和 / 或應報告問題的電子郵件地址。這些對於遇到包裹問題的人很有幫助。

它應該是這樣的:

{
  "url" : "https://github.com/owner/project/issues" ,  
  "email" :"project@hostname.com"
}

您可以指定一個或兩個值。如果您只想提供一個 url,您可以將 “bugs” 的值指定爲一個簡單的字符串而不是一個對象。

如果提供了url,它將被npm bugs命令使用。

license(執照)

你應該爲你的包指定一個許可證,以便人們知道他們如何被允許使用它,以及你對它施加的任何限制。

如果您使用的是 BSD-2-Clause 或 MIT 等通用許可證,請爲您使用的許可證添加當前的SPDX 許可證標識符,如下所示:

{
  "license" : "BSD-3-Clause"
}

您可以查看 SPDX 許可證 ID 的完整列表。理想情況下,您應該選擇 OSI 批准的一種。

如果您的軟件包在多個通用許可下獲得許可,請使用 SPDX 許可表達式語法版本 2.0 string,如下所示:

{
  "license" : "(ISC OR GPL-3.0)"
}

如果您使用的許可證尚未分配SPDX 標識符,或者您使用的是自定義許可證,請使用如下字符串值:

{
  "license" : "SEE LICENSE IN <filename>"
}

然後包含一個<filename>在包的頂層命名的文件。

一些舊包使用許可證對象或包含許可證對象數組的 “許可證” 屬性:

// 無效的元數據
{
  "license" : {
    "type" : "ISC",
    "url" : "https://opensource.org/licenses/ISC"
  }
}

// 無效的元數據
{
  "licenses" : [
    {
      "type""MIT",
      "url""https://www.opensource.org/licenses/mit-license.php"
    },
    {
      "type""Apache-2.0",
      "url""https://opensource.org/licenses/apache2.0.php"
    }
  ]
}

這些樣式現在已被棄用。相反,使用SPDX表達式,如下所示:

{
  "license""ISC"
}
{
  "license""(MIT OR Apache-2.0)"
}

最後,如果您不希望根據任何條款授予他人使用私有或未發佈包的權利:

{
  "license""UNLICENSED"
}

還要考慮設置"private": true以防止意外發布。

author, contributors(作者和貢獻者)

“作者”是一個人。“貢獻者”是一羣人。“person”是一個帶有 “name” 字段和可選的 “url” 和“email”的對象,像這樣:

{
  "name" : "Barney Rubble",
  "email" : "b@rubble.com",
  "url" : "http://barnyrubble.tumblr.com/"
}

或者,您可以將其全部縮短爲一個字符串,然後 npm 將爲您解析它:

{
  "author""Barney Rubble <b@rubble.com> (http://barnyrubble.tumblr.com/)"
}

email 和 url 都是可選的。

npm 還使用您的 npm 用戶信息設置頂級 “維護者” 字段。

funding(檔案)

可選files字段是一個文件模式數組,它描述了當您的包作爲依賴項安裝時要包含的條目。文件模式遵循與 類似的語法.gitignore,但相反:包含文件、目錄或 glob 模式(*,**/*等)將使該文件在打包時包含在 tarball 中。省略該字段將使其默認爲["*"],這意味着它將包含所有文件。

一些特殊的文件和目錄也會被包含或排除,無論它們是否存在於files數組中(見下文)。

您還可以.npmignore在包的根目錄或子目錄中提供一個文件,以防止文件被包含在內。在包的根目錄中,它不會覆蓋 “文件” 字段,但在子目錄中會覆蓋。該.npmignore文件就像一個.gitignore. 如果有一個.gitignore文件,並且.npmignore丟失了,.gitignore則將使用 的內容。

文件包含了 “的 package.json#文件” 欄中_無法_通過排除.npmignore.gitignore

無論設置如何,始終包含某些文件:

READMECHANGESLICENSE&NOTICE可以有任何大小寫和擴展名。

相反,一些文件總是被忽略:

main(主要入口)

browser(瀏覽器)

如果您的模塊打算在客戶端使用,則應使用瀏覽器字段而不是主字段。這有助於提示用戶它可能依賴於 Node.js 模塊中不可用的原語。(例如 window

bin(自定義命令)

很多包都有一個或多個他們想要安裝到 PATH 中的可執行文件。npm 使這變得非常簡單(實際上,它使用此功能來安裝 “npm” 可執行文件。)

要使用它,請bin在 package.json 中提供一個字段,它是命令名到本地文件名的映射。在安裝時,npm 會將該文件符號鏈接到prefix/bin全局安裝或./node_modules/.bin/本地安裝。

給大家看看我自己做一個簡單的 demo:

{
  "name""react-cli-library",
  "version""0.0.2",
  "description""",
  "bin"{
    "react-cli""./bin/index.js"
  },
}

我的名稱叫做 react-cli-library。

所以,npm i react-cli-library

安裝完成之後,執行 react-cli 就會有一些命令,他會執行我的根目錄底下./bin/index.js這個文件。

雖然我的項目名稱是:react-cli-library。但是我執行的內容卻是react-cli,這個取決於 bin 的內容

man(快捷入口)

用來給 Linux 下的 man 命令查找文檔地址,是個單一文件或者文件數組。如果是單一文件,安裝完成後,他就是 man + 的結果,和此文件名無關,例如:

{
  "name": "foo",
  "version": "1.2.3",
  "description": "A packaged foo fooer for fooing foos",
  "main": "foo.js",
  "man": "./man/doc.1"
}

通過 man foo 命令會得到 ./man/doc.1 文件的內容。如果 man 文件名稱不是以模塊名稱開頭的,安裝的時候會給加上模塊名稱前綴。因此,下面這段配置:

{
  "name": "foo",
  "version": "1.2.3",
  "description": "A packaged foo fooer for fooing foos",
  "main": "foo.js",
  "man": [
    "./man/foo.1",
    "./man/bar.1"
  ]
}

會創建一些文件來作爲 man foo 和 man foo-bar 命令的結果。man 文件必須以數字結尾,或者如果被壓縮了,以. gz 結尾。數字表示文件將被安裝到 man 的哪個部分。

{
  "name": "foo",
  "version": "1.2.3",
  "description": "A packaged foo fooer for fooing foos",
  "main": "foo.js",
  "man": [
    "./man/foo.1",
    "./man/foo.2"
  ]
}

會創建 man foo 和 man 2 foo 兩條命令。

directories(目錄)

CommonJS Packages 規範詳細說明了一些可以使用directories對象指示包結構的方法。如果您查看 npm 的 package.json,您會看到它包含 doc、lib 和 man 目錄。

將來,這些信息可能會以其他創造性的方式使用。

目錄. bin

如果在 中指定bin目錄directories.bin,則將添加該文件夾中的所有文件。

由於bin指令的工作方式,同時指定bin路徑和設置directories.bin是錯誤的。如果要指定單個文件,請使用bin,對於現有bin 目錄中的所有文件,請使用directories.bin

目錄. man

一個充滿手冊頁的文件夾。Sugar 通過遍歷文件夾來生成 “man” 數組。

repository(代碼存儲位置)

指定代碼所在的位置。這對想要貢獻的人很有幫助。如果 git repo 在 GitHub 上,那麼該npm docs 命令將能夠找到您。

像這樣做:

{
  "repository"{
    "type""git",
    "url""https://github.com/npm/cli.git"
  }
}

URL 應該是一個公開可用的(可能是隻讀的)url,可以直接傳遞給 VCS 程序,無需任何修改。它不應該是您放入瀏覽器的 html 項目頁面的 url。是給電腦用的。

對於 GitHub、GitHub gist、Bitbucket 或 GitLab 存儲庫,您可以使用與 相同的快捷語法npm install

{
  "repository""npm/npm",

  "repository""github:user/repo",

  "repository""gist:11081aaa281",

  "repository""bitbucket:user/repo",

  "repository""gitlab:user/repo"
}

如果package.json您的包的 不在根目錄中(例如,如果它是 monorepo 的一部分),您可以指定它所在的目錄:

{
  "repository"{
    "type""git",
    "url""https://github.com/facebook/react.git",
    "directory""packages/react-dom"
  }
}

config(配置內容)

“config” 對象可用於設置在升級過程中持續存在的包腳本中使用的配置參數。例如,如果一個包具有以下內容:

{
  "name""foo",
  "config"{
    "port""8080"
  }
}

然後有一個 “開始” 命令,然後引用 npm_package_config_port環境變量,然後用戶可以通過執行npm config set foo:port 8001.

查看configscripts瞭解更多關於包配置的信息。

peerDependencies(對等依賴)

在某些情況下,您希望表達您的包與主機工具或庫的兼容性,而不必執行require此主機的操作。這通常稱爲_插件_。值得注意的是,您的模塊可能會公開主機文檔所預期和指定的特定接口。

例如:

{
  "name""tea-latte",
  "version""1.3.5",
  "peerDependencies"{
    "tea""2.x"
  }
}

這確保您的軟件包tea-latte只能與主機軟件包的第二個主要版本_一起_安裝teanpm install tea-latte可能會產生以下依賴圖:

├── tea-latte@1.3.5
└── tea@2.2.0

在 npm 版本 3 到 6 中,peerDependencies不會自動安裝,如果在樹中發現對等依賴項的無效版本,則會發出警告。由於 NPM V7 的,peerDependencies  默認安裝。

如果無法正確解析樹,嘗試安裝具有衝突要求的另一個插件可能會導致錯誤。因此,請確保您的插件要求儘可能廣泛,而不是將其鎖定爲特定的補丁版本。

假設主機符合 semver,只有主機包的主要版本中的更改纔會破壞您的插件。因此,如果您使用過主機包的每個 1.x 版本,請使用"^1.0""1.x" 來表達這一點。如果您依賴 1.5.2 中引入的功能,請使用 "^1.5.2".

peerDependenciesMeta(捆綁依賴)

這定義了在發佈包時將捆綁的包名稱數組。

如果您需要在本地保留 npm 包或通過單個文件下載使它們可用,您可以通過在bundledDependencies 數組中指定包名稱並執行npm pack.

例如:

如果我們像這樣定義 package.json:

{
  "name""awesome-web-framework",
  "version""1.0.0",
  "bundledDependencies"[
    "renderized",
    "super-streams"
  ]
}

我們可以awesome-web-framework-1.0.0.tgz通過運行獲取文件npm pack。此文件包含的依賴關係renderized,並super-streams可以通過執行安裝在一個新的項目npm install awesome-web-framework-1.0.0.tgz。請注意,包名稱不包含任何版本,因爲該信息在dependencies.

如果這是拼寫"bundleDependencies",那麼這也很榮幸。

optionalDependencies(可選依賴項)

如果可以使用依賴項,但如果找不到或安裝失敗,您希望 npm 繼續,那麼您可以將其放入 optionalDependencies對象中。這是包名稱到版本或 url 的映射,就像dependencies對象一樣。不同之處在於構建失敗不會導致安裝失敗。運行npm install --no-optional將阻止安裝這些依賴項。

處理缺少依賴項仍然是您的程序的責任。例如,這樣的事情:

try {
  var foo = require('foo')
  var fooVersion = require('foo/package.json').version
} catch (er) {
  foo = null
}
if ( notGoodFooVersion(fooVersion) ) {
  foo = null
}

// .. then later in your program ..

if (foo) {
  foo.doFooThings()
}

中的條目optionalDependencies將覆蓋 中的同名條目 dependencies,因此通常最好只放在一個地方。

publishConfig(發佈配置)

這是一組將在發佈時使用的配置值。如果您想設置標記、註冊表或訪問權限,這將特別方便,這樣您就可以確保給定的包沒有被標記爲 “最新”、未發佈到全局公共註冊表或默認情況下範圍模塊是私有的。

查看config可覆蓋的配置選項列表。

workspaces(工作區)

可選workspaces字段是一個文件模式數組,它描述了本地文件系統內的位置,安裝客戶端應該查找這些位置以找到需要符號鏈接到頂級文件夾的每個工作區node_modules

它可以描述要用作工作區的文件夾的直接路徑,也可以定義將解析爲這些相同文件夾的 glob。

在以下示例中,./packages只要文件夾中包含有效package.json文件,位於文件夾內的所有文件夾 都將被視爲工作區 :

{
  "name""workspace-example",
  "workspaces"[
    "./packages/*"
  ]
}

有關workspaces更多示例,請參見。

總結

本文幾乎是全網最全的 package.json 的講解了。一些常用的和不常用的都有區分,不常用的可以當百科全書查一下,面試主要也是會問一些主要內容。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/W1MxoZKCnCumWWbOIWVizw