1. package.json 與 package-lock.json 的關(guān)系

        共 7190字,需瀏覽 15分鐘

         ·

        2022-08-02 05:26

        點擊上方 前端Q,關(guān)注公眾號

        回復加群,加入前端Q技術(shù)交流群

        模塊化開發(fā)在前端越來越流行,使用 node 和 npm 可以很方便的下載管理項目所需的依賴模塊。package.json 用來描述項目及項目所依賴的模塊信息。

        package-lock.jsonpackage.json 有啥關(guān)系和聯(lián)系呢?

        package.json

        管理包

        大家都知道,**package.json 用來描述項目及項目所依賴的模塊信息。**,就是幫我們管理項目中的依賴包的,讓我們遠離了依賴地獄。

        通過 npm 管理,使用一些簡單的命令,自動生成package.json, 安裝包依賴關(guān)系都由package.json來管理,我們幾乎不必考慮它們。

        語義版本控制

        首先我們先來了解下依賴包的版本號的定義

        版本號由三部分組成:major.minor.patch,主版本號.次版本號.修補版本號。

        例如:1.2.3,主要版本1,次要版本2,補丁3。

        • 補丁中的更改表示不會破壞任何內(nèi)容的錯誤修復。
        • 次要版本的更改表示不會破壞任何內(nèi)容的新功能。
        • 主要版本的更改代表了一個破壞兼容性的大變化。如果用戶不適應主要版本更改,則內(nèi)容將無法正常工作。

        安裝依賴包的版本如何指定

        相信大家都會經(jīng)歷過,我們安裝一些依賴包的時候,版本號前面都會帶 ^ 或者 ~ 的符號,這兩個符號代表什么意思呢?

        ~ 會匹配最近的小版本依賴包,比如 ~1.2.3 會匹配所有 1.2.x 版本,但是不包括 1.3.0

        ^ 會匹配最新的大版本依賴包,比如 ^1.2.3 會匹配所有 1.x.x 的包,包括 1.3.0,但是不包括 2.0.0

        * 安裝最新版本的依賴包,比如 *1.2.3 會匹配 x.x.x,

        那么該如何選擇呢?當然你可以指定特定的版本號,直接寫1.2.3,前面什么前綴都沒有,這樣固然沒問題,但是如果依賴包發(fā)布新版本修復了一些小bug,那么需要手動修改package.json文件;~^ 則可以解決這個問題。

        但是需要注意 ^ 版本更新可能比較大,會造成項目代碼錯誤,所以 建議使用 ~ 來標記版本號,這樣可以保證項目不會出現(xiàn)大的問題,也能保證包中的小bug可以得到修復。

        版本號寫 *,這意味著安裝最新版本的依賴包,但缺點同上,可能會造成版本不兼容,慎用!

        多人開發(fā)時依賴包安裝的問題

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

        我們舉個例子:

        假設(shè)我們中安裝了 vue, 當我們運行安裝 npm install vue -save 的時候,在項目中的package.json 的 vue 版本是  vue: ^3.0.0, 我們電腦安裝的vue版本就是 3.0.0 版本,我們把項目代碼提交后,過了一段時間,vue 發(fā)布了新版本 3.0.1,這時新來一個同事,從新 git clone 克隆項目,執(zhí)行 npm install安裝的時候,在他電腦的vue版本就是 3.0.1了,因為^只是鎖了主要版本,這樣我們電腦中的vue版本就會不一樣,從理論上講(大家都遵循語義版本控制的話),它們應該仍然是兼容的,但也許 bugfix 會影響我們正在使用的功能,而且當使用vue版本3.0.0和3.0.1運行時,我們的應用程序會產(chǎn)生不同的結(jié)果。

        大家思考思考,這樣的話,不同人電腦安裝的依賴版項目,是不是都有可能不一樣,就會導致每個人電腦運行的應用程序產(chǎn)生不同的結(jié)果。就會存在bug的隱患。

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

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

        為了解決這個不同人電腦安裝的所有依賴版本都是一致的,確保項目代碼在安裝所執(zhí)行的運行結(jié)果都一樣,這時 package-lock.json 就應運而生了。

        package-lock.json

        package-lock.json 是在 npm(^5.x.x.x)后才有,中途有幾次更改

        介紹

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

        它的產(chǎn)生就是來對整個依賴樹進行版本固定的(鎖死)。

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

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

        注意,使用cnpm install時候,并不會生成 package-lock.json 文件,也不會根據(jù) package-lock.json 來安裝依賴包,還是會使用 package.json 來安裝。

        package-lock.json 生成邏輯

        簡單描述一下 package-lock.json 生成的邏輯。假設(shè)我們現(xiàn)在有三個 package,在項目 lock-test中,安裝依賴A,A項目面有B,B項目面有C

        // package lock-test
        "name""lock-test""dependencies": { "A""^1.0.0" }}
        // package A
        "name""A""version""1.0.0""dependencies": { "B""^1.0.0" }}
        // package B
        "name""B""version""1.0.0""dependencies": { "C""^1.0.0" }}
        // package C
        "name""C""version""1.0.0" }
        復制代碼

        在這種情況下 package-lock.json, 會生成類似下面鋪平的結(jié)構(gòu)

        // package-lock.json

            "name""lock-test",  
            "version""1.0.0",  
            "dependencies": {    
                "A": { "version""1.0.0" },
                "B": { "version""1.0.0" },
                "C": { "version""1.0.0" }  
            }
        }
        復制代碼

        如果后續(xù)無論是直接依賴的 A 發(fā)版,或者間接依賴的B, C 發(fā)版,只要我們不動 package.json, package-lock.json 都不會重新生成。

        A 發(fā)布了新版本 1.1.0,雖然我們 package.json 寫的是 ^1.0.0 但是因為 package-lock.json 的存在,npm i 并不會自動升級,

        我們可以手動運行 npm i [email protected] 來實現(xiàn)升級。

        因為 1.1.0 package-lock.json 里記錄的 [email protected] 是不一致的,因此會更新 package-lock.json 里的 A 的版本為 1.1.0。

        B 發(fā)布了新版本 1.0.1, 1.0.2, 1.1.0, 此刻如果我們不做操作是不會自動升級 B 的版本的,但如果此刻 A 發(fā)布了 1.1.1,雖然并沒有升級 B 的依賴,但是如果我們項目里升級 [email protected],此時 package-lock.json 里會把 B 直接升到 1.1.0 ,因為此刻^1.0.0的最新版本就是 1.1.0。

        經(jīng)過這些操作后 項目 lock-test 的 package.json 變成

        // package 
        lock-test{ "dependencies": { "A""^1.1.0" }}
        復制代碼

        對應的 package-lock.json 文件

        {  
            "name""lock-test",  
            "version""1.0.0",
            "dependencies": {  
                "A": { "version""1.1.0" },
                "B": { "version""1.1.0" },
                "C": { "version""1.0.0" }
            }
        }
        復制代碼

        這個時候我們將 B 加入我們 lock-test 項目的依賴, B@^1.0.0,package.json如下

        "dependencies": { "A""^1.1.0""B""^1.0.0" }}
        復制代碼

        我們執(zhí)行這個操作后,package-lock.json 并沒有被改變,因為現(xiàn)在 package-lock.json[email protected] 滿足 ^1.0.0 的要求

        但是如果我們將 B 的版本固定到 2.x 版本, package-lock.json 就會發(fā)生改變

        "dependencies": { "A""^1.1.0""B""^2.0.0" }}
        復制代碼

        因為存在了兩個沖突的B版本,package-lock.json 文件會變成如下形式

        {  
            "name""lock-test",
            "version""1.0.0",  
            "dependencies": {    
                "A": {      
                    "version""1.1.0",      
                    "dependencies": {        
                        "B": { "version""1.1.0" }      
                    }    
                },    
                "B": { "version""2.0.0" },    
                "C": { "version""1.0.0" }  
            }
        }
        復制代碼

        因為 B 的版本出現(xiàn)了沖突,npm 使用嵌套描述了這種行為

        我們實際開發(fā)中并不需要關(guān)注這種生成的算法邏輯,我們只需要了解,package-lock.json 的生成邏輯是為了能夠精準的反映出我們 node_modules 的結(jié)構(gòu),并保證能夠這種結(jié)構(gòu)被還原。

        package-lock.json 可能被意外更改的原因

        1. package.json 文件修改了
        2. 挪動了包的位置

        將部分包的位置從 dependencies 移動到 devDependencies 這種操作,雖然包未變,但是也會影響 package-lock.json,會將部分包的 dev 字段設(shè)置為 true

        1. registry 的影響

        經(jīng)過實際使用發(fā)現(xiàn),如果我們 node_modules 文件夾下的包中下載時,就算版本一樣,安裝源 registry 不同,執(zhí)行 npm i 時也會修改 package-lock.json

        可能還存在其他的原因,但是 package-lock.json 是不會無緣無故被更改的,一定是因為 package.json 或者 node_modules 被更改了,因為 正如上面提到的 package-lock.json 為了能夠精準的反映出我們 node_modules 的結(jié)構(gòu)

        開發(fā)的建議

        一般情況下 npm install 是可以的,他能保證根據(jù) package-lock.json 還原出開發(fā)時的 node_modules。

        但是為了防止出現(xiàn)剛剛提到的意外情況,除非涉及到對包的調(diào)整,其他情況下建議使用 npm ci 來安裝依賴,會避免異常的修改 package-lock.json

        持續(xù)集成工具中更推薦是用 npm ci,保證構(gòu)建環(huán)境的準確性,npm i 和 npm ci 的區(qū)別 可以參考官方文檔 npm-ci

        參考文章:

        我的package-lock.json被誰改了?

        npm install 生成的package-lock.json是什么文件?有什么用?

        作者:阿離王 

        鏈接:https://juejin.cn/post/7078233610683170824


        往期推薦


        元宇宙嘗鮮之探味奇遇記
        使用 Vite 和 TypeScript 從零打造一個屬于自己的 Vue3 組件庫
        22個Vue 源碼中的工具函數(shù)

        最后


        • 歡迎加我微信,拉你進技術(shù)群,長期交流學習...

        • 歡迎關(guān)注「前端Q」,認真學前端,做個專業(yè)的技術(shù)人...

        點個在看支持我吧
        瀏覽 30
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 国产农村妇女三级全黄第06集在线观看 | 日韩五码在线观看 | 老司机福利院 | 人妻天天爽 | 国产精品 女同 |