05-手动实现一个Loader和Plugin

Loader文件结构

项目github地址:https://github.com/Trade-Offf/LoaderAndPlugin

上图为markdown Loader的文件结构:

  • dist是打包后的内容;
  • node_modules是文件依赖,git clone 项目之后记得 npm i 安装依赖;
  • src是核心功能,里面有一个.md文件,一个js文件。js负责console .md文件;


    直接在JS里不能输出.md文件

    但在node环境下不能通过js直接输出.md文件,所以要经过处理,
    方法一:JS内部处理


    JS内部处理

方法二:写个Loader加载器


Webpack 加载资源文件的过程类似于一个工作管道,你可以在这个过程中依次使用多个 Loader,但是最终这个管道结束过后的结果必须是一段标准的 JS 代码字符串。

所以我们还可以用多个Loader进行处理:
markdown-loader2 中直接返回 HTML 字符串,再安装一个处理 HTML 的 Loader,叫作 html-loader。在webpack.config.js里把module的 use 属性修改为一个数组,以便依次使用多个 Loader。

P.S. 此时注意执行顺序是从后往前,所以要先返回HTML,再处理HTML;


以上,我们用两种方式,实现了一个markdown Loader;


相比于 Loader,插件的能力范围更宽,因为 Loader 只是在模块的加载环节工作,而插件的作用范围几乎可以触及 Webpack 工作的每一个环节。

那么插件机制如何实现呢?很简单,类似软件开发中的钩子机制;

在Webpack整个工作过程中会有很多环节,每个环节都埋下了钩子,在开发时不同节点挂载不同任务,即可实现扩展Webpack的能力;

接下来我想开发一个自动清除Webpack打包结果中的注释,让bundle.js更易读;

image.png

Webpack 要求我们的插件必须是一个函数或者是一个包含 apply 方法的对象,一般我们都会定义一个类,在这个类中定义 apply 方法。然后在使用时,再通过这个类来创建一个实例对象去使用这个插件。

所以我们这里定义一个 RemoveCommentsPlugin 类型,然后在这个类型中定义一个 apply 方法,这个方法会在 Webpack 启动时被调用,它接收一个 compiler 对象参数,这个对象是 Webpack 工作过程中最核心的对象,里面包含了我们此次构建的所有配置信息,我们就是通过这个对象去注册钩子函数

image.png

做完这些,我们还需要知道把任务挂载到哪个钩子上

我们的需求是删除 bundle.js 中的注释,也就是说只有当 Webpack 需要生成的 bundle.js 文件内容明确过后才可能实施。

image.png

那根据 API 文档中的介绍,我们找到一个叫作 emit 的钩子,这个钩子会在 Webpack 即将向输出目录输出文件时执行,非常符合我们的需求。

打印出文件名称bundle.js

我们回到代码中,通过 compiler 对象的 hooks 属性访问到 emit 钩子,再通过 tap 方法注册一个钩子函数,这个方法接收两个参数:

  • 第一个是插件的名称,我们这里的插件名称是 RemoveCommentsPlugin;

  • 第二个是要挂载到这个钩子上的函数;

根据 API 文档中的提示,这里我们在这个函数中接收一个 compilation 对象参数,这个对象可以理解为此次运行打包的上下文,所有打包过程中产生的结果,都会放到这个对象中。

我们可以使用这个对象中的 assets 属性获取即将写入输出目录的资源文件信息,它是一个对象,我们这里通过 for in 去遍历这个对象,其中键就是每个文件的名称,我们尝试把它打印出来;

能够拿到文件名后,我们回到代码中。这里需要先判断文件名是不是以 .js 结尾,因为 Webpack 打包还有可能输出别的文件,而我们的需求只需要处理 JS 文件。

那如果是 JS 文件,我们将文件内容得到,再通过正则替换的方式移除掉代码中的注释,最后覆盖掉 compilation.assets 中对应的对象,在覆盖的对象中,我们同样暴露一个 source 方法用来返回新的内容。另外还需要再暴露一个 size 方法,用来返回内容大小,这是 Webpack 内部要求的格式,具体代码如下:

此时的bundle.js文件如图,实现需求:


bundle.js打包后无注释文件

以上就是我们实现一个移除注释插件的过程,通过这个过程我们了解了:插件都是通过往 Webpack 生命周期的钩子中挂载任务函数实现的。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容