webpack是一個模塊打包器(module bundler),提供了一個核心,核心提供了很多開箱即用的功能,同時它可以用loader和plugin來擴展。webpack本身結構精巧,基於tapable的插件架構,擴展性強,眾多的loader或者plugin讓webpack稍顯復雜。
webpack常用配置包括:devtool、entry、 output、module、resolve、plugins、externals等,本文主要介紹下webpack常用的loader和plugin
webpack允許我們使用loader來處理文件,loader是一個導出為function的node模塊。可以將匹配到的文件進行一次轉換,同時loader可以鏈式傳遞。
一、webpack的常見配置
const webpack = require("webpack");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 入口文件
entry: {
app: path.join(__dirname, "../src/js/index.js")
},
// 輸出文件
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
publicPath: "/"
},
// loader配置
module: {
rules: [
{
test: /\.scss/,
use: [
"style-loader",
"css-loader"
]
}
......
]
},
// plugins配置
plugins: [
// 重新創建html文件
new HtmlWebpackPlugin({
title: "首頁",
filename: "index.html",
template: path.resolve(__dirname, "../src/index.html")
})
......
]
}
二、webpack的打包原理
識別入口文件
通過逐層識別模塊依賴(Commonjs、amd或者es6的import,webpack都會對其進行分析,來獲取代碼的依賴)
webpack做的就是分析代碼,轉換代碼,編譯代碼,輸出代碼
最終形成打包后的代碼
三、什么是loader
loader是文件加載器,能夠加載資源文件,並對這些文件進行一些處理,諸如編譯、壓縮等,最終一起打包到指定的文件中
處理一個文件可以使用多個loader,loader的執行順序和配置中的順序是相反的,即最后一個loader最先執行,第一個loader最后執行
第一個執行的loader接收源文件內容作為參數,其它loader接收前一個執行的loader的返回值作為參數,最后執行的loader會返回此模塊的JavaScript源碼
四、什么是plugin
在webpack運行的生命周期中會廣播出許多事件,plugin可以監聽這些事件,在合適的時機通過webpack提供的API改變輸出結果。
五、loader和plugin的區別
對於loader,它是一個轉換器,將A文件進行編譯形成B文件,這里操作的是文件,比如將A.scss轉換為A.css,單純的文件轉換過程
plugin是一個擴展器,它豐富了webpack本身,針對是loader結束后,webpack打包的整個過程,它並不直接操作文件,而是基於事件機制工作,會監聽webpack打包過程中的某些節點,執行廣泛的任務
class MyPlugin{ constructor(options){ console.log("MyPlugin constructor:", options); } apply(compiler){ compiler.plugin("compilation", compilation => { console.log("MyPlugin"); }); } } module.exports = MyPlugin; webpack.config.js配置: module.exports = { ... plugins: [ new MyPlugin({param: "my plugin"}) ] }
使用該plugin后,執行的順序:
webpack啟動后,在讀取配置的過程中會執行new MyPlugin(options)初始化一個MyPlugin獲取其實例
在初始化compiler對象后,就會通過compiler.plugin(事件名稱,回調函數)監聽到webpack廣播出來的事件
並且可以通過compiler對象去操作webpack
