你可能不知道的package.json

2021-12-26 若川視野
前言

在上一篇npm init @vitejs/app的背後,僅是npm CLI的冰山一角[1]中,有提到我複習npm主要是從兩個大方向來入手,所以這篇繼續來講講package.json這部分知識,經過這輪複習,也發現了自己的很多不足,之前把常用的命令和配置玩熟了,卻沒關心npm已經有了更多新的玩法,而這些玩法卻實實在在地在解決別人的問題。

npm 的配置還是挺多的,具體可以參考package.json官方文檔[2]。通讀了文檔之後,我略過了一些基礎的配置項,總結了一些我認為比較有用的配置項。

常用配置項files

files定義了哪些文件應該被包括在 npm install 後的 node_modules中。

當然,有些文件是自動暴露出來的,不管你是不是配置了files,比如:

README / CHANGELOG / LICENSE

很多庫都定義了 files,避免一些不必要的文件暴露到 node_modules 中。

vite 中是這樣配置的:

{
  "files": [ "bin", "dist", "client.d.ts" ]
}

我之前就不知道這個配置,導致我發布的一個 npm 組件 vue-awesome-progress[3] 就暴露了源碼部分,雖然這也沒啥影響,本來就是開源的。但是這也增加了別人的資源下載量,也是一種浪費。所以,專業點的搞法還是加上files配置吧。

bin

bin 列出了可執行文件,表示你這個包要對外提供哪些腳本。

在這個包被 install 安裝時,如果是全局安裝 -g,bin 列出的可執行文件會被添加到 PATH 變量(全局可執行);如果是局部安裝,則會進入到 node_modules/.bin/ 目錄下。

bin 在一些 CLI 工具中用得很頻繁,比如 Vue CLI。

在開發 npm 包時,要求發布的可執行腳本要以#!/usr/bin/env node開頭,這是為什麼呢?

我查了一下,原來是為了用於指明該腳本文件要使用 node 來執行。

main, browser, module

這三個配置對我們的影響還是挺大的。

main欄位決定了別人require('xxx')時,引用的是哪個模塊對象。在不設置main欄位時,默認值是index.js。如果你開發的包是用於瀏覽器端的,那麼用browser指定入口文件是最佳的選擇。module則代表你開發的包支持ESM,並指定了一個ESM入口。

具體這三個欄位怎麼用,還是挺有學問的,這裡推薦一篇文章package.json中你還不清楚的browser,module,main 欄位優先級[4],講得挺細。

長圖警告!

scripts

scripts也基本上每天都用了,但是它的鉤子腳本你用過嗎?如果沒有用過,可以試試,在組織腳本流程時非常好用!

pre:在一個script執行前執行,比如prebuild,可以在打包前做一些準備工作。post:在一個script執行後執行,比如postbuild,可以在打包後做一些收尾工作。config

通過config配置的參數xxx,可以在腳本中通過npm_package_config_xxx 的形式引用,比如port。

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

依賴相關dependencies

dependencies可以理解為生產依賴,通過npm install --save安裝的依賴包都會進入到dependencies中。

devDependencies

devDependencies可以理解為開發環境依賴,通常是一些工具類的包,比如 webpack, babel等。通過npm install --save-dev安裝的依賴包都會進入到devDependencies中。

但是,在結合一些構建工具使用時,我們往往會有困惑。比如我安裝了一個包到devDependencies中,但是不小心在項目中引用了它,最後也被 webpack 打包到構建結果中了。這是怎麼回事呢?

建議結合上篇文章npm install這一節[5]一起看。

peerDependencies

我是package-a,你裝我,你就必須裝我的peerDependencies

讓「調包俠」將package-a的依賴提升到自己的node_modules中,這樣可以在「調包俠」和package-a都需要同一個依賴(比如vue)時,避免重複安裝。這常見於開發組件或者庫。

注意,一個 npm 包的開發者如果聲明了peerDependencies,開發環境下在該包目錄npm install也不會在node_modules中安裝這些依賴,所以往往還需要藉助devDependencies。

舉個例子,我開發一個組件,不想發布到 npm 時包含了 vue 的代碼,這就需要外部提供 vue ,所以我把 vue 定義在 peerDependencies 也無可厚非。但是,在開發組件時,一般還需要本地開發環境跑一個 demo 試試效果,這時候是依賴 vue 的,所以還需要在 devDependencies 中安裝 vue 。我看了下 vue-router 就是這麼做的,所以我在開發自己的組件時也學會了這招。

