简单实现两个 Webpack 自定义 loader

111 阅读2分钟

基本理论知识

关于 loader 的基本认知

  • loader 的职责是对资源进行转换。
  • loader 的本质是一个导出为函数的 node 模块
  • loader 函数接收一个参数,为包含资源文件内容的字符串
  • loader 函数必须有返回值,将处理完成后的结果 return 出去。

关于编写 loader 的准则

具体参照:# 编写 loader 的用法准则

简单实现自定义 loader

HtmlMinimizeLoader

一个压缩 HTML 文件的 loader,压缩的核心功能交给第三方库 minimize

代码如下:

const Minimize = require("minimize");

/**
 * 压缩 HTML 文件
 * @param {string} source 接收所要处理的文件源代码
 */
function HtmlMinimizeLoader (source) {
    // async 方法返回的才是异步回调函数,异步回调函数会将结果传递出去,因此不需要再 return
    const callback = this.async();

    // webpack 5 不再需要用 loader-utils 的 getOptions 方法获取 option,可以直接通过 this.query 获取
    const options = this.query;    

    const minimize = new Minimize(options);
    // 实际上异步回调函数 callback 接收两个参数,第一个是错误信息,第二个是处理结果
    // 这里 parse 方法的回调函数会返回这两个参数,由 callback 接收并调用
    minimize.parse(source, callback);

    // return result;
};

module.exports = HtmlMinimizeLoader;

关于代码的解读请看片段中的注释

MarkdownLoader

这是一个解析 Markdown 文件的 loader,可以实现将 Markdown 文件显示在 HTML 中。

实现逻辑

1、将 Markdown 文件内容转换为 HTML 结构,这一部分功能交给第三方库 markdown-it

2、处理完的 HTML 结构需要作为一个模块导出,这样才能够通过 import 或 require 被导入。

代码如下:

const MarkdownIt = require("markdown-it");

/**
 * Markdown 文件的加载器
 * @param {string} source 源代码
 * @returns HTML 字符串
 */
function MarkdownLoader (source) {
    const options = this.query;

    // 将 md 转换为 html 格式
    const md = new MarkdownIt({ html: true, ...options });
    const result = md.render(source);
    // html 需要作为一个模块导出,这样才能够通过 import 或 require 被导入
    const html = `module.exports = ${JSON.stringify(result)}`;

    return html;
}

module.exports = MarkdownLoader;

另外,注意这里导出的是 HTML 结构的字符串,并不能直接用在 jsx 中,需要通过 innerHTML 的方式使用。

代码如下:

import mdHTML from "./README.md";

const content = document.createElement("div");
content.innerHTML = mdHTML;
document.body.appendChild(content);

总结

项目地址:

# Webpack-Plugins-And-Loaders

参考文章:

# webpack 中文文档