以前寫了一篇關於webpack 如何使用的文章:webpack 單頁面應用實戰,而且寫了一個 單頁面應用的小項目 放到了github上。正巧公司前段時間用webpack 作了一個項目,項目不大,是基於單頁面應用的。可是上線後才發現了一些問題,原來仍是有一些要優化改進的地方。css
webpack 單頁面應用實戰這篇文章基本已經知足了咱們的需求。好比如下功能咱們都已經實現:html
將css從js中分離出來node
使用loader加載css、圖片等webpack
使用插件生成html以便自動引用變動版本號的文件git
配置公共jsgithub
js文件按需加載web
配置開發環境npm
壓縮js、css、htmlsegmentfault
給css、js、圖片、字體等添加版本號後端
編譯後自動打開瀏覽器
熱替換
使用代理結合後端服務開發
編譯時區分開發環境、生產環境、熱替換環境
config 文件的合併
清空發佈目錄
看似不錯,好像都已經實現了,可是具體到生產環境時仍是有問題的。下面有幾處優化(下面仍是結合這個項目)。
這個問題在項目上線以前我沒有發現,上線之後,有一次需求變化,我在改變其餘js文件的時候,而後打包發佈發現公共js的版本號發生了改變,最後檢查下來,的確是公共js的內容發生了變化,因此對應的版本號發生了變化。緣由就是webpack默認會把最重要的東西放到公共js裏,這裏麪包含webpack啓動應用程序的依賴項、模塊與模塊的依賴關係、以及文件的版本號等信息。因此一旦任意的js文件發生改變都會體如今公共js上。好比咱們經過webpack構建後生成這樣的文件:
再看下common.js 裏大體包含什麼內容(截取一小部分):
公共js版本號會變的問題在 github 上討論了一段時間(點擊這裏),只不過以前沒注意。有人用 webpack-md5-hash 插件實現了,可是感受比較麻煩,最終仍是感受webpack 的貢獻者實現的這種方式很簡單,而且不須要額外的插件,在新版本的webpack中融合的很好。可是提供的這個demo太簡單,在項目中咱們仍是要注意一些問題的。好比使用‘熱替換’時就會報錯。因此咱們要作一些改變,咱們只須要將以前配置公共js的地方:
// webpack.config.js ... plugins:[ // 會把 ‘entry’ 定義的 common 對應的兩個js 打包爲 ‘common.js’ new webpack.optimize.CommonsChunkPlugin("common", 'js/[name].js', Infinity), ] ...
改成:
// webpack.config.js ... new webpack.optimize.CommonsChunkPlugin( devServer ? {name: "common", filename: "js/common.js"}: {names: ["common", "webpackAssets"]} ), ...
注意: ‘devServer’ 是一個標識變量,表明‘熱替換’ ,若有疑惑看上一篇配置變量標識
改爲這種設置之後,當時熱替換模式的時候不對common.js作處理,若是是開發模式或者發佈模式,會從common.js中將各個文件的版本號以及其餘重要信息抽出來,放到‘webpackAssets.js’文件中(名稱能夠自定義)。生成的文件以下,會多出一個文件,這個文件只有幾kb:
改爲這種作法後,一旦其餘的文件發生改變,都會在webpackAssets.js文件中獲得體現,項目的發佈升級,只要額外的將這個文件升級上去便可,而不用將公共js升級上去。這樣的優化會很是有利於處理緩存的問題。
若是項目小不設置webpack請求的模塊目錄不要緊,可是通常項目愈來愈大,webpack會查找不少無用的文件,這時候設置模塊目錄頗有必要性,能夠提升webpack編譯的速度。即設置 resolve.root 屬性。還有一個屬性是 moduleDirectories,這兩個的區別能夠點這裏。resolve.root 接收的參數是 node_modules 文件加的絕對路徑。咱們在以前的webpack.config.js 中增長這個配置項:
// webpack.config.js ... resolve:{ root: [ path.resolve('./node_modules') ], ... } ...
這樣設置後,webpack編譯速度會大大加快,不會每一個文件夾都搜索一遍。