最近在学习webapck的知识,webpack loader是必须学习。今天就来简单的手撸一个webpack loader吧。
前置知识:
loader 定义
- 官方定义:用于对模块的源代码进行转换
- 自己理解:就是用于解决各种不同资源问题
规则
- 最后的loader最早调用,传入调用资源;
- 第一个loader最后调用;期望值传出Javascript和source map
- 中间的loader执行时,会传入前一个loader的传出结果
使用注意
loader 的类型以及一些常用的 api ,更详细的指引请参阅官方文档。
几种类型:
- 同步 loader :
return或调用this.callback都是同步返回值 - 异步 loader :是用
this.async()获取异步函数,是用this.callback()返回值 - raw loader :默认情况下接受
utf-8类型的字符串作为入参,若标记raw属性为true,则入参的类型为二进制数据 - pitch loader :
loader总是从右到左被调用。有些情况下,loader只关心 request 后面的 元数据(metadata),并且忽略前一个loader的结果。在实际(从右到左)执行loader之前,会先从左到右调用loader上的pitch方法。
开发loader时常用的 API 如下:
this.async:获取一个callback函数,处理异步this.callback:同步loader中,返回的方法this.emitFile:产生一个文件this.getOptions:根据传入的schema获取对应参数this.importModule:用于子编译器在构建时编译和执行请求this.resourcePath:当前资源文件的路径
例子
loader执行顺序
- 例子1: loader执行先执行scss-loader,最后执行style-loader
css-loader:处理css 文件的依赖以及资源的加载(因为 webpack 默认只支持JS的导入以及一些资源文件的导入,所以我们需要实现对css文件的导入)
style-loader:将css-loader处理后的结果输出到文档中
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{ loader: "scss-loader" },
]
}
]
}
例子2:
实现一个转换markdown为html的loader
分三步:
- 在webpack.config.js 配置loader,传入option参数
- 编写loader,每一个loader都是一个函数,source为传入资源。这个函数的返回结果要么是二进制数据要么是字符串,字符串就是文件的具体内容(为Javascript),二进制数据就是资源文件比如图片的内容。
// webpack.config.js 配置loader
{
test: /\.md$/,
use: [
{ loader: './markdown-loader', options: { headerIds: false }}
]
}
// 编写loader
// markdown-loader.js
const marked = require("marked");
function markdownLoader(source) {
const options = this.query; // 获取loader参数 { headerIds: false }
另一种options获取方法:
const schema = {
type: 'object', //options是一个对象
properties: {
headerIds: {
type: 'boolean'
},
}
}
const options = this.getOptions(schema) || {}
// 处理
const html = marked.marked(source, options); // 使用marked插件转换为html
const code = `module.exports = ${JSON.stringify(html)}`
return code; // 传出Javascript
}
module.exports = markdownLoader;
// html引用
import html from './markdown.md';
document.getElementById("root").innerHTML = html;