webpack 浅谈系列之 Loader
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/