溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

package.json和package-lock.json怎么使用

發(fā)布時間:2022-09-02 09:43:31 來源:億速云 閱讀:584 作者:iii 欄目:web開發(fā)

本文小編為大家詳細(xì)介紹“package.json和package-lock.json怎么使用”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“package.json和package-lock.json怎么使用”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。

在說package.jsonpackage-lock.json之前,我們先來說說npm安裝包的方式npm的安裝流程。

npm 安裝包的方式

npm 安裝包的方式分為本地安裝和全局安裝。安裝使用npm install或簡寫形式npm i。

本地安裝

本地安裝的包只能在當(dāng)前目錄下使用。

本地安裝很簡單,以element-ui為例

npm i element-ui

在實(shí)際項(xiàng)目開發(fā)過程中,本地安裝我們都會先生成package.json文件。然后安裝的時候包的版本會自動記錄在該文件中。

本地安裝的包又分為開發(fā)依賴(devDependencies)和生產(chǎn)依賴(dependencies)

對于一些只會在開發(fā)環(huán)境中用到的包我們可以安裝在開發(fā)依賴(devDependencies)中。比如webpack、vite等等。

對于一些會在生產(chǎn)環(huán)境中用到的包我們可以安裝在生產(chǎn)依賴(dependencies)中。比如element-ui等等。

那么怎么讓安裝的包分別放到對應(yīng)的依賴位置呢?

如果想要安裝的包放在開發(fā)依賴(devDependencies)中,我們傳遞參數(shù) --save-dev-D 即可。

如果想要安裝的包放在生產(chǎn)依賴(dependencies)中,我們傳遞參數(shù) --save-S 即可。

注意如果我們沒傳遞依賴參數(shù)。會把包默認(rèn)安裝到生產(chǎn)依賴(dependencies)

全局安裝

全局安裝的包能在當(dāng)本機(jī)所有目錄下使用。我們在安裝包的時候傳遞參數(shù)-g--global即可。

npm i -g element-ui

npm i --global element-ui

全局安裝的包路徑我們可以通過npm config get prefix查看。

package.json和package-lock.json怎么使用

npm 安裝流程

前面我們只是介紹了 npm install 是用來安裝依賴的,下面再講一下它到底是怎么安裝的以及一些具體的安裝細(xì)節(jié)。

查找 npm 的配置信息

執(zhí)行安裝命令之后,npm 首先會去查找 npm 的配置信息。 其中,我們最熟悉的就是安裝時候的源信息。npm 會在項(xiàng)目中查找是否有 .npmrc 文件,沒有的話會再檢查全局配置的 .npmrc ,還沒有的話就會使用 npm 內(nèi)置的 .npmrc 文件。

構(gòu)建依賴樹

獲取完配置文件之后,就會構(gòu)建依賴樹。首先會檢查下項(xiàng)目中是否有 package-lock.json ?文件:存在 lock 文件的話,會判斷 lock 文件和 package.json 中使用的依賴版本是否一致,如果一致的話就使用 lock 中的信息,反之就會使用 npm 中的信息;那如果沒有 lock 文件的話,就會直接使用 package.json 中的信息生成依賴樹。

根據(jù)依賴樹下載完整的依賴資源

在有了依賴樹之后,就可以根據(jù)依賴樹下載完整的依賴資源。在下載之前,會先檢查下是否有緩存資源,如果存在緩存資源的話,那么直接將緩存資源解壓到 node_modules 中。如果沒有緩存資源,那么會先將 npm 遠(yuǎn)程倉庫中的包下載至本地,然后會進(jìn)行包的完整性校驗(yàn),校驗(yàn)通過后將其添加的緩存中并解壓到 node_modules 中。

生成 package-lock.json 文件

生成 package-lock.json 文件。 這個文件主要是用來鎖定包的版本,這個筆者后面會詳細(xì)說。

接下來我們說說 package.jsonpackage-lock.json生成方式

package.jsonpackage-lock.json生成方式

首先要明確一點(diǎn),package.json不會自動生成,需要我們使用命令創(chuàng)建。package-lock.json是自動生成的,我們使用 npm install 安裝包后就會自動生成。

下面我們介紹下怎么創(chuàng)建package.json。

npm 為我們提供了創(chuàng)建 package.json 文件的命令 npm init,執(zhí)行該命令會問幾個基本問題,如包名稱、版本號、作者信息、入口文件、倉庫地址、關(guān)鍵字、描述、許可協(xié)議等,多數(shù)問題已經(jīng)提供了默認(rèn)值,你可以在問題后敲回車接受默認(rèn)值。

基本問題問完之后 npm 會在生成文件之前把 package.json 文件內(nèi)容打出來供你確認(rèn),點(diǎn)擊enter鍵就會生成package.json 文件。

