這兩天一直在忙於封裝一個vue table組件併發布到npm,記錄一下我是如何把npm包的大小從100多kb減少到不足1kb的過程。html
這個組件底層依賴於element-ui,使用了其table組件和pagination組件,最終的組件是一個徹底經過配置來描述每一列的表格組件。最開始我發佈的是打包以後的代碼。若是使用的這個組件的項目中沒有引入過element-ui組件,那麼不會形成任何重複的依賴,直接引用打包後的版本。可是若是項目自己已經引入了完整的element-ui(咱們公司使用這個組件的10餘個系統均引入了完整的element-ui),那麼很明顯會形成代碼的重複,會使bundle增長90kb(未壓縮時)。vue
若是發佈的通過打包後的組件,是沒辦法避免重複依賴的。若是能夠像把源代碼直接copy到項目再import引入這樣,就能夠避免重複的依賴了。這個可使用package.json中的module字段來完成。node
當package.json中存在module字段時,會優先尋找module對應的文件,並使用ES模塊規範處理。webpack
咱們能夠把未通過打包的源代碼發佈到npm,並把package.json中的module字段指向源代碼,這樣引入的package就交由項目的構建工具(webpack, babel)來進行處理,所以理論上就能夠避免重複依賴了。git
有可能,由於webpack插件能夠配置exclude字段,若是項目的webpack配置exclude掉了node_modules,就會產生反作用。好比可能未經babel轉碼成es5代碼(我發佈的這個組件目前只會存在這樣一種可能的反作用)。github
到目前爲止,還並不能解決重複依賴的問題。。。這是由於重複依賴的判斷機制.Node.js中相同模塊是否會被加載屢次?web
nodeJs是根據模塊的路徑來判斷是否爲同一依賴的,而你們都知道node.js會從當前模塊所在目錄的node_module開始找起,若是沒找到再會去找上級目錄的node_modules,直到根目錄爲止。那麼問題就來了。vue-cli
我發佈的包裏面dependencies裏包含element-ui,這沒問題,我確實依賴了element-ui。那麼install包時,會根據我寫明的dependencies下載element-ui並放在包的node_modules裏面。因此這個包引用的element-ui和項目自己引用的element-ui因爲path不一樣被認爲是不一樣的依賴,因而都被打包進了bundle裏面形成了重複依賴。npm
方法1,在項目的babel配置中添加按需引入element-ui的配置,可是這個方法須要修改項目的配置,比較繁瑣,我維護的10來個系統須要一個一個去改,太麻煩了。。。。element-ui
方法2,很簡單,把發佈的包的package.json的dependencies的element-ui和Vue刪掉,這樣npm install的時候就不會下載element-ui到包的node_modules,就是往上級目錄找,直到項目node_modules裏面的element-ui,這樣,包引用的element-ui和項目引用的element-ui就是同一個依賴,就不會重複打包這和vue-cli3打包的庫不會包含Vue依賴是同一個原理。最終的結果就是最終生產環境打包後的chunk-vender.js僅僅增長了不到1kb。
不過這樣也形成了必定的問題,那就是自己不使用element-ui的項目須要手動引入打包以後的發佈的文件。不過不使用element-ui組件的項目使用這個表格組件的收益和機率都不高,若是真的要用的話,單獨再發佈一個徹底打包以後的包,也能快速解決問題。
經過這兩天的折騰,主要收穫有4點一、發佈npm包的流程二、package.json中的module字段三、判斷重複依賴的機制四、基於ui組件封裝組件時如何避免重複依賴