wabpack 是做什么的?
概念:webpack 是一個用于現(xiàn)代 JavaScript 應(yīng)用程序的 靜態(tài)模塊打包工具。當(dāng) webpack 處理應(yīng)用程序時,它會在內(nèi)部從一個或多個入口點構(gòu)建一個 依賴圖(dependency graph),然后將你項目中所需的每一個模塊組合成一個或多個 bundles,它們均為靜態(tài)資源,用于展示你的內(nèi)容
原理: 從入口開始遞歸的開始讀取模塊所依賴的的文件內(nèi)容,生成 AST 樹,然后遍歷 AST 樹,輸出讓瀏覽器能夠運行的代碼到 dist 文件夾
loader 與 plugin 的區(qū)別
webpack 將一切都視為模塊,但是 webpack 原生只能解析 js 文件和 json 文件,如果要解析其他類型的文件就要用到 loader,所以loader 相當(dāng)于翻譯官的作用,將其他類型的文件進行預(yù)處理
Plugin 為插件的意思,Plugin 可以擴展 webpack 的功能,在 Webpack 運行的生命周期中會廣播出許多事件,Plugin 可以監(jiān)聽這些事件,幫助 webpack 做一些事情。
loader 有些什么注意事項
- 單一原則,一個 loader 只能做一個事情
- 多個 loader 會按照從右至左的順序執(zhí)行
例如:
['css-loader', 'vue-style-loader'] // 會先執(zhí)行vue-style-loader然后再執(zhí)行css-loader
常用的 plugin
- html-webpack-plugin 這個插件會創(chuàng)建一個 html 文件,并且會自動的引入打包好的文件資源
- mini-css-extract-plugin 打包過后的 css 在 js 文件里,該插件可以把 css 單獨抽出來
怎么利用 webpack 來優(yōu)化網(wǎng)頁性能
- 資源文件壓縮
- Tree Shaking
- 代碼分離
- 動態(tài)導(dǎo)入代碼(懶加載、預(yù)獲?。?/li>
- 緩存
資源文件壓縮
webpack 默認在生產(chǎn)模式中的就會壓縮 js 代碼,css 壓縮可以使用 CssMinimizerWebpackPlugin 這個插件
Tree Shaking
Tree Shaking中文含義是搖樹,在 webpack 中指的是打包時把無用的代碼搖掉,以優(yōu)化打包結(jié)果,而webpack5已經(jīng)自帶了這個功能了,當(dāng)打包環(huán)境為production時,默認開啟tree-shaking功能。
代碼分離
將公共資源提取出來,打包成一個文件,optimization 中進行如下配置
optimization: {
splitChunks: {
chunks: 'all'
}
}
動態(tài)導(dǎo)入代碼(懶加載、預(yù)獲?。?/h4>
懶加載:當(dāng)用到某個模塊的時候才加載
預(yù)獲?。寒?dāng)瀏覽器空閑的時候采取獲取資源
緩存
瀏覽器具有緩存機制,當(dāng)不更改文件名的時候,瀏覽器會認為你沒有更新,就會使用緩存版本
具體實現(xiàn):
- 緩存第三方庫,將第三方庫提取到單獨的 Vendorchunks 的文件中,利用瀏覽器的長效緩存機制,命中緩存來消除請求,在 optimization.splitChunks 添加 cacheGroups 參數(shù)
- 業(yè)務(wù)代碼文件不緩存,在 output 中的 filename 設(shè)置為[name][contenthash].js,contenthash 會根據(jù)文件的內(nèi)容生成一個 hash 的字符串
如何提高代碼構(gòu)建速度
- 優(yōu)化 loader 配置,縮小處理范圍:合理利用這兩個屬性 exclude:不需要處理的文件 和 include:需要處理的文件
- HMR(Hot Module Replacement) 模塊熱替換只重新構(gòu)建發(fā)生變化的模塊
- babel 緩存 第二次構(gòu)建時,會讀取之前的緩存,只重新構(gòu)建變化的文件
- 使用 Dll 進行分包
- 多進程打包
優(yōu)化 loader 配置
在使用loader時,可以通過配置include、exclude、test屬性來匹配文件,接觸include、exclude規(guī)定哪些匹配應(yīng)用loader
在配置 babel-loader時,如下:
module.exports = {
module: {
rules: [
{
// 如果項目源碼中只有 js 文件就不要寫成 /\.jsx?$/,提升正則表達式性能
test: /\.js$/,
// babel-loader 支持緩存轉(zhuǎn)換出的結(jié)果,通過 cacheDirectory 選項開啟
use: ['babel-loader?cacheDirectory'],
// 只對項目根目錄下的 src 目錄中的文件采用 babel-loader
include: path.resolve(__dirname, 'src'),
},
]
},
};
模塊聯(lián)邦
我們知道 webpack 可以通過 dll 實現(xiàn)對同一個項目的公共組件模塊,做成代碼共享 common chunk,但是如果是要實現(xiàn)跨項目針對不同的應(yīng)用就變得非常的困難不易實現(xiàn)。幾乎沒辦法做到不同應(yīng)用之間進行插拔式的熱更新。那怎么樣去實現(xiàn)這種跨應(yīng)用間的共用模塊運用呢?于是乎 webpack5 內(nèi)置了一個模塊聯(lián)邦的功能特性,這個功能可以讓跨應(yīng)用間做到模塊共享真正的插拔式的便捷使用。比如 a 應(yīng)用如果想使用 b 應(yīng)用中 list 的組件,通過模塊聯(lián)邦可以直接在 a 中進行 import('b/list')非常的方便
模塊聯(lián)邦配置使用
new ModuleFederationPlugin({
// 當(dāng)前應(yīng)用的名稱, 需要唯一性
name: "main_app",
// 入口文件名稱, 用于對外提供模塊時候的入口文件名
filename: "remoteEntry.js",
// 需要導(dǎo)出的模塊, 用于提供給外部其他項目進行使用
exposes: {
"./search": "./src/search/search.vue"
},
// 需要依賴的遠程模塊, 用于引入外部其他模塊
remotes: {
lib_remote: "lib_remote@http://localhost:8085/remoteEntry.js",
},
// 配置共享的組件, 一般是對第三方庫做共享使用
shared: {
vue: {
eager: true,
singleton: true,
}
}
})