package.json和package-lock.json怎么使用

如果覺得這樣一步一步太慢的話我們還可以一鍵生成。使用npm init -y 或者 npm init -f就可以一鍵生成package.json 文件啦。(npm init -ynpm init -fnpm init --yesnpm init --force的簡寫形式)。

package.json和package-lock.json怎么使用

到這里,小伙伴們肯定有疑問了,一鍵生成的package.json里面的內(nèi)容是在哪里控制的呢?比如我想一鍵生成出來的package.json里面的author是我自己需要怎么做呢?

我們來看看npm的初始配置吧,使用npm config ls -l命令查看npm的所有配置。

package.json和package-lock.json怎么使用

可以發(fā)現(xiàn)我們的init-author-name的配置是空,所以我們來設(shè)置下。

# 設(shè)置配置
npm config set init-author-name 'randy'

# 查看配置
npm config get init-author-name

我們再來生成一遍package.json

package.json和package-lock.json怎么使用

可以發(fā)現(xiàn),我們的author就有默認(rèn)值啦,其他的默認(rèn)配置都可以設(shè)置,這里筆者就不再舉例了。

package.json詳解

package.json文件,它是項(xiàng)目的配置文件,常見的配置有配置項(xiàng)目啟動、打包命令,聲明依賴包等。package.json文件是一個JSON對象,該對象的每一個成員就是當(dāng)前項(xiàng)目的一項(xiàng)設(shè)置。

package.json和package-lock.json怎么使用

下面筆者分別介紹各個配置代表的意義。

name

name很容易理解,就是項(xiàng)目的名稱。

version

version字段表示該項(xiàng)目包的版本號,它是一個字符串。在每次項(xiàng)目改動后,即將發(fā)布時,都要同步的去更改項(xiàng)目的版本號。

npm依賴包版本號

npm默認(rèn)所有的Node包都使用語義化版本號,這是一套指導(dǎo)開發(fā)人員如何增長版本號的規(guī)則。

每個版本號都形如:1.2.3,有三部分組成,依次叫主版本號、次版本號修訂號;

  • 主版本號

    當(dāng)新版本無法兼容基于前一版本的代碼時,則提高主版本號;

  • 次版本號

    當(dāng)新版本新增了功能和特性,但仍兼容前一版本的代碼時,則提高次版本號;

  • 修訂號

    當(dāng)新版本僅僅修正了漏洞或者增強(qiáng)了效率,仍然兼容前一版本代碼,則提高修訂號;

  • 最優(yōu)版本

    默認(rèn)情況下,npm install xxx --save下載的都是最新版本,并且會在package.json文件里登記一個最優(yōu)版本號。

舉個例子,我們安裝element-ui

npm i element-ui -S

在安裝的時候它會選擇目前的一個最新的版本進(jìn)行安裝,我們查看github,看到element-ui的最新版本是2.15.9。

package.json和package-lock.json怎么使用

這里我們自動安裝的也就是2.15.9版本,并且版本號并不是固定的而是一個最優(yōu)版本。

package.json和package-lock.json怎么使用

那什么是最優(yōu)版本呢?

最優(yōu)版本會在版本前多了一個^符號,這個符號其實(shí)是有特殊意義的。同理這個符號還有可能是~符號。

那這兩個符號有什么區(qū)別呢?

^ 兼容某個大版本

^意味著下載的包可能會是更高的次版本號或者修訂版本號。(也就是主版本不能變,次版本、修訂版本可以隨意變)。

兼容某個大版本

如:^1.1.2 ,表示>=1.1.2 <2.0.0,可以是1.1.2,1.1.3,.....,1.1.n,1.2.n,.....,1.n.n
~ 兼容某個次版本

~意味著有可能會有更高的修訂版本號。(也就是主版本、次版本不能變,修訂版本可以隨意變)。

兼容某個次版本 

如:~1.1.2,表示>=1.1.2 <1.2.0,可以是1.1.2,1.1.3,1.1.4,.....,1.1.n

看了上面版本號的指定后,我們可以知道,當(dāng)我們使用了 ^ 或者 ~ 來控制依賴包版本號的時候 ,多人開發(fā),就有可能存在大家安裝的依賴包版本不一樣的情況,就會存在項(xiàng)目運(yùn)行的結(jié)果不一樣。

舉個例子

