loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。
Loader 本质
loader 只是一个导出为函数的 JavaScript 模块。有同步 loader 和异步 loader。
同步 loader
// 同步loadermodule.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.jsmodule.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.jsimport { 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源码
前端知识体系总结输出文章目录大全
评论