PS: 自從有了
yarn, npm的 shrinkwrap 就被拋棄了,推薦大家使用yarn !
對(duì)于web developer來說,代碼依賴管理一直都是個(gè)頭疼的問題。自前端代碼模塊化開發(fā)以來,前端依賴管理也從原始的手動(dòng)加載維護(hù)演化為基于模塊倉庫和工具的自動(dòng)管理。目前相對(duì)比較流行的包管理工具是bower和npm。
bower && npm
bower的完全面向web的包管理工具。本身并不存儲(chǔ)模塊代碼,對(duì)包結(jié)構(gòu)也無強(qiáng)制規(guī)范。安裝的依賴默認(rèn)存儲(chǔ)在bower_components目錄下,存儲(chǔ)特點(diǎn)是扁平化的依賴結(jié)構(gòu),如果依賴庫相互之間有版本沖突,bower會(huì)提示用戶并讓用戶仲裁版本。
由于本身的設(shè)計(jì)缺陷無法滿足復(fù)雜項(xiàng)目的構(gòu)建需求,bower在社區(qū)也越來越不流行,但還有一些依賴只能通過bower安裝(比如ember的一些庫)。
npm起初是Node.js生態(tài)的包管理器,后來隨著同構(gòu)js庫的發(fā)展,npm已經(jīng)發(fā)展成了JavaScript生態(tài)的包管理器。npm模塊遵循CommonJS規(guī)范,代碼統(tǒng)一發(fā)布到npm倉庫。安裝的依賴存儲(chǔ)在node_modules目錄下,依賴采用樹形結(jié)構(gòu)存放,也就是同一個(gè)依賴可能會(huì)存在不同的版本,對(duì)于web開發(fā)者來說要注意代碼冗余。
部署版本問題
bower和npm都支持語義化版本號(hào)來定義依賴版本。給版本兼容和依賴升級(jí)帶來一些便利,但也造成了版本的不確定性。在實(shí)際開發(fā)和部署時(shí),往往會(huì)造成開發(fā)時(shí)和部署時(shí)安裝的依賴版本不一致,給線上產(chǎn)品帶來未知風(fēng)險(xiǎn)。
npm 鎖定依賴版本
為此,npm提供了shrinkwrap命令來解決這個(gè)問題。在開發(fā)階段依賴穩(wěn)定后,運(yùn)行如下命令:
npm shrinkwrap
npm shrinkwrap--dev//將dev-dependencies計(jì)算在內(nèi)
shrinkwrap會(huì)在根目錄生成npm-shrinkwrap.json文件。之后的npm install會(huì)參照這個(gè)文件的版本來安裝。
注意項(xiàng)
- shrinkwrap計(jì)算時(shí)是根據(jù)當(dāng)前依賴安裝的目錄結(jié)構(gòu)生成的,如果你不能保證package.json文件定義的依賴與
node_modules下已安裝的依賴是匹配、無冗余的,建議在執(zhí)行shrinkwrap命令前清理依賴并重新安裝(rm -rf node_modules && npm install)或精簡(jiǎn)依賴(npm prune)。 - 默認(rèn)情況下,shrinkwrap只計(jì)算dependencies依賴,而不計(jì)算dev-dependencies,如果在生產(chǎn)環(huán)境也需要開發(fā)依賴或你的依賴分類不清晰,使用
--dev參數(shù)生成shrinkwrap文件確保不會(huì)出問題。 - 如果不需要關(guān)注dev-dependencies,建議npm install --production或npm prune --production
bower 鎖定版本
bower官方并未提供該功能,這里提供下社區(qū)貢獻(xiàn)的方案:bower-shrinkwrap-resolver
1.npm install bower -g
2.npm install bower-shrinkwrap-resolver -g
3.添加以下內(nèi)容到.bowerrc:
{
"resolvers": [
"bower-shrinkwrap-resolver"
]
}
之后執(zhí)行bowerinstall,會(huì)自動(dòng)生成bower-shrinkwrap.json文件。如果需要重新生成,執(zhí)行bower install --reset-shrinkwrap。
參考資料
-npm shrinkwrap
-使用npm shrinkwrap來管理項(xiàng)目依賴
-那些年使用npm進(jìn)行依賴管理所踩的坑
-uber/shrinkwrap