假設(shè)我們中安裝了 vue, 當(dāng)我們運(yùn)行安裝 npm install vue -save 的時候,在項(xiàng)目中的package.jsonvue 版本是 vue: ^3.0.0, 我們電腦安裝的vue版本就是 3.0.0 版本,我們把項(xiàng)目代碼提交后,過了一段時間,vue 發(fā)布了新版本 3.1.0,這時新來一個同事,從新 git clone 克隆項(xiàng)目,執(zhí)行 npm install安裝的時候,在他電腦的vue版本就是 3.1.0了,因?yàn)閊只是鎖了主要版本,這樣我們電腦中的vue版本就會不一樣。從理論上講(大家都遵循語義版本控制的話) ,它們應(yīng)該仍然是兼容的(因?yàn)榇伟姹咎柕男薷闹皇切鹿δ?,并不是不兼容舊版本),這里假設(shè) vue 次版本的迭代會影響我們正在使用的功能,那么這就會導(dǎo)致嚴(yán)重的問題,我們同一個項(xiàng)目會產(chǎn)生不同的運(yùn)行結(jié)果。

這時也許有同學(xué)想到,那么我們在package.json上面鎖死依賴包的版本號不就可以了? 直接寫 vue: 3.0.0鎖死,這樣大家安裝vue的版本都是3.0.0版本了。

這個想法固然是不錯的,但是你只能控制你自己的項(xiàng)目鎖死版本號,那你項(xiàng)目中依賴包的依賴包呢?你怎么控制限制別人鎖死版本號呢?

description

description字段用來描述這個項(xiàng)目包,它是一個字符串,可以讓其他開發(fā)者在 npm 的搜索中發(fā)現(xiàn)我們的項(xiàng)目包。

author

author顧名思義就是作者,表示該項(xiàng)目包的作者。

contributors

contributors表示該項(xiàng)目包的貢獻(xiàn)者,和author不同的是,該字段是一個數(shù)組,包含所有的貢獻(xiàn)者

homepage

homepage就是項(xiàng)目的主頁地址了,它是一個字符串。

repository

repository表示代碼的存放倉庫地址

bugs

bugs表示項(xiàng)目提交問題的地址

依賴類型

前面說到有開發(fā)依賴和生產(chǎn)依賴,其實(shí)npm還有同版本的依賴、捆綁依賴、可選依賴。

  • dependencies 生產(chǎn)依賴

  • devDependencies 開發(fā)依賴

  • peerDependencies 同版本的依賴

  • bundledDependencies 捆綁依賴

  • optionalDependencies 可選依賴

dependencies 生產(chǎn)依賴

dependencies 表示項(xiàng)目依賴,這些依賴都會成為你的線上生產(chǎn)環(huán)境中的代碼組成的部分。當(dāng)它關(guān)聯(lián)到 npm 包被下載的時候,dependencies下的模塊也會作為依賴,一起被下載。

devDependencies 開發(fā)依賴

devDependencies表示開發(fā)依賴, 不會被自動下載的。因?yàn)?devDependencies 一般是用于開發(fā)階段起作用或是只能用于開發(fā)環(huán)境中被用到的。 比如說我們用到的 Webpack,預(yù)處理器 babel-loader、scss-loader,測試工具E2E等, 這些都相當(dāng)于是輔助的工具包, 無需在生產(chǎn)環(huán)境被使用到的。

這里筆者啰嗦一句,當(dāng)我們只開發(fā)應(yīng)用,不對外開源的話,包隨意放在dependenciesdevDependencies是不影響的,因?yàn)楸挥玫降哪K不管你再哪個依賴?yán)锩娑紩淮虬5侨绻_發(fā)的是庫文件,是開源的,已經(jīng)上傳到npm倉庫的,這個你就得嚴(yán)格區(qū)分dependenciesdevDependencies依賴了。因?yàn)楫?dāng)你在安裝第三方包的時候,只會同步下載第三方包dependencies里面的依賴,所以,當(dāng)你第三方包的某依賴寫到devDependencies中,被別人下載后沒下載到該依賴是會報錯運(yùn)行不了的。

peerDependencies 同版本的依賴

peerDependencies 表示同版本的依賴,很多小伙伴肯定難以理解,下面筆者舉個例子就明白了。

vuex我們都使用過,vue的狀態(tài)管理器,它肯定是依賴vue的,但是我們查看它的package.json文件,會發(fā)現(xiàn)dependencies并沒有依賴vue

package.json和package-lock.json怎么使用

??!這是怎么回事呢?其實(shí)他就是用到了peerDependencies 同版本的依賴。

package.json和package-lock.json怎么使用

這下知道什么意思了吧,就是這個包它非常清楚的知道,你使用我的時候必定是在vue環(huán)境下使用,所以你一定會安裝vue,所以我就沒必要再在dependencies下申明vue依賴了,只需要在peerDependencies申明依賴就行了,和主項(xiàng)目共用同一個vue依賴,避免了重復(fù)安裝。

這樣的好處就是node_modules里面不會安裝兩個vue。減少了node_modules體積的同時大大提高了安裝速度。

bundledDependencies 捆綁依賴

bundledDependencies和前面的依賴不同它是一個數(shù)組,里面定義了捆綁依賴。

