loader 在 webpack 编译中起到非常重要的作用,用于对模块的源代码进行转换,比如 css-loader 将 css 代码处理成字符串,style-loader 创建 style 标签将 css 代码添加到 html 页面中。

自定义 loader

新建 node 项目,在 src 文件夹下的 index.js 中简单编写一些代码

const user = {
  name: 'alice',
  age: 20,
};

创建 loaders 文件夹,在文件夹下增加用于处理 loader 的 js 文件,通过 module.exports 函数可以拿到需处理的文件内容,并将处理好的结果返回

module.exports = function (content) {
  console.log('ice-loader>>', content);
  return content + '"@author icecream"';
};

在配置文件 webpack.config.js 中引入自定义的 loader 。定义 loader 方式有两种

  • 通过相对路径引入(这里使用的方式)
  • 通过 resolveLoader 属性配置,默认会去 node_modules 中查询依赖
// 其他配置省略
module: {
    rules: [
      {
        test: /\.js/i,
        use: ['./loaders/ice-loader'],
      },
    ],
  },

通过 webpack 编译文件,在控制台上输出了获取到的文件内容,编译后文件就是通过自定义 loader 返回的内容。

同步异步 loader

通过 loader 处理的数据需要返回 javscript 字符串,有两种方式

  • return 语句返回内容
  • this.callback 函数返回内容

当遇到异步返回的情况时,直接使用以上两种方式是会报错的

需要通过 this.async 函数将处理过程变成异步,this.callback 第一个参数接收 error,如果没有错误则传递 null,其他参数与loader中 module.exports 获取的参数相同

babel-loader

babel-loader 处理 js 代码借助的是 babel 这个工具,我们也可以简易实现一个,取名为ice-babel-loader,使用 babel 的时候需要通过 plugin 或者 presets 定义处理规则

{
  test: /\.js/i,
  use: [
    {
      loader: './loaders/ice-babel-loader',
      options: {
        presets: ['@babel/preset-env'],
      },
    },
  ],
},

babel 工具核心库是 @babel/core,定义处理规则要用到预设 @babel/preset-env,依次安装

const babel = require('@babel/core');

module.exports = function (content) {

  const options = this.getOptions(); // 获取loader中定义的options
  const callback = this.async();   babel.transform(content, options, (err, result) => {
    if (err) callback(error);
    callback(null, result.code);
  });
};

这样我们定义的 ice-babel-loader 就将 es6 的语法转成了 es5

md-loader

Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成有效的 XHTML(或者HTML)文档。

那 md 文件是否可以通过 loader 转换成 html 文档呢?答案是肯定的,已经有一些好用的库给我们提供了这个功能。

marked 用于处理 markdown 格式的文件,highlight.js 用于给 markdown 文件中的代码设置样式

const { marked } = require('marked');
const hljs = require('highlight.js'); module.exports = function (content) {
// 给markdown中的代码增加class属性
  marked.setOptions({
    highlight: function (code, lang) {
      return hljs.highlight(lang, code).value;
    },
  });
  const htmlContent = marked(content);
  return htmlContent;
};

此时通过 md-loader 返回的是普通字符串,不能被 javascript 代码所识别,还需要通过 html-loader 处理。

{
test: /\.md/i,
use: ['html-loader', './loaders/md-loader'],
},

通过 loader 处理后的 md 文件导出的是 javascript 字符串,所以可以直接添加到 body 中查看效果,另外代码的样式显示需要引入 highlight.js 中的 css 文件

// index.js
import code from './doc.md';
import 'highlight.js/styles/default.css';
document.body.innerHTML = code;

这样 markdown 文件就可以在项目中被解析到 html 页面中了

总结

  • 自定义 loader 通过 module.exports 获取获取资源内容,经过一系列处理并返回处理后的结果。
  • 自己编写的 loader 在本地可以直建立文件夹处理资源,开发完成后发布到 npm 仓库可以直接通过下载包的方式引用 loader。

以上就是关于 自定义loader 的介绍, 更多有关 webpack 的内容可以参考我其它的博文,持续更新中~

