每個前端專案中都有一個 package.json 檔案,你瞭解它嗎?花幾分鐘再重新審視一下這個熟悉的陌生人。
如何生成 package.json
在專案資料夾下執行npm init -y
快速生成。 -y
代表一路 yes
。開啟檔案我們看到以下資訊。
{
"name": "package-json",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
逐個介紹下上述欄位:
name
包名稱,必填項version
包版本,必填項description
包描述資訊,一句話介紹這個包的用途main
包入口檔案。
如require('package-json')
,相當於使用了包的index.js。 該欄位在開發 npm 包時較為常見,身為切圖仔的我們接觸的不多。scripts
包執行指令碼,常用的npm start
、npm run dev
、npm run build
都是註冊在這裡的。keywords
關鍵詞與 description 類似,用於介紹包的用途author
包建立者license
包協議,用於規定是否開源、是否付費
web 專案的 package.json
大部分開發者是圍繞 web 開發進行工作的。我們來看看 web 專案的 package.json 常見配置欄位 dependencies
、devDependencies
、private
、scripts
...
dependencies & devDependencies
面試官:請講講dependencies
和devDependencies
的區別?
簡單,dependencies是生產環境的依賴,安裝包時執行npm install -S xxx
;devDependencies 是開發環境的依賴, 安裝包需要執行 npm install -D xxx
生產環境和開發環境指什麼?如果不小心將 react 或 vue 這種依賴安裝到 devDependencies
列表中專案還能執行嗎?
就 web 專案而言,筆者認為dependencies
和devDependencies
的本質差異並不大。包安裝在哪,專案都能正常的構建、執行。差異主要在於語義表達。
dependencies
往往是指打包構建後依賴包的程式碼會被打進產物中,在生產環境執行中是不可缺少的。
devDependencies
是指那些開發、構建過程中那些工具,如構建使用的webpack、程式碼檢查的 eslint、程式碼轉義的 babel 等都屬於開發環境依賴。他們存在的目的是:幫助我們將開發的程式碼安全、便捷的轉換成使用者瀏覽器可執行的程式碼。
還有一點差異, npm install --production=true 不會安裝 devDependencies
下的依賴的,只會安裝dependencies
的依賴。一般沒人會控制這個變數。
private
若package.json中設定了 "private": true
,npm 將拒絕釋出它。
web 專案大多不需要提交到 npm 倉庫,建議將 private
設為 true。
順便一提 monorepo 熱潮下,大家會將 monorepo 專案根目錄的 private
設為 true,來避免哪個小夥伴誤將整個目錄發包
scripts
scripts
控制專案生命週期的指令碼。想一下天天用的 npm run dev、npm run build、npm run lint都做了哪些事情。看看scripts配置便知。
如果想了解團隊專案工程化實現,那麼也建議從 scripts 配置入手,一點點讀懂命令對應的指令碼檔案,你就是工程大佬了。
scripts
需要著重介紹的一點是命令鉤子pre
、post
。鉤子可以註冊某命令的前置命令和後置命令。
寫個例子吧:
{
"scripts": {
"prexxx": "echo 'start~'",
"xxx": "echo 'xxx running'",
"postxxx": "echo 'end!'"
}
}
當我們執行 npm run xxx時會看到下面結果。prexxx
、postxxx
被自動執行。
用途:在commit之前執行 lint ,npm run dev之前自動為使用者安裝包等等~
想想還可以做哪些事情,歡迎討論。
engines
我們很難保證同事間的開發環境統一,例如不同開發者的 node 版本是不一致的,有人是8.x, 有人是10.x 有人是14.x。來個新人問一下你們 node 用什麼版本,累不累。配置下 engines
吧
"engines": {
"node": ">=12.10.0 <15"
}
上述版本是我亂寫,如果開發者的版本不符合要求控制檯會報錯引導使用者去改正,避免了口口相傳
非 web 專案的 package.json
之前介紹的欄位,同樣適用。有幾個屬性是包專案常用且有用的。
如main
、files
、bin
main
前文已經介紹過, 包的入口檔案。預設是專案根目錄下的index.js。
"main":"./lib/index.js",
如果你的包名是package-json, 當使用者程式碼require('package-json')
時,相當於require了你包目錄下的 ./lib/index.js
檔案。
files
files
用於決定哪些檔案被髮布到 npm 倉庫去。不在files中的檔案,包的使用者是無法訪問的,main
指向的檔案也必須存在於這個列表範圍內。
"files": [
"src",
"dist/*.js",
"types/*.d.ts"
],
bin
命令列工具入口。當你的包提供了一個命令列工具時,你需要為命令列工具指定一個入口。命令名稱和本地可指定檔案的對應關係。可以參考看看vue-cli-service的原始碼
"bin": {
"vue-cli-service": "bin/vue-cli-service.js"
}
如果你細心的話會發現我們們專案下的node_modules/bin資料夾裡有好多可執行檔案。
對使用者來說:本地安裝包的bin
下的可執行檔案會被連結到 ./node_modules/.bin/
;全域性安裝包的bin
將會被軟鏈到 /usr/local/bin
下。
dependencies & devDependencies
當我們的專案作為一個包提供給別人使用時,開發者執行npm install
我們需要注意只有dependencies
會作為包的依賴安裝,devDependencies
則會被忽略掉,講到這裡相信大家終於能理解什麼是開發環境、什麼是生產環境了。
開發包是需要注意不要誤將生產依賴安裝到devDependencies
中去,會導致你的使用者跑不起來。
其他
建議:有什麼工程上的疑問,自己先看專案配置檔案,還不懂再諮詢同事。不然可能會被噴~
關注我,不迷路