webpack中loader使用和的工作原理
阿新 • • 發佈:2020-12-27
技術標籤:webpack
loader的本質就是一個個的函式,在模組的編譯階段,會使用這些loader對原始碼進行處理,處理時,一般都會生成AST解析樹,這樣可以方便處理。
單個loader的使用沒有什麼好記錄的。
多個loader的使用是用一個use陣列,loader的使用順序是從下往上,也就是從use陣列的後往前執行的,下面的load1、loader2、loader3是我自己定義的loader
use: [
'loader1',
'loader2',
{
loader: 'loader3',
options: {
name: 'jack',
age: 18
}
}
]
為了方便webpack找到loader,我們可以配置loader的解析規則,也就是解析路徑
// 配置loader的解析規則
resolveLoader: {
// 指定找loader去哪個地方找
modules: [
// 這是預設值
'node_modules',
// 指定自己的
path.resolve(__dirname, 'loaders')
]
},
下面是loader1.js的內容,註釋已經寫得很清楚了,值得注意的是,module.exports和module.exports.pitch這兩個函式的執行順序是不一樣的,pitch是按照use陣列從前往後執行,所以比較適合用來對loader做一些預處理。
// loader本質上是一個函式
// content就是原始檔或者後一個loader傳過來的內容
// module.exports = function (content, map, meta) {
// // console.log(content);
// console.log(111);
// return content;
// }
// 下面這種寫法和上面那種寫法是一樣的(同步loader)
module.exports = function (content, map, meta) {
console.log(111);
// 第一個引數是是否有錯誤,第三四個引數是可選的
this.callback (null, content, map, meta);
}
// pitch方法會根據loader的順序從前往後執行
module.exports.pitch = function () {
console.log('pitch 111');
}
下面是loader2中的內容,不同於loader1的是,它是一個非同步的loader,非同步loader的好處就是它可以執行一些非同步操作,可以等非同步操作完之後再執行接下來的loader,效能更好。
// 非同步loader
module.exports = function (content, map, meta) {
console.log(222);
// 呼叫this.async() 告訴webpack這是一個非同步loader,需要等待 callback() 回撥之後再進行下一個loader處理
const callback = this.async();
setTimeout(() => {
callback(null, content)
}, 1000)
console.log('loader2中的非同步')
}
module.exports.pitch = function () {
console.log('pitch 222');
}
下面是loader3中的內容,主要就是獲取loader的選項和驗證loader的選項
//getOptions方法可以來獲取loader的選項(這個包webpack沒有自帶)
const { getOptions } = require('loader-utils');
// 驗證options是不是符合規範(這個包是webpack內部自帶的包)
const { validate } = require('schema-utils');
const schema = require('./schema');
module.exports = function (content, map, meta) {
// 獲取options
const options = getOptions(this);
console.log(333, options);
// 校驗options是否合法,如果不合法,會報錯
validate(schema, options, {
name: 'loader3'
})
return content;
}
module.exports.pitch = function () {
console.log('pitch 333');
}
這是schema.json中的內容
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "名稱~"
}
},
"additionalProperties": true
}
下面是執行打包後的結果,可以看到loader中的內容按預期執行