npm包的更新說明,你還敢不看嗎
前言
平時工作少不了依賴一些第三方的npm包,站在各位大牛的肩膀上來更好的寫bug,此外還可以學習各位大佬們的各種設計思路和優雅實現。不過npm包雖好,但使用之前也要多加甄別,特別是相同包的不同版本之間的差別,可能一不小心,原本用的飛起的輪子就會讓我們笑不出來。下面用兩次慘痛的線上問題來給大家提個醒。
版本依賴符號
在描述問題之前,先談一下npm的包管理控制。
假設我們依賴一個npm包 a 常見的依賴符號有下面這么幾種
{
"dependencies": {
"a":"5.6.1",
"a":">=5.6.1",
"a":">5.6.1",
"a":"<=5.6.1",
"a":"<5.6.1",
"a":"~5.6.1",
"a":"^5.6.1"
}
}
我們安裝的npm包依賴有大概下面這么幾種:
- version 匹配具體版本 例如:a:5.6.1
-
|>=|<|<= version 大於或者小於5.6.1
- ~version 大致相當於當前版本 即 5.6.X 均可以 5.7.1不可以
- ^version 兼容版本 兼容的是中間的版本,例如5.7.X不包括 6.X.X
詳細區別請查看
根據上面的安裝標識,npm會默認去拉去符合規定的最新版本。
當我們執行npm i 時 默認的版本依賴關系是"a":"^5.6.1"
npm i a -s //默認安裝的依賴符號是 "a":"^5.6.1"
上面是npm的版本控制規范,有規范也要我們去遵循才可以生效。
開發者版本控制
我們發布npm包的時候,版本標識是package.json中的version
"version": "0.0.1"
一般來說對於測試版本,都是0.X.X的版本(當然也可以有例外,例如react,最高到0.14.X,突然來了個15.X.X)
成熟版本會從1.X.X開始。
如果有bug或者功能更新的時候,可不能隨便更新,要根據對使用者的影響程度來進行版本更新。
版本更新策略
從我們團隊來說版本更新策略如下:
- bugfix 原有功能和api無變動
最后一位小版本更新 - 功能更新,新增api等,但是老版本依舊可以使用
中間一位版本更新 - 不兼容更新,老版本無法使用
最前面的大版本升級
更復雜一點的可以通過tag來控制不同包具體可以參考https://cnodejs.org/topic/537b47d1cbcc39634983b739來了解
使用者
結合前面提到的,npm 默認的兼容版本安裝,成熟npm包來說,更新策略一般都是考慮使用者的。
會進行比較嚴謹的版本控制,但是我們新項目使用的時候,如果覺得老的包有用,直接npm i 之前可要思量一下,是否進行了打的版本升級。
問題示例
一、query-string 6.x版本不支持低版本
問題描述
上線一個月左右的一個項目,突然接到反饋,某個頁面正常渲染之后,無法選中某個某個模塊。
問題定位
- 問題復現
接到反饋之后,立即拿起手邊的手機進行復現,心里還說這么明顯的問題竟然發生了,趕緊分分鍾干掉。
結果發現手邊的手機都無法復現這種情況
- app版本
這時候懷疑是不是app版本問題,試着讓用戶升級下app。
結果發現依舊存在相同問題
- 確認問題機型
這時候詢問發現機型為oppo,沒有仔細去看具體型號。
趕緊拿了個oppo r17測試機,發現依然不存在相關問題。
- 是否網絡問題
因為使用的是公司內網,切換到手機4g,依然無法復現。
- 操作系統版本
這時候懷疑是舊版本不兼容最新語法,不過我們的js都是經過處理的,應該不會存在,不過還是確認了下用戶操作系統,安卓4.6
- 復現
因為身邊手機版本都較高,無法復現,不復現就很難定位。這時候想起來我司有個雲真機平台,終於找到了個低版本的oppo,app運行都有點卡的那種。。。上面終於復現了。趕緊去調試,發現點擊的時候報錯:
Uncaught SyntaxError: Use of const in strict mode.
這下確認是es6沒有被轉義的問題了
問題解決
不過這里還有點疑問,我們項目本身將src下的源碼進行了處理的。如果說沒有成功,那么多用到const的地方,應該一開始就報錯。這下就讓我我有點頭疼了。
仔細想了想,可能是第三方npm包沒有經過轉義處理,不過引了那么多的包,確定還是太難了。webpack打包之后的代碼生產環境下是壓縮的,簡直不能看。
本地打包
還好webpck4提供了不同的mode方式,可以直接使用 --mode development指定打包,這樣是沒有壓縮過的。
對比發現,const出現在query-string相關邏輯中,直接本地打開查看,發現就是其6.X的版本有要求。
🔥 Want to strengthen your core JavaScript skills and master ES6?
I would personally recommend this awesome ES6 course by Wes Bos.
Also check out his Node.js, React, Sublime courses.
可以從其tag中看到,原本使用的5.x是基於es5的,18年五月份升級了6.x,拋棄了支持es5,要求限制環境。
問題原因
原本使用過該模塊用來解析和序列化請求參數,所以新項目就直接安裝了該依賴。
安裝的時候,如果沒有指定版本,npm會默認獲取最新版本,所以安裝了6.x的版本。
這時候我們沒有去查看是否已經有大版本的更新。
但目前大部分新型手機已經支持es6,所以在開發測試和上線的過程中,不會出現該問題。
只有在部分低版本的手機,才會發現。
二、antd upload組件不顯示已上傳圖片
問題描述
同事做的一個項目用到了antd的upload組件,發現測試環境可以顯示后端返回的圖片,但是線上不可以,因為同事休假,本着團結互助,積極接鍋的精神,就拿過來改了。
本地復現
首先拉代碼到本地,然后本地測試,依然還是沒有問題的。
這樣情況,還是對比下環境依賴。因為這里比較明顯是upload的問題,所以我們只關注antd就好。
對比測試環境和線上可以看到確實版本有差別:
beta和本地是3.1.4 線上是3.5.4
在本地限定版本之后可以發現問題修復。
問題原因
- 代碼跟進去可以看到:
3.5.4版本做了個限制:
//圖片后綴名必須為以下其一
(webp|svg|png|gif|jpg|jpeg|bmp)$/.test(extension)
因為我們返回的縮略圖地址沒有后綴,所以不會顯示。
-
我們項目里面的版本依賴的寫法是兼容版本寫法:
"antd": "^3.1.4"
因為3.5.4和3.1.4都是符合要求的。
-
antd的版本升級策略是說的過去的畢竟不是大改動,正常情況下圖片無外乎其中之一,這么小的概略就被我們碰上了。
結束語
吃一塹長一智,所以在使用npm包的時候一定要結合實際情況認真篩選是否適用,對於部分已經使用過的npm包,新項目使用的時候一定要注意是否有大版本變動。
對於問題,首先還是要復現問題,為了更好的復現,最好保證各種版本都一致才能更好的定位。
定位之后就比較好解決了。