webpack只能處理javascript的模塊,如果要處理其他類型的文件,就需要使用loader來轉(zhuǎn)換。loader是webpack中一個重要的概念,它是指用來降一段代碼轉(zhuǎn)換成另一端代碼的webpack加載器。
首先,來新建一個項目webpack-loader,并且安裝webpack,webpack-cli
// 新建webpack.config.js
let path = require("path");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
filename: "build.js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [
{
test: /\.js$/,
use: path.resolve(__dirname, 'loader', 'loader1.js') // 這里解析除了一個絕對路徑“rootpath +“/loader/loader1.js””
}
]
}
};
上邊代碼中,對js文件,我們使用loader目錄下的loader1.js來轉(zhuǎn)換。接下來我們些loader1.js
現(xiàn)在的文件結(jié)構(gòu)是這樣的

image.png
正常情況下loader是一個函數(shù),所以,我們的loader1.js大約是這樣的:
//loader1.js
function loader(source) {
// 這里的參數(shù)是源碼
// ...這里就進(jìn)行一些代碼轉(zhuǎn)換
return source;
}
module.exports = loader;
運行 npx webpack

image.png
但是像
path.resolve(__dirname, 'loader', 'loader1.js')這樣的寫法實在不美觀,我們可以再webpack.config.js中加resolveLoader字段來重命名
//webpack.config.js
resolveLoader: {
modules: ['node_modules', path.resolve(__dirname, 'loader', 'loader1.js')]
//別名
// alias: {
// loader1: path.resolve(__dirname, 'loader', 'loader1.js')
// }
},
module: {
rules: [
{
test: /\.js$/,
use: 'loader1'
}
]
}
以上,alias和modules都可以實現(xiàn)loader的查找
下邊我們來說說loader的配置,先新建兩個文件,loader2.js,loader3.js
//loader1.js
function loader(source) {
console.log("loader1~~~~~~");
return source;
}
module.exports = loader;
// loader2.js
function loader(source) {
console.log("loader2~~~~~~");
return source;
}
module.exports = loader;
//loader3.js
function loader(source) {
console.log("loader3~~~~~~");
return source;
}
module.exports = loader;
// webpack.config.js
module.exports = {
...
module: {
rules: [
{
test: /\.js$/,
use: "loader1"
},
{
test: /\.js$/,
use: "loader2"
},
{
test: /\.js$/,
use: "loader3"
}
]
}
...
}
執(zhí)行

image.png
如圖,之前的博客有提過,loader的執(zhí)行順序是從下往上,從右往左的。但如果需要指定順序的話,笨辦法就是按照loader的加載順序來寫,或者配置*enforce*來實現(xiàn)
module: {
rules: [
{
test: /\.js$/,
use: "loader1",
enforce: "pre"
},
{
test: /\.js$/,
use: "loader2"
},
{
test: /\.js$/,
use: "loader3",
enforce: "post"
}
]
}
現(xiàn)在運行

image.png
可以看到“pre”會將loader置前,“post”將loader置后。normal介于兩者之間。那么inline類型的loader呢?我們來試一下:
// 新建a.js
module.exports = "lcccc";
//index.js中引入,并且傳入inline-loader
console.log("loader");
let str = require('inline-loader!./a.js');
//新建inline-loader.js文件
function loader(source) {
console.log("inline-loader~~~~~~");
return source;
}
module.exports = loader;
運行

image.png
可以看到,執(zhí)行優(yōu)先級是這樣
pre > normal > inline > post的但是當(dāng)某個文件你想特殊處理,比如上邊的a.js,就是不想讓它用webpack配置的pre和normal loader,而只使用inline-loader,你可以這樣:
//index.js
console.log("loader");
// “-!”,不會讓文件再去通過pre+normal loader來處理了
// “!”, 不使用normal-loader
// “!!”,什么都不要,只使用這個行內(nèi)loader
let str = require("-!inline-loader!./a.js");
執(zhí)行:

image.png
別的情況大佬們自己試試
loader分為Pitch Loader和Normal Loader

圖片轉(zhuǎn)自珠峰培訓(xùn)

圖片轉(zhuǎn)自珠峰培訓(xùn)
如上圖:
loader執(zhí)行首先會加載pitch-loader(書寫loader的順序),然后加載資源resource,最后執(zhí)行normal-loader(正常加載loader的順序,右到左,下往上)
如果pitch-loader有返回值,則會跳過后面的loader,直接走到上一層的normal-loader里面。
從上圖也大抵能夠理解loader為什么是從下往上,從右往左執(zhí)行了。至于pitch,后續(xù)博文會有詳解