"name": "test",
"version": "1.0.0",
"bundledDependencies": [ "bundleD1", "bundleD2" ]

當(dāng)我們此時執(zhí)行 npm pack的時候, 就會生成一個 test-1.0.0.tgz的壓縮包, 在該壓縮包中還包含了 bundleD1bundleD2 兩個安裝包。

實(shí)際使用到這個壓縮包的時候,npm install test-1.0.0.tgz 的命令時, bundleD1bundleD2 也會被安裝的。

這樣做的意義是什么呢?

如果bundleD1bundleD2包在npm上有,能下載到固然沒意義。但是當(dāng)bundleD1bundleD2是自己臨時開發(fā)的,并且當(dāng)前項(xiàng)目又依賴這兩個包,并且這兩個包在npm上沒有,下載不到,這下就有意義了。相當(dāng)于跟主包一起捆綁發(fā)布。

這里需要注意的是: 在 bundledDependencies 中指定的依賴包, 必須先在dependencies 和 devDependencies 聲明過, 否則 npm pack 階段是會報錯的。

optionalDependencies 可選依賴

optionalDependencies表示可選依賴,就是說當(dāng)你安裝對應(yīng)的依賴項(xiàng)安裝失敗了, 也不會對整個安裝過程有影響的。一般我們很少會用到它, 這里我是不建議大家去使用, 可能會增加項(xiàng)目的不確定性和復(fù)雜性。 了解即可。

engines

當(dāng)我們維護(hù)一些舊項(xiàng)目時,可能對npm包的版本或者Node版本有特殊要求,如果不滿足條件就可能無法將項(xiàng)目跑起來。為了讓項(xiàng)目開箱即用,可以在engines字段中說明具體的版本號:

"engines": {
  "node": ">=8.10.3 <12.13.0",
  "npm": ">=6.9.0"
}

需要注意,engines只是起一個說明的作用,即使用戶安裝的版本不符合要求,也不影響依賴包的安裝。

scripts

關(guān)于scripts可以看看筆者前面寫的 npm script的那些騷操作,感興趣的小伙伴可以自行查看。

config

config字段用來配置scripts運(yùn)行時的配置參數(shù)。

main

main 字段用來指定加載的入口文件,在 browserNode 環(huán)境中都可以使用。如果我們將項(xiàng)目發(fā)布為npm包,那么當(dāng)使用 require 導(dǎo)入npm包時,返回的就是main字段所列出的文件的module.exports 屬性。如果不指定該字段,默認(rèn)是項(xiàng)目根目錄下的index.js。如果沒找到,就會報錯。

browser

browser字段可以定義 npm 包在 browser 環(huán)境下的入口文件。如果 npm 包只在 web 端使用,并且嚴(yán)禁在 server 端使用,使用 browser 來定義入口文件。

module

module字段可以定義 npm 包的 ESM 規(guī)范的入口文件,browser 環(huán)境和 node 環(huán)境均可使用。如果 npm 包導(dǎo)出的是 ESM 規(guī)范的包,使用 module 來定義入口文件。

需要注意,*.js 文件是使用 commonJS 規(guī)范的語法(require('xxx')),* .mjs 是用 ESM 規(guī)范的語法(import 'xxx')。

上面三個的入口入口文件相關(guān)的配置是有差別的,特別是在不同的使用場景下。在Web環(huán)境中,如果使用loader加載ESM(ES module),那么這三個配置的加載順序是browser→module→main,如果使用require加載CommonJS模塊,則加載的順序?yàn)?code>main→module→browser。

Webpack在進(jìn)行項(xiàng)目構(gòu)建時,有一個target選項(xiàng),默認(rèn)為Web,即構(gòu)建Web應(yīng)用。如果需要編譯一些同構(gòu)項(xiàng)目,如node項(xiàng)目,則只需將webpack.config.jstarget選項(xiàng)設(shè)置為node進(jìn)行構(gòu)建即可。如果在Node環(huán)境中加載CommonJS模塊,或者ESM,則只有main字段有效。

bin

bin字段用來指定各個內(nèi)部命令對應(yīng)的可執(zhí)行文件的位置

"bin": { "someTool": "./bin/someTool.js" },
"scripts": {
  "dev": "someTool build"
}

上面的例子相當(dāng)于定義了一個命令someTool,它對應(yīng)的可執(zhí)行文件的位置是./bin/someTool.js,這樣我們就能在scripts里面直接使用該命令了someTool。

files

files配置是一個數(shù)組,用來描述當(dāng)把npm包作為依賴包安裝時需要說明的文件列表。當(dāng)npm包發(fā)布時,files指定的文件會被推送到npm服務(wù)器中,如果指定的是文件夾,那么該文件夾下面所有的文件都會被提交。

