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/