webpack 插件机制分析及开发调试

这篇具有很好参考价值的文章主要介绍了webpack 插件机制分析及开发调试。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

webpack插件机制

插件概念

Webpakck插件的基本模型

apply方法的由来

入参Compiler对象解释

区分Compilation 对象

Tapable & Tapable 实例

Plugin调用流程

开发调试Plugin&Loader


webpack插件机制

        webpack 插件机制是整个 webpack 工具的骨架,而 webpack 本身也是利用这套插件机制构建出来的。

插件概念

        专注处理 webpack 在编译过程中某个特定任务的功能模块,可以称为插件。最常见的如 html-webpack-plugin 。

        那么怎么样的一个东西可以称之为 webpack 插件呢?一个完整的 webpack 插件需要满足以下几点规则和特征:

  • ·是一个独立的模块。

  • ·模块对外暴露一个 js 函数。

  • ·函数的原型 (prototype) 上定义了一个注入 compiler 对象的 apply 方法。

  • ·apply 函数中需要有通过 compiler 对象挂载的 webpack 事件钩子,钩子的回调中能拿到当前编译的 compilation 对象,如果是异步编译插件的话可以拿到回调 callback。

  • ·完成自定义子编译流程并处理 complition 对象的内部数据。

  • ·如果异步编译插件的话,数据处理完成后执行 callback 回调。

Webpakck插件的基本模型

    // 1、BasicPlugin.js 文件(独立模块)
    // 2、模块对外暴露的 js 函数
    class BasicPlugin{
        //在构造函数中获取用户为该插件传入的配置
        constructor(pluginOptions) {
            this.options = pluginOptions;
        }
        //3、原型定义一个 apply 函数,并注入了 compiler 对象
        apply(compiler) {
            //4、挂载 webpack 事件钩子(这里挂载的是 emit 事件)
            compiler.plugin('emit', function (compilation, callback) {
                // ... 内部进行自定义的编译操作
                // 5、操作 compilation 对象的内部数据
                console.log(compilation);
                // 6、执行 callback 回调
                callback();
            });
        }
    }
    // 7、暴露 js 函数
    module.exports = BasicPlugin;

apply方法的由来

因为webpack中调用插件的方式就是plugin.apply()。

webpack部分源码:

https://github.com/webpack/webpack/blob/10282ea20648b465caec6448849f24fc34e1ba3e/lib/webpack.js#L35

    const webpack = (options, callback) => {
        ...
        for (const plugin of options.plugins) {
            plugin.apply(compiler);
        }
        ...
    }

入参Compiler对象解释

        compiler 对象是 webpack 的编译器对象,compiler 对象会在启动 webpack 的时候被一次性的初始化,compiler 对象中包含了所有 webpack 可自定义操作的配置,例如 loader 的配置,plugin 的配置,entry 的配置等各种原始 webpack 配置等。

        在 webpack 插件中的自定义子编译流程中,我们肯定会用到 compiler 对象中的相关配置信息,我们相当于可以通过 compiler 对象拿到 webpack 的主环境所有的信息。

webpack部分源码:

https://github.com/webpack/webpack/blob/10282ea20648b465caec6448849f24fc34e1ba3e/lib/webpack.js#L30

    // webpack/lib/webpack.js
    const Compiler = require("./Compiler")  
  
    const webpack = (options, callback) => {
        ...
        // 初始化 webpack 各配置参数
        options = new WebpackOptionsDefaulter().process(options) 

        // 初始化 compiler 对象,这里 options.context 为 process.cwd()
        let compiler = new Compiler(options.context)     

        // 往 compiler 添加初始化参数
        compiler.options = options         

        // 往 compiler 添加 Node 环境相关方法             
        new NodeEnvironmentPlugin().apply(compiler)

        for (const plugin of options.plugins) {
            plugin.apply(compiler);
        }
        ...
    }