如果有不想提交的文件,可以在項(xiàng)目根目錄中新建一個.npmignore文件,并在其中說明不需要提交的文件,防止垃圾文件推送到npm上。這個文件的形式和.gitignore類似。寫在這個文件中的文件即便被寫在files屬性里也會被排除在外。比如可以在該文件中這樣寫:

node_modules

.vscode

build

.DS_Store

man

man 命令是 Linux 中的幫助指令,通過該指令可以查看 Linux 中的指令幫助、配置文件幫助和編程幫助等信息。如果 node.js 模塊是一個全局的命令行工具,在 package.json 通過 man 屬性可以指定 man 命令查找的文檔地址。

man 字段可以指定一個或多個文件, 當(dāng)執(zhí)行man {包名}時, 會展現(xiàn)給用戶文檔內(nèi)容。

需要注意:

  • man文件必須以數(shù)字結(jié)尾,如果經(jīng)過壓縮,還可以使用.gz后綴。這個數(shù)字表示文件安裝到哪個 man 節(jié)中;

  • 如果 man 文件名稱不是以模塊名稱開頭的,安裝的時候會加上模塊名稱前綴。

對于上面的配置,可以使用以下命令來執(zhí)行查看文檔:

man npm-access
man npm-audit

directories

directories字段用來規(guī)范項(xiàng)目的目錄。node.js 模塊是基于 CommonJS 模塊化規(guī)范實(shí)現(xiàn)的,需要嚴(yán)格遵循 CommonJS 規(guī)范。模塊目錄下除了必須包含包項(xiàng)目描述文件 package.json 以外,還需要包含以下目錄:

  • bin :存放可執(zhí)行二進(jìn)制文件的目錄

  • lib :存放js代碼的目錄

  • doc :存放文檔的目錄

  • test :存放單元測試用例代碼的目錄

  • ...

在實(shí)際的項(xiàng)目目錄中,我們可能沒有按照這個規(guī)范進(jìn)行命名,那么就可以在directories字段指定每個目錄對應(yīng)的文件路徑:

"directories": {
    "bin": "./bin",
    "lib": "./lib",
    "doc": "./doc",
    "test" "./test",
    "man": "./man"
},

這個屬性實(shí)際上沒有什么實(shí)際的作用,當(dāng)然不排除未來會有什么比較有意義的用處。

private

private字段可以防止我們意外地將私有庫發(fā)布到npm服務(wù)器。只需要將該字段設(shè)置為true

preferGlobal

preferGlobal字段表示用戶不把該模塊安裝為全局模塊。如果設(shè)置為true并把該模塊安裝為全局模塊就會顯示警告。

它并不會真正的防止用戶進(jìn)行局部的安裝,只是對用戶進(jìn)行提示,防止產(chǎn)生誤解。

publishConfig

publishConfig配置會在模塊發(fā)布時生效,用于設(shè)置發(fā)布時一些配置項(xiàng)的集合。如果不想模塊被默認(rèn)標(biāo)記為最新,或者不想發(fā)布到公共倉庫,可以在這里配置tag或倉庫地址。

os

os字段可以讓我們設(shè)置該npm包可以在什么操作系統(tǒng)使用,不能再什么操作系統(tǒng)使用。如果我們希望開發(fā)的npm包只運(yùn)行在linux,為了避免出現(xiàn)不必要的異常,建議使用Windows系統(tǒng)的用戶不要安裝它,這時就可以使用os配置:

"os" ["linux"]   // 適用的操作系統(tǒng)
"os" ["!win32"]  // 禁用的操作系統(tǒng)

cpu

該配置和OS配置類似,用CPU可以更準(zhǔn)確的限制用戶的安裝環(huán)境:

"cpu" ["x64", "AMD64"]   // 適用的cpu
"cpu" ["!arm", "!mips"]  // 禁用的cpu

可以看到,黑名單和白名單的區(qū)別就是,黑名單在前面加了一個!

license

license 字段用于指定軟件的開源協(xié)議,開源協(xié)議表述了其他人獲得代碼后擁有的權(quán)利,可以對代碼進(jìn)行何種操作,何種操作又是被禁止的。常見的協(xié)議如下:

  • MIT :只要用戶在項(xiàng)目副本中包含了版權(quán)聲明和許可聲明,他們就可以拿你的代碼做任何想做的事情,你也無需承擔(dān)任何責(zé)任。

  • Apache :類似于 MIT ,同時還包含了貢獻(xiàn)者向用戶提供專利授權(quán)相關(guān)的條款。

  • GPL :修改項(xiàng)目代碼的用戶再次分發(fā)源碼或二進(jìn)制代碼時,必須公布他的相關(guān)修改。

typings或者types

typings或者types字段用來指定TypeScript的入口文件

eslintConfig

