面试必备!十分钟搞懂 Webpack Loader 和 Plugin 开发,快速拿下大厂 Offer!

开发 前端
如果要讲解 plugin 和 loader 那么会涉及到三个术语:module、chunk、bundle。所以咱们就先说明下 module、chunk、bundle 然后再来看下 plugin 和 loader。

Hello,大家好,我是 Sunday。

在前两天同学的面试中,有一位同学被问到 如何开发 webpack 的 loader 和 plugin?有没有实际 loader 或者 plugin 的开发经验。果然,面试只会越来越卷啊。

webpack 是大家所熟知的打包工具,里面包含了 5 个核心概念:

  1. 入口:entry
  2. 出口:output
  3. 加载器:loader
  4. 插件:plugin
  5. 模式:mode

图片图片

入口、出口、模式 的概念其实都比较好理解。但是一旦涉及到 loader 和 plugin,特别是实现 loader 和 plugin 很多小伙伴就比较懵了。

所以,今天咱们就拿出 10 分钟的时间,一起来看那看那 loader 和 plugin 是如何实现的!

module、chunk、bundle

如果要讲解 plugin 和 loader 那么会涉及到三个术语:module、chunk、bundle。

所以咱们就先说明下 module、chunk、bundle 然后再来看下 plugin 和 loader。

在打包工具中,有三个 “术语”:module、chunk、bundle:

  1. module:模块:通常一个模块代表了一个文件。一般指的是 js 文件,当然也可以是 css 文件 或者 图像文件。
  2. chunk:块:块通常是在构建过程中由打包工具(如: Webpack)根据配置生成的,它们由一组相关的模块放在一起打包组成。
  3. bundle:打包文件:打包文件是指构建工具在打包过程中生成的最终输出文件,可以在浏览器中加载并运行。

总的来说:模块是组成项目的一个个文件,块是由一组相关模块组成的单元,而打包文件是构建工具最终生成的包含模块和资源的输出文件。

实现 loader 和 plguin

那么明确好了这三个基本的概念之后,接下来咱们来看下 loader 和 plugin:

loader 一般被称为 加载器, webpack 默认只能处理 .js 的文件。如果项目中遇到其他类型的文件,那么就需要通过 loader 进行处理。

plugin 一般被叫做 插件,它可以为 构建工具(不只是 webpack,还包含 vite 或者 rollup) 提供一些附加的功能。比如说,咱们上一小节用到了 HtmlWebpackPlugin 它就是一个典型的插件,它可以在 webpack 构建的过程中生成一个新的 HTML 文件。并且自动生成新的 bundle 文件。

明确好了它们的基本概念之后,接下来咱们来看下它们 运行时机 的区别,咱们来看下面这张图:

图片图片

从图中咱们可以看到:

  1. loader 是在打包之前执行的,执行的时机比较固定。其实也很好理解嘛。loader 它实质就是一个转换器,将 A 文件进行编译形成 B 文件,操作的是文件,比如:将A.scss 转变为B.css,单纯的文件转换过程。
  2. 而 plugin 是在整个编译的周期中都会起作用。webpack 在整个运行的生命周期中,会广播出很多的事件,plugin 就可以监听这些事件,然后在某一个时机下,改变输出结果就可以了。

那么明确好了它们的一个运行机制之后,接下来咱们来实现一个简单的 loader 和 plugin:

loader 的简单实现

需求:

实现一个 loader 处理 txt 文件,把 hello world 转化为 配置对象下 content 属性的值

  1. 在 webpack-project/vue.config.js 中利用 chainWebpack 添加新的 loader:
// 添加一个处理 txt 文件的loader
config.module
// 创建一个新的规则,命名为 'custom-loader'
.rule('txt-loader')
// 适用于哪些文件
.test(/\.txt$/)
// 指定要使用的 loader 的名称
.use('txt-loader')
// loader 的路径
.loader('./src/loaders/textLoader')
// 配置对象
.options({
    content: '你好,世界'
})
.end()
  1. 然后创建 test.txt 文件:
hello world
  1. 实现 textLoader :
const loaderUtils = require('loader-utils')
// 接收options配置
module.exports = function (source) {
// 获取配置文件
const options = loaderUtils.getOptions(this)
// 把 hello world 替换成 content 属性配置
source = source.replace(/hello world/, options.content)
// 最后需要返回一个可执行的代码,所以需要 module.exports = '内容'
return `module.exports = '${source}'`
}
  1. 最后在 main.js 中导入该文件,并打印:
const text = require('./test.txt')
console.log(text)

plugin 的简单实现

看完 loader 之后,接下来咱们来看一个 plugin 的构建。

需求:

在 webpack 打印完成之后,在终端输出指定内容

  1. 创建 webpack-project/src/plugins/logPlugin.js 文件:
class LogPlugin {
// 通过构造函数,获取到传入的内容 content
constructor(options) {
    this.content = options.content
}

// Webpack 会调用 logPlugin 实例的 apply 方法给插件实例传入 compiler 对象。compiler 表示编译器的实例,它代表了完整的 webpack 环境配置
apply(compiler) {
    // 指定一个挂载到 webpack 自身的事件钩子。done 会在 webpack 构建完成后回调
    compiler.hooks.done.tap('logPlugin', (compilation) => {
        // compilation: 当前打包构建流程的上下文
        console.log(this.content)
    })
}
}

module.exports = LogPlugin
  1. 在 vue.config.js 中,添加 plugin:
// 添加一个新的 plugin
// 添加一个新的插件
config
.plugin('LogPlugin')
.use(LogPlugin, [{ content: 'hello sunday' }])
.end()

此时,运行项目可在终端打印指定内容。

webpack 在官网中提供了 如何构建 loader 和 如何构建 plugin 的文档,大家如果想要深入了解它们的构建方式的话,那么可以查询下对应的文档内容。

责任编辑:武晓燕 来源: 程序员Sunday
相关推荐

2019-09-16 09:14:51

2021-09-07 09:40:20

Spark大数据引擎

2012-07-10 01:22:32

PythonPython教程

2024-11-07 16:09:53

2024-01-29 00:20:00

GolangGo代码

2022-04-13 22:01:44

错误监控系统

2009-04-29 17:35:47

LinuxWebMail系统

2020-12-17 06:48:21

SQLkafkaMySQL

2023-10-27 09:40:52

VitePressGatsby

2019-04-01 14:59:56

负载均衡服务器网络

2022-03-04 16:06:33

数据库HarmonyOS鸿蒙

2022-06-16 07:31:41

Web组件封装HTML 标签

2024-06-19 09:58:29

2023-04-12 11:18:51

甘特图前端

2022-03-23 09:32:38

微服务容器Kubernetes

2024-05-13 09:28:43

Flink SQL大数据

2023-11-30 10:21:48

虚拟列表虚拟列表工具库

2015-09-06 09:22:24

框架搭建快速高效app

2024-03-04 15:19:52

Python编程内建函数

2009-10-09 14:45:29

VB程序
点赞
收藏

51CTO技术栈公众号