区分Compilation 对象

        compilation 实例继承于 compiler,compilation 对象代表了一次 单一版本 webpack 构建和生成编译资源

        (编译资源是 webpack 通过配置生成的一份静态资源管理 Map(一切都在内存中保存),以 key-value 的形式描述一个 webpack 打包后的文件。编译资源就是这一个个 key-value 组成的 Map)

        的过程。

        当运行 webpack 开发环境中间件时,每当检测到一个文件变化,一次新的编译将被创建,从而生成一组新的编译资源以及新的 compilation 对象。

        一个 compilation 对象包含了 当前的模块资源、编译生成资源、变化的文件、以及 被跟踪依赖的状态信息。编译对象也提供了很多关键点回调 供插件做自定义处理时选择使用。

        Compiler 和 Compilation 的区别在于:Compiler 代表了整个 Webpack 从启动到关闭的生命周期,而 Compilation 只代表一次新的编译。

Tapable & Tapable 实例

        webpack 的插件架构主要基于 Tapable 实现的,Tapable 是 webpack 项目组的一个内部库,主要是抽象了一套插件机制。

        webpack 源代码中的一些 Tapable 实例都继承或混合了 Tapable 类。Tapable 能够让我们为 javaScript 模块添加并应用插件。它可以被其它模块继承或混合。它类似于 NodeJS 的 EventEmitter 类,专注于自定义事件的触发和操作。除此之外, Tapable 允许你通过回调函数的参数访问事件的生产者。

        简单来说,就是我们熟悉的发布-订阅模式。这里暂不详细讲了,有点偏题~感兴趣的可以自行查找资料~

Plugin调用流程

1. 注册,类似于 EventEmitter 的 on

对应源码:

https://github.com/webpack/tapable/blob/42b520760e138c23e7808881cb4322557e878307/lib/Tapable.js#L35

    compiler.plugin('emit', (compilation, callback) => {
       // 在生成资源并输出到目录之前完成某些逻辑
    })

    // Tapable.js
    options => {
        ...
        if(hook !== undefined) {
            const tapOpt = {
                name: options.fn.name || "unnamed compat plugin",
                stage: options.stage || 0
            };
            if(options.async)
                // 将插件中 异步钩子的回调函数 注入
                hook.tapAsync(tapOpt, options.fn);
            else
                hook.tap(tapOpt, options.fn);
            return true;
        }
    };

2. 执行,类似于 EventEmitter 的emit

对应源码:

https://github.com/webpack/webpack/blob/e7c8fa414b718ac98d94a96e2553faceabfbc92f/lib/Compiler.js#L307

  this.hooks.emit.callAsync(compilation, err => {
      if (err) return callback(err);
      outputPath = compilation.getPath(this.outputPath);
      this.outputFileSystem.mkdirp(outputPath, emitFiles);
  });

开发调试Plugin&Loader

npm link

适合场景:Plugin&Loader

        Npm link 专门用于开发和调试本地的 Npm 模块,能做到在不发布模块的情况下, 将本地的一个正在开发的模块的源码链接到项目的 node_modules 目录下,让项目可以直接使 用本地的 Npm 模块。由于是通过软链接的方式实现的,编辑了本地的 Npm 模块的代码,所以在项目中也能使用到编辑后的代码。

  1. 确保正在开发的本地 Loader 模块的 package.json 已经配置好(最主要的main字段的入口文件指向要正确)

  2. 在本地的 Npm 模块根目录下执行 npm link,将本地模块注册到全局

  3. 在项目根目录下执行 npm link loader-name ,将第 2 步注册到全局的本地 Npm 模块链接到项目的 node moduels 下,其中的 loader-name 是指在第 1 步的package.json 文件中配置的模块名称

Resolveloader

适合场景:loader

        ResolveLoader 用于配置 Webpack 如何寻找 Loader ,它在默认情况下只会去 node_modules 目录下寻找。为了让 Webpack 加载放在本地项目中的 Loader, 需要修改 resolveLoader.modules。文章来源地址https://www.toymoban.com/news/detail-600646.html

    //假设本地项目中的 Loader 在项目目录的 ./loaders/loader-name 下
    module.exports = {
        resolveLoader:{
            //去哪些目录下寻找 Loader ,有先后顺序之分
            modules :['node modules','./loaders/'],
        }
    }