eslint的配置可以寫在單獨(dú)的配置文件.eslintrc.json 中,也可以寫在package.json文件的eslintConfig配置項(xiàng)中。

babel

babel的配置可以寫在單獨(dú)的配置文件babel.config.json 中,也可以寫在package.json文件的babel配置項(xiàng)中。

unpkg

使用該字段可以讓 npm 上所有的文件都開啟 cdn 服務(wù),該CND服務(wù)由unpkg提供。

lint-staged

lint-staged是一個在Git暫存文件上運(yùn)行linters的工具,配置后每次修改一個文件即可給所有文件執(zhí)行一次lint檢查,通常配合gitHooks一起使用。

使用lint-staged時,每次提交代碼只會檢查當(dāng)前改動的文件。

gitHooks

gitHooks用來定義一個鉤子,在提交(commit)之前執(zhí)行ESlint檢查。在執(zhí)行lint命令后,會自動修復(fù)暫存區(qū)的文件。修復(fù)之后的文件并不會存儲在暫存區(qū),所以需要用git add命令將修復(fù)后的文件重新加入暫存區(qū)。在執(zhí)行pre-commit命令之后,如果沒有錯誤,就會執(zhí)行git commit命令

"gitHooks": {
  "pre-commit": "lint-staged"
}

這里就是配合lint-staged來進(jìn)行代碼的檢查操作。每次commit前運(yùn)行lint-staged。

browserslist

browserslist字段用來告知支持哪些瀏覽器及版本。Babel、postcss、eslint等工具都會用到它。

當(dāng)然你也可以單獨(dú)建立.browserslistrc文件來配置。如需了解更多可以查看browserslist 官方文檔。

package-lock.json 詳解

前面說了package.json里面的包版本不是一個具體的版本,而是一個最優(yōu)版本。而package-lock.json里面定義的是某個包的具體版本,以及包之間的層疊關(guān)系。

一個 package-lock.json 里面的每個依賴主要是有以下的幾部分組成的:

  • Version: 依賴包的版本號

  • Resolved: 依賴包的安裝源(其實(shí)就是可以理解為下載地址)

  • Intergrity: 表明完整性的 Hash 值

  • Dev: 表示該模塊是否為頂級模塊的開發(fā)依賴或者是一個的傳遞依賴關(guān)系

  • requires: 依賴包所需要的所有依賴項(xiàng),對應(yīng)依賴包 package.jsondependencices 中的依賴項(xiàng)

  • dependencices: 依賴包 node_modeles 中依賴的包(特殊情況下才存在)。并不是所有的子依賴都有 dependencies 屬性,只有子依賴的依賴和當(dāng)前已安裝在根目錄的 node_modules 中的依賴沖突之后, 才會有這個屬性。 這可能涉及嵌套情況的依賴管理。

假設(shè)我們的項(xiàng)目依賴A、B、C三個包,并且B包又依賴特定版本C包,所以B包就會有dependencices,那么我們項(xiàng)目的整個node_modules的目錄結(jié)構(gòu)如下

node_modules
  A.package
  B.package
    node_modules
      C.package
  C.package

那什么情況下package.json和package-lock.json里面的版本號一致呢?

當(dāng)package.json里面不再使用最優(yōu)版本,而是一個特定有效版本,也就是版本號前不帶修飾符,這樣package.jsonpackage-lock.json里面的版本號才是一致的。

或者我們npm install xxx@1.1.2 帶上版本號,安裝特定版本的包package.jsonpackage-lock.json里面的版本號也是一致的。

或者我們package.json里面定義的包版本就是最新的,我們安裝的時候package.jsonpackage-lock.json里面的版本號也會是一致的。

package-lock.json什么時候會變

  • package-lock.jsonnpm install的時候會自動生成。

  • 當(dāng)我們修改依賴位置,比如將部分包的位置從 dependencies 移動到 devDependencies 這種操作,雖然包未變,但是也會影響 package-lock.json,會將部分包的 dev 字段設(shè)置為 true。

  • 還有如果我們安裝源 registry 不同,執(zhí)行 npm install 時也會修改 package-lock.json。

因?yàn)樗菚涗浳覀兊囊蕾嚢刂返摹?/p>

package.json和package-lock.json怎么使用

  • 當(dāng)我們使用npm install添加或npm uninstall移除包的時候,同時也會修改 package-lock.json。

  • 當(dāng)我們更新某個包的版本的時候,同時也會修改 package-lock.json。

怎么安裝指定版本的包

我們知道,使用npm install xxx會安裝某最新版本的包。

如果在根目錄下直接運(yùn)行npm install,那么npm會根據(jù)package.json下載所有的最新版本的包。

那么怎么安裝指定版本的包呢?

