webpack
擁有六大核心部分:Entry
、Output
、Loaders
、Plugins
、Mode
、Browser Compatibility
,這里就我的理解來稍微聊聊 Loaders
這個部分。
1. 認識 Loader
先放出我對 loader
的理解:
Loader 是用來逐個處理指定類型的文件。
emmm... 下面我們對上面那句話稍微解釋下。
首先我們要先明確,一個 Loader
是如何在 webpack
中配置的,見下面的代碼
{
test: /\.txt$/,
use: 'raw-loader'
}
其中 test
屬性(一個正則表達式)就是用來 指定文件類型的(文件名正在匹配),而 use
屬性自然就是使用指定的 Loader
來 處理 匹配到的文件。最后還剩 逐個 沒解釋,這個其實就是字面意思,Loader
一次處理一個對應的文件,并不是接受一個文件的列表。
對 Loader
有個概念后,我們來說為什么 webpack
需要它。因為 webpack
天生只認識 .js
文件,要是你用到其他類型的文件(例如 .css
、.vue
)那就需要對應的 Loader
來處理了。
接著第二個問題就是:什么樣的文件會經過 Loader
過濾?簡單來說,就是被你代碼中 import
的文件是會去匹配 Loader
的。
2. 執行順序
Loader
是配置在 webpack
一個數組屬性里的,既然是數組那一般來說就存在順序關系。
Loader 的執行順序是從下往上執行的
下面看一段示例配置來驗證下
rules: [{
test: /\.js$/,
use: {
loader: path.resolve('./loader/L03.js')
}
}, {
test: /\.js$/,
use: [{
loader: path.resolve('./loader/L01.js')
}, {
loader: path.resolve('./loader/L02.js')
}]
}]
下面是打印出來的順序
loader two
loader one
loader three
3. 寫一個 Loader
一個 Loader
其實就是一個 js
文件,下面是其基本結構
/**
* @param {string} source
* @returns {string} dist
*/
module.exports = function (source) {
console.log('loader one')
const dist = doSomethingForSrc(source)
return dist
}
入參 source
來自源文件或者上一個 Loader
的 return
,返回值 dist
會流入到下一個 Loader
或者成為最終格式寫入文件。
下面推薦個工具類 loader-utils
,其中有方法可以讀取到 loader
配置中的 options
屬性
// loader
{
loader: path.resolve('./loader/L02.js'),
options: {
msg: 'world'
}
}
const {
getOptions
} = require('loader-utils')
module.exports = function (source) {
console.log('loader two')
const {
msg
} = getOptions(this)
console.log('msg') // world
const reg = new RegExp('\{\{msg\}\}', 'g')
return source.replace(reg, msg)
}
4. 寫在最后
上面講的知識或者代碼,都是源于個人的理解,可能在準確性和深度上都欠妥,不過好處是說的夠直白。同時對于初級使用,理解到這程度也應該夠用。
附上官網關于 Loader
的說明:https://webpack.js.org/api/loaders/