到了这里,关于webpack 插件机制分析及开发调试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端10年进化 Node.js、模块化、CommonJS、AMD、CMD、Webpack、Vue-cli、Electron-vue

    模块化的概念在软件开发领域已经存在很长时间,但在 JavaScript 中的模块化发展相对较晚。以下是对您提出的问题的回答: 提出时间:JavaScript 中的模块化概念相对较早地提出于 CommonJS 规范。CommonJS 是一种 JavaScript 模块化规范,最早在 2009 年由 Ryan Dahl 和其他社区成

    2024年02月11日
    浏览(78)
  • AWS 中文入门开发教学 45- Cloud9 - Node.js的开发与调试

    在 Cloud9 环境中开发调试 Node.js 应用程序 cloud9还提供了一个非常好用的debug工具:

    2024年02月16日
    浏览(63)
  • 前端开发调试技巧:如何在Component下选中当前插件并且查看当前插件信息

    在react开发项目中,在Component下选中组件,然后在控制台输$r 按回车键即可输出该组件信息。例如 $r.props输出该组件的props参数。例子详情见如下截图

    2024年02月07日
    浏览(53)
  • Node.js 开发常用到的库和插件工具,同事看到后也悄悄收藏了……

    Node.js是一个功能强大,并且非常流行的 JavaScript 运行时环境,使开发人员能够高效率的构建高性能应用程序。下面介绍了8个常见的应用程序开发中用到的库和函数,可以用于缓存数据、操作日期、处理图像、发送电子邮件、发出 HTTP 请求、记录请求和响应、压缩数据和哈希

    2024年02月09日
    浏览(45)
  • Node.js与Webpack笔记(二)

    上一篇:Node.js与Webpack笔记(一)-CSDN博客 1.Webpack简介以及体验 webpack是一个静态模块打包工具,从入口构建依赖图,打包有关的模块,最后用于展示你的内容 静态模块:编写代码过程中,html,css,js,图片等固定内容的文件 打包过程,注意:只有和入口有直接/间接引入关系

    2024年03月10日
    浏览(82)
  • 前端jd要求:了解一门后端开发语言优先 解决方案之Node.js

    作为前端开发者,了解一门后端开发语言可以为我们提供更多的职业机会和技术优势。在当今的技术领域中,前后端分离的开发模式已经成为主流,前端和后端的协作和沟通变得越来越紧密。因此,作为前端开发者,学习一门后端语言已经成为提高自己技能的重要途径。 以下

    2024年02月12日
    浏览(49)
  • 第三节:Node.js 之 Webpack 打包

    官网网址:https://webpack.docschina.org/ 减少文件数量,缩减代码体积,提高浏览器打开速度。 用于分析、并打包代码。支持所有类型文件的打包,其本质是一个第三方模块包。 初始化包环境 安装依赖包 配置package.json 的 scripts(自定义命令) 在根目录下新建 src 文件夹, 所有要

    2024年02月15日
    浏览(52)
  • Node.js入门与 Webpack模块打包工具

    目录 Node.js入门 fs模块-读写文件 path模块-路径处理  压缩前端html 认识URL中的端口号 http模块-创建Web服务 体验 Web 服务除了接口数据以外,还能返回网页资源等  Node.js模块化  ECMAScript标准-默认导出和导入 ECMAScript标准-命名导出和导入  包的概念 npm软件包管理器 npm安装所有依

    2024年02月11日
    浏览(44)
  • Node.JS学习 | Babel | webpack | ES6

    💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! Node.JS能够在服务器端运行JavaScript的开放源代码、跨平台运行环境;Node.js采用Google开发的V8运行代码,使用事件驱动、非阻塞IO和异步输入输出模型等技术来提高性能,可优化应用程序的传输量和规模 let有效避免var的变

    2024年02月07日
    浏览(42)
  • 安全开发-JS应用&原生开发&JQuery库&Ajax技术&加密编码库&断点调试&逆向分析&元素属性操作

    1、布置前端页面 2、JS获取提交数据 3、JS对上传格式判断 4、后端对上传数据处理 前端JS进行后缀过滤,后端PHP进行上传处理 架构:html js php - upload.php 安全问题: 1、过滤代码能看到分析绕过 2、禁用JS或删除过滤代码绕过 前端白名单很轻易就能绕过 0、布置前端页面 1、获取

    2024年02月12日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包