loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。
Loader 本质
loader 只是一个导出为函数的 JavaScript 模块。有同步 loader 和异步 loader。
同步 loader
// 同步loader
module.exports = function(content,map,meta){
return someSyncOperation(content)
}
复制代码
异步 loader
// 异步loader:使用 this.async 来获取 callback 函数
module.exports = function(content,map,meta){
var callback = this.async()
someAsyncOperation(content, function(err, result) {
if (err) return callback(err);
callback(null, result, map, meta);
});
}
复制代码
Loader 的执行顺序
首先看看 loader 的配置:
module.exports = {
module:{
rules:[
{
test:/\.less$/,
use:[
'style-loader',
'css-loader',
'less-loader'
]
}
]
}
}
复制代码
多个 loader 是串行执行,顺序从后到前执行,这是因为 Webpack 采用的是 Compose 的函数组合方式:
// 将前一个函数的返回值作为下一个函数的入参,依次往下执行
var compose = (...fns)=>{
return (arg)=>fns.reduce((promise,fn)=>promise.then(fn),Promise.resolve(arg))
}
// 用法如下:
var item1 = (x)=>{return new Promise((resolve)=>{
setTimeout(()=>{
console.log('1')
resolve(x)
},1000)
})}
var item2 = (y)=>{return new Promise((resolve)=>{
setTimeout(()=>{
console.log('2')
resolve(y+3)
},5000)
})}
var a = compose(item1,item2)
a(5).then(console.log)
// 依次输出:1,2,8
复制代码
Row-loader 的实现
// scr/raw-loader.js
module.exports = function(source){
const json = JSON.stringify(source)
// 为了安全,处理ES6模板字符串问题
.replace(/\u2028/g,'\\u2028')
.replace(/\u2029/g,'\\u2029')
return `export default ${json}`
}
复制代码
Loader-Runner 调试工具
loader 不同于 plugin,可以独立于 webpack 进行开发调试。
安装
npm install loader-runner --save-dev
复制代码
使用例子
// test-loader.js 调试 raw-loader.js
import { runLoaders } from "loader-runner";
const fs = require('fs')
const path = require('path')
runLoaders({
// 资源的绝对路径(可以增加查询字符串,如?query)
resource:'./test.txt',
// loader的绝对路径可以增加查询字符串)
loaders:[path.resolve(__dirname,'./loader/raw-loader.js')],
// 基础上下文之外的额外loader上下文
context:{
minimize:true
},
// 读取资源函数
readResource:fs.readFile.bind(fs)
},function(err,result){
err?console.log(err):console.log(result)
})
// 运行测试
node test-loader.js
复制代码
loader 中如何进行异常处理,使用缓存,产生一个文件,详细可以查看:loader api 官方文档
总结
至此我们学习了 Loader 的使用。
附文章:
浅谈webpack源码
前端知识体系总结输出文章目录大全
评论