bundledDependencies

bundledDependencies跟上面的依賴都不太一樣,配置上不是鍵值對的形式,而是一個數組。

{
  "bundledDependencies": [
    "vue",
    "vue-router"
  ]
}

在運行npm pack時,會將對應依賴打包到tgz文件中。用得不多,不知道具體的細節,主要還是直接用npm install安裝 tgz 包的場景比較少,有個概念就行。

optionalDependencies

optionalDependencies用於配置可選的依賴,即使配了這個,代碼裡也要做好判斷(保護),否則運行報錯就不好玩了。

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

題外話

仔細讀過package.json文檔後,整體上還是解決了我的不少困惑,對我開發 npm 組件也提供了不少幫助。如果您想了解更多細節和實戰,不妨打開我這個項目vue-awesome-progress[3]看看,希望對您有所幫助!

參考[1]

npm init @vitejs/app的背後,僅是npm CLI的冰山一角: https://juejin.cn/post/6950817077670182943

[2]

package.json官方文檔: https://docs.npmjs.com/cli/v7/configuring-npm/package-json

[3]

vue-awesome-progress: https://cumt-robin.github.io/vue-awesome-progress/

[4]

package.json中你還不清楚的browser,module,main 欄位優先級: https://www.cnblogs.com/qianxiaox/p/14041717.html

[5]

上篇文章npm install這一節: https://juejin.cn/post/6950817077670182943#heading-6