我們只需要安裝的時候帶上版本號就可以啦。比如筆者上面element-ui默認(rèn)安裝的最新版本是2.15.9。我們來安裝一個2.15.7的特定版本。

npm install element-ui@2.15.7

我們最新版本的2.15.9的版本包就會被替換。并且它會同步修改我們的package.jsonpackage-lock.json。

package.json和package-lock.json怎么使用

package.json和package-lock.json怎么使用

我們知道,安裝完生成package-lock.json之后包的版本就會被固定下來,后續(xù)不管你怎么npm install都不會再變化。

如果我想更新到最新版本的包該怎么辦呢?

怎么更新包的版本

更新包的版本有很多種方式。

npm install指定版本

我們知道最新包的版本,直接按上面的安裝指定包并帶上版本號即可。原理和安裝特定版本的包一致。

npm install element-ui@2.15.9

它會同步修改我們的package.jsonpackage-lock.json。

npm update

不知道最新包的版本,我們運(yùn)行npm update xxx 即可。

npm update element-ui

它會將指定包更新成最新版本,并且同步修改我們的package.jsonpackage-lock.json。

如果想更新項(xiàng)目下所有的包,直接運(yùn)行 npm update 即可。

請注意,更新包它是會遵循我們的最優(yōu)版本號控制的。也就是說當(dāng)我們的版本是被^修飾時,再怎么更新它只會更新次版本和修訂版本,并不會更新主版本。

比如筆者安裝的element-ui包的版本是1.0.0

package.json和package-lock.json怎么使用

package.json里面版本號如下

package.json和package-lock.json怎么使用

當(dāng)我們npm update element-ui更新包時,它只會更新成最新的次版本和修訂版本,并不會更新主版本。

package.json和package-lock.json怎么使用

package.json里面版本號如下

package.json和package-lock.json怎么使用

刪除 package-lock.json

如果想更新項(xiàng)目下所有的包我們還可以將package-lock.json刪除,然后運(yùn)行npm install,它也會安裝所有的最新版本的包,并且會重新生成package-lock.json。

package-lock.json 需要提交到倉庫嗎

至于我們要不要提交 lockfiles 到倉庫中?這個就需要看我們具體的項(xiàng)目的定位了。

  • 如果是開發(fā)一個應(yīng)用, 我的理解是 package-lock.json文件提交到代碼版本倉庫.這樣可以保證項(xiàng)目中成員、運(yùn)維部署成員或者是 CI 系統(tǒng), 在執(zhí)行 npm install后, 保證在不同的節(jié)點(diǎn)能得到完全一致的依賴安裝的內(nèi)容,減少bug的出現(xiàn)。

  • 如果你的目標(biāo)是開發(fā)一個給外部環(huán)境用的庫,那么就需要認(rèn)真考慮一下了, 因?yàn)?strong>庫文件一般都是被其他項(xiàng)目依賴的,在不使用 package-lock.json的情況下,就可以復(fù)用主項(xiàng)目已經(jīng)加載過的包,減少依賴重復(fù)和體積

  • 如果說我們開發(fā)的庫依賴了一個精確版本號的模塊,那么在我們?nèi)ヌ峤?lockfiles 到倉庫中可能就會出現(xiàn), 同一個依賴被不同版本都被下載的情況,這樣加大了node_modules的體積。如果我們作為一個庫的開發(fā)者, 其實(shí)如果真的使用到某個特定的版本依賴的需求, 那么定義peerDependencies 是一個更好的選擇。

所以, 我個人比較推薦的一個做法是:把 package-lock.json一起提交到倉庫中去, 不需要 ignore。但是在執(zhí)行 npm publish 命令的時候,也就是發(fā)布一個庫的時候, 它其實(shí)應(yīng)該是被忽略的不應(yīng)該被發(fā)布出去的。

可以不使用package-lock.json嗎

在項(xiàng)目中如果沒有鎖版本的必要,可以不使用package-lock.json,在安裝模塊時指定--no-lock即可。

依賴包版本精準(zhǔn)控制

我們都知道package-lock.json主要是用來鎖定包版本的。

其實(shí)在npm的發(fā)展歷史中,控制包的版本有package-lock.jsonnpm-shrinkwrap.json兩種方式

npm-shrinkwrap.json

npm5之前(不包括5),主要是用npm-shrinkwrap.json來精準(zhǔn)控制安裝指定版本的npm包。

那怎么生成npm-shrinkwrap.json呢?其實(shí)一條命令npm shrinkwrap就能搞定。

它會生成一個npm-shrinkwrap.json文件,記錄目前所有依賴包(及更底層依賴包)的版本信息。這樣當(dāng)以后其他人運(yùn)行npm install命令時,npm首先會找到npm-shrinkwrap.json文件,依照其中的信息準(zhǔn)確的安裝每一個依賴包,只有當(dāng)這個文件不存在時,npm才會使用package.json。

