loader-runner 介绍
定义:loader-runner 允许在不安装 webpack 的情况下,允许 loaders
作用
- 作为 webpack 的依赖,webpack 中使用它执行 loader
 - 
loader 的参数获取
通过 loader-utils 的 getOptions 方法获取
loader 异常处理
loader 内直接通过 throw 抛出
通过 this.callback 传递错误
loader 的异步处理
通过 this.async 来返回一个异步函数
 第一个参数是 Error,第二个参数是处理结果
loader 中使用缓存
webpack 中默认开启 loader 缓存
- 可以通过 
this.cacheable(false)关掉缓存 
缓存条件:loader 的结果在相同的输入下有确定的输出
开发一个 raw-loader
目录 |-loaders |-raw-loader.js |-demo.txt |-run-loader.js
// raw-loader.jsmodule.exports = function (source) {const json = JSON.stringify(source).replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029')// return `export default ${json}`; // 这种方式返回也行this.callback(null, json)}
// run-loader.jsconst { runLoaders } = require('loader-runner');const fs = require('fs');const path = require('path');const config = {resource: path.join(__dirname, './loaders/demo.txt'),loaders: [path.join(__dirname, './loaders/raw-loader.js'),],context: {minimize: true,},readResource: fs.readFile.bind(fs)}const callback = (err, result) => {err ? console.error(err) : console.log(result)}runLoaders(config, callback)
开发一个自动合成雪碧图的 loader
准备知识:如何将两张图片合成一张图片
使用 spritesmith —— https://www.npmjs.com/package/spritesmith
开始实现
目录 |-dist |-loaders |-images |-sprite-loader.js |-run-loader.js
/* index.css */.img1 {background-image: url('./images/fork.png?__sprite');}.img2 {background-image: url('./images/github.png?__sprite');}.img3 {background-image: url('./images/twitter.png?__sprite');}
// sprite-loader.jsconst Spritesmith = require('spritesmith');const fs = require('fs');const path = require('path');module.exports = function (source) {const callback = this.async();const regAll = /url\('([\S]+\?__sprite)'\)/g;const imgs = source.match(regAll);const matchImgs = [];const reg = /url\('([\S]+)\?__sprite'\)/;for (let i in imgs) {const imgPath = reg.exec(imgs[i])[1];matchImgs.push(path.join(__dirname, imgPath));}Spritesmith.run({src: matchImgs}, (err, result) => {fs.writeFileSync(path.join(process.cwd(), 'dist/sprite.png'), result.image);// 替换 css 文件中的图片路径source = source.replace(regAll, (match) => {return 'url("dist/sprite.png")';})fs.writeFileSync(path.join(process.cwd(), 'dist/index.css'), source);callback(null, result);})}
const { runLoaders } = require('loader-runner');const fs = require('fs');const path = require('path');const config = {resource: path.join(__dirname, './loaders/index.css'),loaders: [path.join(__dirname, './loaders/sprite-loader.js'),],context: {minimize: true,},readResource: fs.readFile.bind(fs)}const callback = (err, result) => {err ? console.error(err) : console.log(result)}runLoaders(config, callback)

