温馨提示:这篇文章已超过465天没有更新,请注意相关的内容是否还可用!
摘要:,,Loader和Plugin在软件开发中各有其独特作用。Loader主要负责加载和解析资源,而Plugin则通常用于扩展程序的功能。编写Loader需要关注资源文件的格式和处理流程,确保资源能够被正确加载并转换为应用程序可使用的格式。而编写Plugin则需要考虑与主程序的接口设计和功能扩展点,确保Plugin能够无缝集成并扩展主程序的功能。整体而言,理解资源处理和功能扩展的需求是编写Loader和Plugin的关键思路。
前面两节我们简要介绍了Loader与Plugin的概念,现在我们来详细回顾下它们的区别。
Loader 是文件加载器,主要功能是加载资源文件,并对这些文件进行编译、压缩等处理,最终一起打包到指定的文件中。
Plugin 赋予了 webpack 各种灵活的功能,例如打包优化、资源管理、环境变量注入等,目的是解决 Loader 无法实现的其他任务。
从整个运行时机上来看,Loader 主要运行在打包文件之前,而 Plugins 在整个编译周期都起作用,Webpack在运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过Webpack提供的 API 改变输出结果。
二、编写Loader
在编写 Loader 前,我们需要了解 Loader 的本质。
Loader 本质为一个函数,该函数中的this
作为上下文会被 webpack 填充,我们不能将 Loader 设为一个箭头函数,函数接受一个参数,为 webpack 传递给 Loader 的文件源内容,函数中this
是由 webpack 提供的对象,能够获取当前 Loader 所需的各种信息。
Loader 函数中可能有异步操作或同步操作,异步操作通过this.callback
返回,返回值要求为 string 或者 Buffer。
示例代码如下:
// 导出一个函数,source为webpack传递给loader的文件源内容 module.exports = function(source) { const content = doSomeThing2JsString(source); // 对文件进行某种处理 // loader 配置了 options 对象,那么this.query将指向 options const options = this.query; // 可以用作解析其他模块路径的上下文 console.log('this.context'); /this.callback 参数errorError | null,当 loader 出错时向外抛出一个 errorcontentString | Buffer,经过 loader 编译后需要导出的内容sourceMap为方便调试生成的编译后内容的 source mapast本次编译生成的 AST 静态语法树,之后执行的 loader 可以直接使用这个 AST */ this.callback(null, content); // 异步处理完成后的回调 return content; // 同步返回处理后的内容 }
在编写Loader的过程中,建议保持功能单一,避免一个Loader做多种功能,将LESS文件转换成CSS文件并不是一步到位的,而是通过多个loaders(如less-loader、css-loader、style-loader)的链式调用完成的。
三、编写Plugin
Webpack 基于发布订阅模式,在其运行的生命周期中会广播出许多事件,插件通过监听这些事件,可以在特定的阶段执行自己的任务。
在编写自己的插件时,需要遵循一定的规范:
1、插件必须是一个函数或者是一个包含apply
方法的对象,这样才能访问 compiler 实例。
2、传给每个插件的compiler
和compilation
对象都是同一个引用,因此不建议修改。
3、异步的事件需要在插件处理完任务时调用回调函数通知 Webpack 进入下一个流程,否则会卡住。
实现 Plugin 的模板如下:
class MyPlugin { // Webpack 会调用 MyPlugin 实例的 apply 方法给插件实例传入 compiler 对象 apply (compiler) { // 找到合适的事件钩子,实现自己的插件功能 compiler.hooks.emit.tap('MyPlugin', compilation => { // compilation: 当前打包构建流程的上下文 console.log(compilation); // 在这里实现你的插件功能... }) } }
在emit
事件发生时,代表源文件的转换和组装已经完成,此时可以读取到最终将输出的资源、代码块、模块及其依赖,并且可以修改输出资源的内容。
还没有评论,来说两句吧...