写点什么

WebPack | Loader 处理非 JavaScript 模块机制详解

用户头像
梁龙先森
关注
发布于: 2021 年 01 月 27 日
WebPack | Loader处理非JavaScript模块机制详解

loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。


本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。

Loader 本质

loader 只是一个导出为函数的 JavaScript 模块。有同步 loader 和异步 loader。


  1. 同步 loader

// 同步loadermodule.exports = function(content,map,meta){	return someSyncOperation(content)}
复制代码
  1. 异步 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 进行开发调试。

  1. 安装

npm install loader-runner --save-dev
复制代码
  1. 使用例子

// 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源码

前端知识体系总结输出文章目录大全


发布于: 2021 年 01 月 27 日阅读数: 42
用户头像

梁龙先森

关注

脚踏V8引擎的无情写作机器 2018.03.17 加入

还未添加个人简介

评论

发布
暂无评论
WebPack | Loader处理非JavaScript模块机制详解