npm
中依賴版本號是 ^x.y.z
,能夠包含哪些版本呢?前端
今天有同事遇到一個問題,咱們代碼裏依賴的某個npm
包,寫的是版本是 hard-source-webpack-plugin@^0.12.0
,可是在執行 npm install
的時候,安裝的始終是 0.12.0
這個版本,而不是這個包的最新版 0.13.1
。node
剛開始,我還覺得是由於有 lock
的緣由,好比有 package-lock.json
或者 yarn.lock
,我認識是某個lock文件裏,鎖定了版本爲 0.12.0
。但實際狀況是,因爲以前同事的代碼有點bug,雖然源碼中的確是有package-lock.json
和 yarn.lock
文件的,可是實際發版的時候,因爲代碼的bug,並無將這兩個文件發佈到npm
倉庫裏。webpack
目前的狀況就是,package.json
裏寫的版本是 ^0.12.0
,這個包在 npm
源的最新版是 0.13.1
。可是經過npm安裝出來,始終是0.12.0的,並非0.13.1。web
根據以前的理解,語義的版本是 ^0.12.0
,那麼是能夠覆蓋到 [major, minor, patch] 三位版本中的 後兩位 的,按理說應該會自動安裝 0.13.1 這個版本啊。shell
難道是緩存的鍋?嗯,有可能,npm的確是在本地有緩存的啊。因而清除掉本地的緩存 npm cache clean —force
,再從新安裝,WFT?仍是 0.12.0 啊!!npm
看來不是緩存的鍋。那是網絡問題麼?也不是,清除掉緩存都仍是能安裝到 0.12.0 ,網絡確定是OK的……json
貌似,客觀緣由 都排查得差很少了……只能從 主觀方面 找問題了。緩存
版本號 ^0.12.0
,真的包含了 0.13.1
麼??網絡
再翻出 npm版本官方文檔 看看,嗯,以前的確理解錯了。文檔裏明確說了,^
指明的版本範圍,只要不修改 [major, minor, patch] 三元組中,最左側的第一個非0位,都是能夠的。也就是說,要肯定 ^
版本包含的範圍,先要找到 最左側的第一個非0位 ,只有在這一位右側的變更,才被包含在這個 ^
指定的範圍內。舉個🌰:工具
^1.2.3
版本包括:>= 1.2.3
而且 < 2.0.0
^0.2.3
版本包括:>= 0.2.3
而且 < 0.3.0
^0.0.3
版本包括:>= 0.0.3
而且 < 0.0.4
同時,在官網還找到一個 npm
命令行工具:semver
,能夠安裝到全局:npm i -g semver
,以後,能夠用這個工具來檢查某個範圍版本具體包含哪些,拿今天遇到的問題,就能夠這樣:
bogon:~ jess$ semver -r ^0.12.0 0.12.0 0.13.0 0.13.1
0.12.0
bogon:~ jess$
bogon:~ jess$ semver -r ^0.12.0 0.12.0 0.12.1 0.12.10 0.13.0 0.13.1
0.12.0
0.12.1
0.12.10
bogon:~ jess$
bogon:~ jess$
複製代碼
PS :
咱們目前在應用的代碼裏,爲了防止某些包在升級過程當中,沒有遵循語義化版本,致使咱們應用在每次打包後,生成的代碼可能不一樣,通常都會用 yarn.lock
或者 package-lock.json
來鎖定項目依賴的包的版本號。
可是上次有同窗在開源的 第三方包 裏,發現大多數都沒有 yarn.lock
或者 package-lock.json
,感到有點奇怪,爲何這些開源的包,不鎖定依賴的第三方版本呢?
個人理解,大概是這兩個方面:
nodejs
的 node_modules
是個比黑洞還深的坑,可見一般在咱們一個應用裏,會依賴多少的第三方開源包。每個開源包,又會依賴不少別的包。若是每一個開源包都鎖定本身的依賴版本,那麼不少底層的基礎包,可能會被安裝不少個,雖然只是 patch
部分存在版本差別,那前端代碼打包以後,體積無疑會增大不少。所以,開源包爲了和其餘的開源包 共享 更底層的包,就不能鎖定本身的版本