相關焦點

  • 全方位解讀 package.json
    平常在工作中,對package.json這個文件的接觸非常非常少。一些同學可能還會看一下script裡面有什麼命令,執行了哪些方法。又或者了解一下dependencies和devDependencies其他大部分的同學可能直接就npm i和npm start就開始工作了。
  • 關於前端大管家package.json,你知道多少
    今天來看看前端的大管家 package.json 文件相關的配置,充分了解這些配置有助於我們提高開發的效率,規範我們的項目。文章內容較多,建議先收藏在學習!在每個前端項目中,都有 package.json 文件,它是項目的配置文件,常見的配置有配置項目啟動、打包命令,聲明依賴包等。
  • 大前端快閃:package.json文件知多少?
    快閃一:package.json文件知多少如果你使用了nodejs、npm項目、Angular項目等,你都會用到package.json文件,package.json文件是項目的清單文件,package.json在react項目開發和部署階段扮演了重要角色。
  • 這還是我最熟悉的package.json嗎?
    在不設置main欄位時,默認值是index.js。如果你開發的包是用於瀏覽器端的,那麼用browser指定入口文件是最佳的選擇。module則代表你開發的包支持ESM,並指定了一個ESM入口。具體這三個欄位怎麼用,還是挺有學問的,這裡推薦一篇文章package.json中你還不清楚的browser,module,main 欄位優先級[4],講得挺細。長圖警告!
  • npm配置文件package.json裡面的欄位你知道多少
    創建一個前端項目目前都離不開npm包管理工具,所以根目錄必須有一個package.json文件如何創建呢?1.2.3)(1.2.3)(^1.2.3)-- 大版本和小版本-- 1代表大版本(如果有整個項目的改動可以直接修改大版本)-- 2.3代表小版本(功能修改可以用小版本)-- ~會匹配最近的小版本依賴包,比如~1.2.3會匹配所有1.2.x版本,但是不包括
  • 【第878期】Node, NPM, Yarn 和 package.json
    正文從這開始~在本節中,我們將學習如何設置 Node,NPM,Yarn 和 package.json。首先需要安裝 Node,它提供了後端 JavaScript 的運行環境,同時還包括構建前端技術棧所需的所有工具。macOS 或 Windows 用戶可以直接下載安裝文件,Linux 用戶可以通過包管理器安裝。
  • 細說Golang的JSON解析
    Go語言自帶的json包可以讓你在程序中方便的讀取和寫入 JSON 數據。生成JSON場景相對簡單一些,json.Marshal()會根據傳入的結構體生成JSON數據。解析JSON會把數據解析到結構體中,由於JSON格式的自由組合的特點,尤其是那些結構複雜的JSON數據對新手來說聲明接受JSON數據的結構體類型就會陷入不知從何下手的困擾。
  • 你不知道的 Npm(Node.js 進階必備好文)
    為什麼寫這篇文章很多 Node.js 開發者,都知道有 package.json 這個文件,也多少都了解一些 npm 知識,但是可能沒有系統的學習過,這部分的知識對於開發一個  cli 工具,發布自己的 npm 包都很常用,開發中也會經常用到npm script內容,系統的學習一下確實會有所幫助,上面三個場景如果你都用不到,配置上節約時間,
  • 現代配置指南——YAML 比 JSON 高級在哪?
    一般靜態化的配置會選擇 json 文件,而動態化的配置,涉及到引入其他模塊,因此會選擇 js 文件。還有現在許多新工具同時支持多種配置,比如 Eslint,兩種格式的配置任你選擇:後來不知道什麼時候,突然出現了一種以 .yaml 或 .yml 為後綴的配置文件。
  • 手把手教你擼一個JSON解析器
    一個佛系的公眾號《你的第一:總有人喜歡你,總有人不喜歡你》
  • 【Go Web開發】發送JSON響應
    [https://towardsdatascience.com/an-introduction-to-json-c9acb464f43e]提供了完整的介紹,建議你在繼續之前可以先閱讀裡面的內容。實際上,我們需要做的唯一特殊的事情是在響應上設置Content-Type: application/json頭,以便客戶端知道它正在接收json,並相應地解析它。下面我就開始這麼做。
  • 擼一個 JSON 解析器
    下面我們封裝一個token類來存儲每一個token對應的值   package com.json.demo.tokenizer;public class Token {    private TokenType tokenType;    private String value;    public Token
  • 你應該知道的 NPM 知識都在這!
    package.json 這個文件,也多少都了解一些 npm 知識,但是可能沒有系統的學習過,這部分的知識對於開發一個  cli 工具,發布自己的 npm 包都很常用,開發中也會經常用到npm script內容,系統的學習一下確實會有所幫助,上面三個場景如果你都用不到,配置上節約時間,知其所以然也是有必要的!
  • 擼一個JSON解析器
    下面我們封裝一個token類來存儲每一個token對應的值package com.json.demo.tokenizer;public class Token {    private TokenType tokenType;    private String value;    public Token
  • Go語言複合數據類型之JSON
    Go語言通過標準庫encoding/json,encoding.xml,encoding/asn1和其他庫對JSON的解碼和編碼做了很好的支持,這些庫都擁有相同的API。我們在實例中使用最多的encoding/json來做演示。
  • 【 Node.js】你應該知道的 NPM 知識都在這!
    為什麼寫這篇文章很多 Node.js 開發者,都知道有 package.json 這個文件,也多少都了解一些 npm 知識,但是可能沒有系統的學習過,這部分的知識對於開發一個  cli 工具,發布自己的 npm 包都很常用,開發中也會經常用到npm script內容,系統的學習一下確實會有所幫助,上面三個場景如果你都用不到,配置上節約時間,
  • 【 Node.js 進階】你應該知道的 NPM 知識都在這!
    為什麼寫這篇文章很多 Node.js 開發者,都知道有 package.json 這個文件,也多少都了解一些 npm 知識,但是可能沒有系統的學習過,這部分的知識對於開發一個  cli 工具,發布自己的 npm 包都很常用,開發中也會經常用到npm script內容,系統的學習一下確實會有所幫助,上面三個場景如果你都用不到,配置上節約時間,
  • 使用golang解析yaml、json、xml文件
    "email": "jaingzong@163.com"      }    },    {      "name": "喬克",      "address": "chongqing",      "age": 30,      "social": {        "mobile": "11333331111111",
  • 你不知道的 JSON.stringify!!!
    我們可能會想像一個叫做 "stringify "的函數總是返回一個字符串.但它並沒有!例如,如果你嘗試 stringify undefined,它返回 undefined ,而不是一個字符串。JSON.stringify 也可能遇到問題,導致它拋出一個錯誤。
  • 自己手擼一個 JSON 解析器
    下面我們封裝一個token類來存儲每一個token對應的值package com.json.demo.tokenizer;/** * 存儲對應類型的字面量 */public class Token {    private TokenType tokenType;    private String value;