熟悉又陌生的package.json
前言
隨著前端的不時(shí)開展,package.json
可謂是在前端項(xiàng)目中無處不在,它不只在項(xiàng)目根目錄會(huì)有,而且在?node_modules?中也存在。那么這個(gè)文件到底是干嘛的,又有什么作用?很多人對(duì)它的認(rèn)識(shí)是不是只停留在dependencies
、devDependencies
項(xiàng)目依賴列表,或者是script
項(xiàng)目的各種腳本指令等,實(shí)踐上它能做的事情遠(yuǎn)不止這些。
創(chuàng)立package.json
現(xiàn)往常當(dāng)你運(yùn)用腳手架生成一個(gè)根本的項(xiàng)目時(shí),它會(huì)自動(dòng)幫你生成package.json
。
當(dāng)我們手動(dòng)創(chuàng)立項(xiàng)目時(shí),能夠運(yùn)用npm init
,然后依據(jù)提示一步步輸入相應(yīng)的內(nèi)容完成后即可自動(dòng)創(chuàng)立,當(dāng)然你也能夠運(yùn)用npm init -y
跳過交互直接生成
npm init
生成的根底package.json
文件內(nèi)容如下:
這樣看著十分簡單,事實(shí)上,它所包含的功用屬性遠(yuǎn)不止這些。
常見屬性
name
它表示項(xiàng)目稱號(hào),該字段決議了你發(fā)布的包在 npm 的名字,也就是平常裝置依賴的包名
一些規(guī)則:
稱號(hào)必需小于或等于 214 個(gè)字符。這包括范圍包的范圍。
作用域包的稱號(hào)能夠以點(diǎn)或下劃線開頭。假如沒有范圍,這是不允許的。
新包的稱號(hào)中不得包含大寫字母。
該稱號(hào)最終成為 URL、命令行參數(shù)和文件夾稱號(hào)的一局部。因而,稱號(hào)不能包含任何非 URL 平安字符。
version
它表示項(xiàng)目的版本號(hào),該"version"
屬性必需采用major.minor.patch
格式的方式。
{ ?"version": "1.0.0"}
普通來講假如你方案發(fā)布包,則package.json
?中最重要的內(nèi)容就是name和version,由于它們是必需的。稱號(hào)和版本一同構(gòu)成一個(gè)標(biāo)識(shí)符,假定該標(biāo)識(shí)符是完整獨(dú)一的。對(duì)包的更改應(yīng)該隨同著對(duì)版本的更改。假如你不打算發(fā)布包,則name和version字段是可選的。
description
它表示項(xiàng)目的描繪信息,該內(nèi)容會(huì)直接展現(xiàn)在npm
官網(wǎng),它主要是為了讓其別人快速理解的項(xiàng)目
keywords
它表示項(xiàng)目的關(guān)鍵字,它是一個(gè)數(shù)組,它能夠便當(dāng)其別人更好的搜索
{ ?"keywords": ["songyao", "songyao-cli", "cli"]}
比方這個(gè)我之前寫的腳手架,在npm
上的檢索信息
author
它表示項(xiàng)目的作者信息,它既能夠是一個(gè)字符串,又能夠是一個(gè)對(duì)象
{ ?"author": "nanjiu"}{ ?"author": { ? ?"name": "nanjiu", ? ?"email": "xxx@163.com", ? ?"url": "https://bettersong.github.io/nanjiu/" ?}}
其中email
、url
是可選的
repository
它表示項(xiàng)目的倉庫地址
簡單寫法:
{ ?"repository": "https://github.com/***"}
版本控制寫法:
{ ?"repository": { ?"type": "git", ?"url": "http://github.com/***", ?"directory": "nanjiu" ? ?}}
contributors
它表示項(xiàng)目的奉獻(xiàn)者,該字段是一個(gè)數(shù)組
{ ?"contributors": [ ?{ ? ? ?"name" : "nanjiu", ? ? ?"email" : "nanjiu@xx.com", ? ? ?"url" : "https://bettersong.github.io/nanjiu/" ? ?}, ]}
script
它表示項(xiàng)目的可執(zhí)行腳本命令
{ ?"script": { ? ?"start": "node ./build/cli.js start", ? ?"dev": "vue-cli-service serve --mode dev", ? ?"build:oa": "vue-cli-service build --mode oa", ? ?"build:oa-legacy": "vue-cli-service build --mode oa --modern", ? ?"build:pre": "vue-cli-service build --mode pre --modern", ?}}
執(zhí)行時(shí)運(yùn)用npm run
對(duì)應(yīng)的key
就能夠,比方npm run start
每個(gè) npm script 有 pre 和 post 兩個(gè)鉤子, pre 鉤子在腳本執(zhí)行前將被觸發(fā), post 則是在腳本執(zhí)行后觸發(fā)
### dependencies
它表示項(xiàng)目消費(fèi)環(huán)境中所需的依賴,當(dāng)運(yùn)用npm
裝置時(shí),依賴會(huì)默許插入該字段中
{ ?"dependencies": { ? ?"@nestjs/common": "^10.0.0", ? ?"@nestjs/core": "^10.0.0", ? ?"@nestjs/mapped-types": "*", ? ?"@nestjs/platform-express": "^10.0.0", ? ?"@types/cors": "^2.8.13", ? ?"cors": "^2.8.5", ? ?"reflect-metadata": "^0.1.13", ? ?"rxjs": "^7.8.1", ?}}
在裝置依賴時(shí)也能夠運(yùn)用--save
參數(shù),表示依賴是消費(fèi)環(huán)境所需
npm install--save
或者運(yùn)用-S
簡寫
npm i-S
devDependencies
它表示項(xiàng)目開發(fā)環(huán)境所需的依賴,比方webpack
、vite
、babel
等工程化依賴包。這些依賴表示只需求在開發(fā)環(huán)境裝置,無需在消費(fèi)環(huán)境裝置。
{ ?"devDependencies": { ? ?"@nestjs/cli": "^10.0.0", ? ?"@nestjs/schematics": "^10.0.0", ? ?"@nestjs/testing": "^10.0.0", ?}}
想要將依賴制定裝置在devDependencies
下,能夠運(yùn)用如下命令:
npm i--save-dev
或者
npm i-D
browserslist
它表示打包時(shí)需求支持哪些閱讀器,普通babel
、autoperfixer
會(huì)運(yùn)用該字段停止配置
{ ?"browserslist": [ ? ?"> 1%", ? ?"last 2 versions", ? ?"iOS >= 9.3", ? ?"Android >= 6.0" ?],}
babel
它表示babel
的配置項(xiàng),用來指定babel
的編譯配置
{ ?"babel": { ? ?"presets": ["@babel/preset-env"] ?}}
不過引薦做法還是運(yùn)用babel
單獨(dú)配置文件:babel.config.js
等
gitHooks
它表示git
定制化腳本程序,能夠用來配置代碼提交檢測(cè)等
比方:
{ ?"scripts": { ? ?"lint:diff": "node ./models/pre_commit.js" ?}, ?"gitHooks": { ? ?"pre-commit": "npm run lint:diff" ?},}
hook類型有很多種:
commit-msg:?鉤子在啟動(dòng)提交信息編輯器之前,默許信息被創(chuàng)立之后運(yùn)轉(zhuǎn)。
post-update:?僅在一切的ref被push之后執(zhí)行一次。它與post-receive很像,但是不接納舊值與新值。主要用于通知。
pre-applypatch:?實(shí)踐上的調(diào)用機(jī)遇是應(yīng)用補(bǔ)丁之后、變卦commit之前。
pre-commit:?鉤子在鍵入提交信息前運(yùn)轉(zhuǎn)。
prepare-commit-msg:?鉤子在啟動(dòng)提交信息編輯器之前,默許信息被創(chuàng)立之后運(yùn)轉(zhuǎn)。
pre-push:?鉤子會(huì)在 git push 運(yùn)轉(zhuǎn)期間, 更新了遠(yuǎn)程援用但尚未傳送對(duì)象時(shí)被調(diào)用。
pre-rebase:?鉤子運(yùn)轉(zhuǎn)于變基之前,以非零值退出能夠中止變基的過程。
post-checkout:?更新工作樹后調(diào)用checkout時(shí)調(diào)用,或者執(zhí)行 git clone后調(diào)用。主要用于考證環(huán)境、顯現(xiàn)變卦、配置環(huán)境。
等...
生疏屬性
以上這些屬性想必是每個(gè)package.json
文件中常見的屬性,但它除了以上這些屬性之外還有許多同樣十分重要的屬性。
bugs
它表示項(xiàng)目問題的提交地址,這個(gè)普通在開源項(xiàng)目中見的多
{ ?"bugs": { ? ? "url" : "http://github.com/***/issues", ? ? ? "email" : "nanjiu@xx.com" ?}}
peerDependencies
它表示項(xiàng)目對(duì)等依賴,運(yùn)用npm install --save-peer
裝置
這個(gè)其真實(shí)我們工作中用的并不多,普通用于開發(fā)插件,避免項(xiàng)目在裝置該插件時(shí),屢次裝置相同的依賴
{ ?"peerDependencies": { ?"react": ">=16.9.0", ?"react-dom": ">=16.9.0" ?},}
需求留意的是在?npm 2
?中,當(dāng)我們下載?ant-design@3.x
?時(shí),peerDependencies
?中指定的依賴會(huì)隨著?ant-design@3.x
?一同被強(qiáng)迫裝置,所以我們不需求在宿主項(xiàng)目的?package.json
?文件中指定?peerDependencies
?中的依賴,但是在?npm 3
?中,不會(huì)再強(qiáng)迫裝置?peerDependencies
?中所指定的包,而是經(jīng)過正告的方式來提示我們,此時(shí)就需求手動(dòng)在?package.json
?文件中手動(dòng)添加依賴
optionalDependencies
它表示可選依賴項(xiàng)
當(dāng)你希望某些依賴即便下載失敗或者沒有找到時(shí),項(xiàng)目仍然能夠正常運(yùn)轉(zhuǎn)或者 npm 繼續(xù)運(yùn)轉(zhuǎn)的時(shí),就能夠把這些依賴放在?optionalDependencies
?對(duì)象中,但是?optionalDependencies
?會(huì)掩蓋?dependencies
?中的同名依賴包,所以不要把一個(gè)包同時(shí)寫進(jìn)兩個(gè)對(duì)象中。
需求留意,由于optionalDependencies中的依賴可能并為裝置勝利,所以一定要做異常處置,否則當(dāng)獲取這個(gè)依賴時(shí),假如獲取不到就會(huì)報(bào)錯(cuò)。
try { ?var axios = require('axios') ?var fooVersion = require('axios/package.json').version } catch (er) { ?// 報(bào)錯(cuò)}
bundledDependencies
它表示捆綁依賴項(xiàng)
與其他幾種依賴項(xiàng)不同,他不是一個(gè)鍵值對(duì)的對(duì)象,而是一個(gè)數(shù)組,數(shù)組里是包名的字符串,例如:
{ ?"bundleDependencies": [ ? ?"axios", ? ? ?"lodash" ?] }
engines
它表示聲明node環(huán)境
與依賴關(guān)系一樣,假如不指定版本(或者指定“ *”作為版本) ,那么任何版本的節(jié)點(diǎn)都能夠。
{ ?"engines": { ? ?"node": ">=0.10.3 <15" ?}}
main
它表示項(xiàng)目的入口文件,假如不指定該字段,默許是根目錄下的index.js
{ ?"main": "./src/index.js",}
從 Node.js 12.20.0 版本開端,"main" 字段也能夠指定 ES 模塊的入口文件
browser
它表示UMD模塊的入口文件
UMD:兼容 CommonJS 和 AMD 的模塊,既能夠在 node 環(huán)境中被?require
?援用,也能夠在閱讀器中直接用 CDN 被script
標(biāo)簽 引入
main 字段里指定的入口文件在 browser 和 node 環(huán)境中都能夠運(yùn)用。假如只想在 web 端運(yùn)用,制止在 server 端運(yùn)用,能夠經(jīng)過 browser 字段指定入口。
{ ?"browser": "./src/index.js" }
module(非官方字段)
它表示ES模塊入口文件,閱讀器環(huán)境和 node環(huán)境均可運(yùn)用
{ ?"module": "./src/index.js" }
在Web環(huán)境中,假如運(yùn)用loader加載ESM(ES module),那么這三個(gè)配置的加載次第是browser→module→main
,假如運(yùn)用require加載CommonJS模塊,則加載的次第為main→module→browser
。
main
、browser
、module
三個(gè)字段都是用于 npm 包的,假如項(xiàng)目不是作為 npm 包發(fā)布,這三個(gè)字段不需求寫。
導(dǎo)出包只在 web 端運(yùn)用,并且制止在 server 端運(yùn)用,運(yùn)用?
browser
導(dǎo)出包只在 server 端運(yùn)用,運(yùn)用?
main
導(dǎo)出 ESM 標(biāo)準(zhǔn)的包,運(yùn)用?
module
導(dǎo)出包在 web 端和 server 端都允許運(yùn)用,運(yùn)用?
module
?和?main
exports(非官方字段)
它表示當(dāng)打包工具支持exports
字段時(shí),?main/browser/module
的配置將被疏忽,而運(yùn)用該字段
{ ?"exports": { ? ?"require": "./index.js", ? ?"import": "./index.mjs" ?}}
type(非官方字段)
它表示指定運(yùn)用那種模塊方式,默許值為commonjs
比方指定運(yùn)用ES Module
:
{ ?"type":"module"}
files
它表示指定哪些文件能夠被上傳到npm上,有點(diǎn)相似.gitignore
,但功用與之相反
{ ?"files": [ ? ?"index.js", ? ?"dist" ?],}
無論設(shè)置如何,一直包含某些文件:
package.json
README
LICENSE
/LICENCE
main
字段中的文件
os
它表示該模塊只能在那個(gè)操作系統(tǒng)上運(yùn)轉(zhuǎn)
{ ?"os" : [ "darwin", "linux", "win32" ]}
還能夠阻止而不是允許操作系統(tǒng),只需在被阻止的操作系統(tǒng)前面加上!
{ ?"os": [ ? ?"!win32" ?]}
cpu
它表示指定項(xiàng)目只在某些CPU架構(gòu)上運(yùn)轉(zhuǎn)
{ ?"cpu": [ ? ?"x64", ? ?"ia32" ?]}
與os
相似,它同樣能夠運(yùn)用!
{ ?"cpu": [ ? ?"!arm", ? ?"!mips" ?]}
private
它表示該項(xiàng)目是私有的,能夠避免我們將私有項(xiàng)目發(fā)布到npm
上
{ ?"private": true}
preferGlobal
當(dāng)設(shè)置?preferGlobal
?字段為 true 時(shí),它表示你的包更合適以全局方式裝置,而不是作為項(xiàng)目的依賴項(xiàng)停止本地裝置。
<button type="button" class="btn btn-dark rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="{ "preferGlobal": true }" aria-label="復(fù)制" data-bs-original-title="復(fù)制">
{ ?"preferGlobal": true}