一起来自定义loader吧的更多相关文章

  1. ASP.NET WebApi通过自定义ControllerSelector来自定义Controller的选择

    在web api中,我们可以通过给Cotroller类添加RoutePrefixAttribute来定义url与Controller之间的映射,但是有时候有一些特殊情况下,我们需要做一些特殊处理来将某 ...

  2. 最好的Kubernetes客户端Java库fabric8io,快来自定义你的操作

    我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 Kubernetes Java客户端 对于Kubernetes集群的操作,官方提供了命令行工具kubectl,这也是我 ...

  3. 使用 antd 的 form 组件来自定义提交的数据格式

    最近使用antd UI 的表单提交数据,数据里面有的是数组,有的是对象.提交的时候还要去校验参数,让人非常头疼.在我仔细看完文档之后,发现 antd 的 form 组件做的非常不错,这些需求通通不是问 ...

  4. 通过jquery来实现文本框和下拉框动态添加效果,能根据自己的需求来自定义最多允许添加数量,实用的jquery动态添加文本框特效

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. 通过web.config来自定义output caching缓存

    我们服务器有开启缓存功能, 缓存功能可以减少您访问网站时候网站在服务器里面的编译时间, 大大加快您网站的访问速度, 如果您需要对您网站进行频繁更新的话, 您可以考虑暂时将缓存时间减少,或者暂时关闭缓存 ...

  6. sql结合通配符来自定义转义字符

    1.使用   ESCAPE   关键字,定义转义符.在模式中,当转义符置于通配符之前时,该通配符就解释为普通字符.例如,要搜索在任意位置包含字符串   5%   的字符串,请使用:      WHER ...

  7. [How to]如何通过xib来自定义UIViewController

    代码:https://github.com/xufeng79x/CreateControllerByXib 1.简介 UIViewController实例可以通过代码.storyborad或者xib方 ...

  8. 《TomCat与Java Web开发技术详解》(第二版) 第三章节的学习总结--利用Context元素来自定义web应用的存储位置

    在学习完第三章后(第三章提供的web应用是helloaapp,我将其放到了tomcat/webapps中),对Context元素的作用理解不深:但是当进入第四章后,发现第四章提供的源码包中也有一个叫h ...

  9. 纯CSS3来自定义单选框radio与复选框checkbox

    单选框(radio)自定义样式 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 3 ...

  10. Media Session API 为当前正在播放的视频,音频,提供元数据来自定义媒体通知

    google 文档 https://developers.google.cn/web/updates/2017/02/media-session <html lang="zh-cmn- ...

随机推荐

  1. 关于Mybatis

    一:Mybatis的优缺点 优点: 1.与JDBC相比,减少了百分之五十的代码量. 2.Mybatis是最简单的持久层框架,简单易学. 3.Mybatis灵活,不会对应用程序和现数据库设计强加任何影响 ...

  2. 2023-02-14:魔物了占领若干据点,这些据点被若干条道路相连接, roads[i] = [x, y] 表示编号 x、y 的两个据点通过一条道路连接。 现在勇者要将按照以下原则将这些据点逐一夺回:

    2023-02-14:魔物了占领若干据点,这些据点被若干条道路相连接, roads[i] = [x, y] 表示编号 x.y 的两个据点通过一条道路连接. 现在勇者要将按照以下原则将这些据点逐一夺回: ...

  3. 2020-10-25:go中channel的close流程是什么?

    福哥答案2020-10-25:

  4. 2020-10-23:go中channel的创建流程是什么?

    福哥答案2020-10-23:1.元素大小是否小于2的16次方,否则throw.2.对齐检查,否则throw.3.元素大小和容量的乘积不能超出范围,否则panic.4.生成*hchan,设置buf.4 ...

  5. 2021-03-10:一个数组上共有 N 个点,序号为0的点是起点位置,序号为N-1 的点是终点位置。现在需要依次的从 0 号点走到 N-1 号点。但是除了 0 号点和 N-1 号点,他可以在其余的 N-2 个位置中选出一个点,并直接将这个点忽略掉,问从起点到终点至少走多少距离?

    2021-03-10:一个数组上共有 N 个点,序号为0的点是起点位置,序号为N-1 的点是终点位置.现在需要依次的从 0 号点走到 N-1 号点.但是除了 0 号点和 N-1 号点,他可以在其余的 ...

  6. 2021-03-08:在一个数组中,任何一个前面的数a,和任何一个后面的数b,如果(a,b)是降序的,就称为逆序对。返回逆序对个数。

    2021-03-08:在一个数组中,任何一个前面的数a,和任何一个后面的数b,如果(a,b)是降序的,就称为逆序对.返回逆序对个数. 福哥答案2021-03-08: 1.归并排序,从右往左,相等拷右. ...

  7. @csrf_exempt

    在Django中对于基于函数的视图我们可以 @csrf_exempt 注解来标识一个视图可以被跨域访问.那么对于基于类的视图,我们应该怎么办呢? 简单来说可以有两种访问来解决 方法一:在类的 disp ...

  8. SpringIOC和SpringAOP

    作为一个Spring使用者条件: 拥有深入的Spring框架知识和开发经验,能够熟练地运用Spring框架来构建复杂的应用程序. 了解Spring框架的核心概念和设计思想,如控制反转(IoC).依赖注 ...

  9. docker-compose单服务器部署ELK

    docker-compose 部署ELK 本项目采用的ELK版本为6.5.3,7.0+ 以上的版本部分配置不适合,请查看docker-compose多服务器部署ELK文章 目录结构 elk |--do ...

  10. Unparseable date: "2019-03-27"

    Unparseable date: "2 public static void main(String[] args) { try { String dateStr="2019-0 ...