webpack 打包
webpack 中每個模塊有一個唯一的 id,是從 0 開始遞增的。
整個打包后的 bundle.js 是一個匿名函數自執行。
參數則為一個數組。數組的每一項都為個 function。
function 的內容則為每個模塊的內容,并按照 require 的順序排列。
識別入口文件,識別模塊依賴,來打包代碼。webpack做的就是分析代碼,轉換代碼,編譯代碼,輸出代碼
Webpack的兩個最核心的原理分別是:
一切皆模塊
正如js文件可以是一個“模塊(module)”一樣,其他的(如css、image或html)文件也可視作模 塊。
因此,你可以require(‘myJSfile.js’)亦可以require(‘myCSSfile.css’)。
這意味著我們可以將事物(業務)分割成更小的易于管理的片段,從而達到重復利用等的目的。
按需加載
傳統的模塊打包工具(module bundlers)最終將所有的模塊編譯生成一個龐大的bundle.js文件。
但是在真實的app里邊,“bundle.js”文件可能有10M到15M之大可能會導致應用一直處于加載中狀態。
因此Webpack使用許多特性來分割代碼然后生成多個“bundle”文件,而且異步加載部分代碼以實現按需加載。
如何實現一個簡單的webpack
- 讀取文件分析模塊依賴
- 對模塊進行解析執行(深度遍歷)
- 針對不同的模塊使用相應的loader
- 編譯模塊,生成抽象語法樹AST。
- 循環遍歷AST樹,拼接輸出js。
loader原理
在解析對于文件,會自動去調用響應的loader,
loader 本質上是一個函數,輸入參數是一個字符串,輸出參數也是一個字符串。
當然,輸出的參數會被當成是 JS 代碼,從而被 esprima 解析成 AST,觸發進一步的依賴解析。
webpack會按照從右到左的順序執行loader。
一種正確的思路是:
使用JS代碼解析工具(如esprima或者acorn),
將JS代碼轉換成抽象語法樹(AST),
再對AST進行遍歷。
這部分的核心代碼是 parse.js。
webpack優化
設置externals配置項分離不需要打包的庫文件,然后在模版文件中使用script引入即可,配置代碼片段如下:
url-loader中單獨配置cdn,做到js訪問線上路徑,靜態資源使用cdn,兩者互不影響
url-loader不能檢測到js中的background,所以我們凡是在js中引用的地址,必須在外面先import這張圖片,url-loader才會解析并打包
由于webpack打包后的js過大,以至于在加載資源時間過長。所以將文件打包成多個js文件,在需要的時候按需加載。 優化方案:
entry:{ main:'xxx.js' } plugins:{new commonsChunkPlugin({name:'commons',minChunks:function(module){// 下邊return參考的vue-cli配置// any required modules inside node_modules are extracted to vendorreturn (module.resource &&/\.js$/.test(module.resource) &&module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0)} }) , // 以下才是關鍵 new commonsChunkPlugin({name:'charts',chunks:['commons'] minChunks:function(module){return (module.resource &&/\.js$/.test(module.resource) &&module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0 && ['jquery.js', 'highcharts.js','echarts'].indexOf( module.resource.substr(module.resource.lastIndexOf('/')+1).toLowerCase() ) != -1)} }) }優化
1.縮小文件搜索范圍,配置比如resolve.modules,resolve.modules,resolve.mainFields,resolve.alias ,resolve.extensions ,module.noParse 配置
2.使用DllPlugin 要給 Web 項目構建接入動態鏈接庫
3.HappyPack 就能讓 Webpack 做到這點,它把任務分解給多個子進程去并發的執行,子進程處理完后再把結果發送給主進程
4.當 Webpack 有多個 JavaScript 文件需要輸出和壓縮時,原本會使用 UglifyJS 去一個個挨著壓縮再輸出, 但是 ParallelUglifyPlugin 則會開啟多個子進程,把對多個文件的壓縮工作分配給多個子進程去完成
5.可以監聽文件的變化,當文件發生變化后可以自動刷新瀏覽器,從而提高開發效率。
6.(Hot Module Replacement)的技術可在不刷新整個網頁的情況下做到超靈敏的實時預覽。 原理是當一個源碼發生變化時,只重新編譯發生變化的模塊,再用新輸出的模塊替換掉瀏覽器中對應的老模塊。
7.Tree Shaking 可以用來剔除 JavaScript 中用不上的死代碼。它依賴靜態的 ES6 模塊化語法,例如通過 import 和 export 導入導出
8.可以使用CommonsChunkPlugin 把多個頁面公共的代碼抽離成單獨的文件進行加載
9.Webpack 內置了強大的分割代碼的功能去實現按需加載,可以用import實現路由按需加載。
10.Scope Hoisting 可以讓 Webpack 打包出來的代碼文件更小、運行的更快, 它又譯作 “作用域提升”
11.可以使用可視化分析工具 Webpack Analyse等去分析輸出結果,從頁進行優化.
對于 Webpack4,打包項目使用 production 模式,這樣會自動開啟代碼壓縮
12.優化圖片,對于小圖可以使用 base64 的方式寫入文件中
給打包出來的文件名添加哈希,實現瀏覽器緩存文件
總結
以上是生活随笔為你收集整理的webpack 打包的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何定制陶瓷礼品
- 下一篇: 实现一个MVVM和promise