因?yàn)檫@是npm5之前的方案,所以現(xiàn)在基本上看不到了。現(xiàn)在都是package-lock.json方案。

package-lock.json

相較npm-shrinkwrap.jsonpackage-lock.json的優(yōu)點(diǎn)是能自動生成。

官方文檔是這樣解釋的:package-lock.json 它會在 npm 更改 node_modules 目錄樹或者 package.json 時自動生成的 ,它準(zhǔn)確的描述了當(dāng)前項(xiàng)目npm包的依賴樹,并且在隨后的安裝中會根據(jù) package-lock.json 來安裝,保證是相同的一個依賴樹,不考慮這個過程中是否有某個依賴有小版本的更新。

當(dāng)我們在一個項(xiàng)目中npm install時候,會自動生成一個package-lock.json文件,和package.json在同一級目錄下。package-lock.json記錄了項(xiàng)目的一些信息和所依賴的模塊。這樣在每次安裝都會出現(xiàn)相同的結(jié)果,不管你在什么機(jī)器上面或什么時候安裝。

可以看到package-lock.json里面包的版本不再是最優(yōu)版本啦,而是一個固定版本,這也是它為什么鎖定版本的原因。

package.json和package-lock.json怎么使用

并且我們依賴的依賴它也會安裝一個特定的版本,并鎖定起來。比如element-ui所依賴的throttle-debounce

package.json和package-lock.json怎么使用

所以當(dāng)我們下次再npm install時候,npm 發(fā)現(xiàn)如果項(xiàng)目中有 package-lock.json 文件,則會根據(jù) package-lock.json 里的內(nèi)容來處理和安裝依賴而不再根據(jù) package.json。

可見package-lock.json原理就是將項(xiàng)目中用到的所有依賴都指定一個固定的版本,后續(xù)安裝直接讀取該文件來安裝依賴。

在這里需要注意,如果用的是cnpm是不會自動生成package-lock.json文件的。我們平時開發(fā)最好的實(shí)踐就是使用npm然后將鏡像設(shè)置為淘寶源就可以了。

// 設(shè)置淘寶鏡像
npm config set registry https://registry.npm.taobao.org

// 查看鏡像源
npm config get registry

或許是package-lock.json最佳的實(shí)操建議

當(dāng)我們的項(xiàng)目第一次去搭建的時候, 使用 npm install 安裝依賴包, 并去提交 package.json、package-lock.json, 至于node_moduled目錄是不用提交的。

當(dāng)我們作為項(xiàng)目的新成員的時候, checkout/clone項(xiàng)目的時候, 執(zhí)行一次 npm install 去安裝依賴包,它會根據(jù)package-lock.json下載對應(yīng)固定版本的包。

當(dāng)我們出現(xiàn)了需要升級依賴的需求的時候:

  • 升級小版本的時候, 依靠 npm update

  • 升級大版本的時候, 依靠 npm install xxx

  • 當(dāng)然我們也有一種方法, 直接去修改 package.json 中的版本號, 并去執(zhí)行 npm install 去升級版本

  • 當(dāng)我們本地升級新版本后確認(rèn)沒有問題之后, 去提交新的 package.jsonpackage-lock.json文件。

當(dāng)我們出現(xiàn)了需要降級依賴的需求的時候:

  • 我們?nèi)?zhí)行npm install @x.x.x 命令后,驗(yàn)證沒有問題之后, 是需要提交新的 package.jsonpackage-lock.json 文件。

當(dāng)我們出現(xiàn)了需要刪除依賴的需求的時候:

  • 當(dāng)我們執(zhí)行 npm uninstall 命令后,需要去驗(yàn)證,提交新的 package.jsonpackage-lock.json 文件。

  • 或者是更加暴力一點(diǎn), 直接操作 package.json, 刪除對應(yīng)的依賴, 執(zhí)行 npm install 命令, 需要去驗(yàn)證,提交新的package.jsonpackage-lock.json 文件。

當(dāng)你把更新后的package.jsonpackage-lock.json提交到代碼倉庫的時候, 需要通知你的團(tuán)隊(duì)成員, 保證其他的團(tuán)隊(duì)成員拉取代碼之后,更新依賴可以有一個更友好的開發(fā)環(huán)境保障持續(xù)性的開發(fā)工作。

如果你的 package-lock.json 出現(xiàn)沖突或問題, 我的建議是將本地的 package-lock.json文件刪掉, 然后去找遠(yuǎn)端沒有沖突的 package.jsonpackage-lock.json, 再去執(zhí)行 npm install 命令。

undefined

讀到這里,這篇“package.json和package-lock.json怎么使用”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點(diǎn)還需要大家自己動手實(shí)踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI