手写Webpack-Plugin

这篇具有很好参考价值的文章主要介绍了手写Webpack-Plugin。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Plugin原理

一、Plugin作用

通过插件我们可以扩展webpack,使webpack可以执行更广泛的任务,拥有更强的构建能力。

Plugin工作原理

webpack 就像一条生产线,要经过一系列处理流程后才能将源文件转换成输出结果。 这条生产线上的每个处理流程的职责都是单一的,多个流程之间有存在依赖关系,只有完成当前处理后才能交给下一个流程去处理。 插件就像是一个插入到生产线中的一个功能,在特定的时机对生产线上的资源做处理。webpack 通过 Tapable 来组织这条复杂的生产线。 webpack 在运行过程中会广播事件,插件只需要监听它所关心的事件,就能加入到这条生产线中,去改变生产线的运作。 webpack 的事件流机制保证了插件的有序性,使得整个系统扩展性很好。 ——「深入浅出 Webpack」

站在代码逻辑的角度就是:webpack在编译过程中,会触发一些列 Tapable钩子事件,插件所做的就是找到相应的钩子,往上面挂载自己的任务,也就是注册事件,这样,当webpack执行到相关的钩子函数时就会触发我们挂载的任务事件。

Webpack内部钩子

Tapable

Tapable 为 webpack 提供了统一的插件接口(钩子)类型定义,它是 webpack 的核心功能库。webpack 中目前有十种 hooks,在 Tapable 源码中可以看到,他们是:

// https://github.com/webpack/tapable/blob/master/lib/index.js
exports.SyncHook = require("./SyncHook");
exports.SyncBailHook = require("./SyncBailHook");
exports.SyncWaterfallHook = require("./SyncWaterfallHook");
exports.SyncLoopHook = require("./SyncLoopHook");
exports.AsyncParallelHook = require("./AsyncParallelHook");
exports.AsyncParallelBailHook = require("./AsyncParallelBailHook");
exports.AsyncSeriesHook = require("./AsyncSeriesHook");
exports.AsyncSeriesBailHook = require("./AsyncSeriesBailHook");
exports.AsyncSeriesLoopHook = require("./AsyncSeriesLoopHook");
exports.AsyncSeriesWaterfallHook = require("./AsyncSeriesWaterfallHook");
exports.HookMap = require("./HookMap");
exports.MultiHook = require("./MultiHook");

Tapable 还统一暴露了三个方法给插件,用于注入不同类型的自定义构建行为:

  • tap:可以注册同步异步钩子
  • tapAsync:回调方式注册异步钩子
  • tapPromise:Promise方式注册异步钩子

Plugin构建对象

Compiler

compiler 对象中保存着完整的 Webpack 环境配置,每次启动 webpack 构建时它都是一个独一无二,仅仅会创建一次的对象。

这个对象会在首次启动 Webpack 时创建,我们可以通过 compiler 对象上访问到 Webapck 的主环境配置,比如 loader 、 plugin 等等配置信息。
它有以下主要属性:

  • compiler.options 可以访问本次启动 webpack 时候所有的配置文件,包括但不限于 loaders 、 entry 、 output 、 plugin 等等完整配置信息。
  • compiler.inputFileSystem 和 compiler.outputFileSystem 可以进行文件操作,相当于 Nodejs 中 fs。
  • compiler.hooks 可以注册 tapable 的不同种类 Hook,从而可以在 compiler 生命周期中植入不同的逻辑。

Compilation

compilation 对象代表一次资源的构建,compilation 实例能够访问所有的模块和它们的依赖。
一个 compilation 对象会对构建依赖图中所有模块,进行编译。 在编译阶段,模块会被加载(load)、封存(seal)、优化(optimize)、 分块(chunk)、哈希(hash)和重新创建(restore)。
它有以下主要属性:

  • compilation.modules 可以访问所有模块,打包的每一个文件都是一个模块。
  • compilation.chunks chunk 即是多个 modules 组成而来的一个代码块。入口文件引入的资源组成一个 chunk,通过代码分割的模块又是另外的 chunk。
  • compilation.assets 可以访问本次打包生成所有文件的结果。
  • compilation.hooks 可以注册 tapable 的不同种类 Hook,用于在 compilation 编译模块阶段进行逻辑添加以及修改。
    手写Webpack-Plugin,webpack,前端,node.js

开发一个Plugin插件

一个简单的插件构成

class TestPlugin {
  constructor() {
    console.log("TestPlugin constructor()");
  }
  // 1. webpack读取配置时,new TestPlugin() ,会执行插件 constructor 方法
  // 2. webpack创建 compiler 对象
  // 3. 遍历所有插件,调用插件的 apply 方法
  apply(compiler) {
    console.log("TestPlugin apply()");
  }
}

module.exports = TestPlugin;

手动实现生成文件大小分析文件插件

// plugins/analyze-webpack-plugin.js
class AnalyzeWebpackPlugin {
  apply(compiler) {
    // emit是异步串行钩子
    compiler.hooks.emit.tap("AnalyzeWebpackPlugin", (compilation) => {
      // Object.entries将对象变成二维数组。二维数组中第一项值是key,第二项值是value
      const assets = Object.entries(compilation.assets);

      let source = "# 分析打包资源大小 \n| 名称 | 大小 |\n| --- | --- |";

      assets.forEach(([filename, file]) => {
        source += `\n| ${filename} | ${file.size()} |`;
      });

      // 添加资源
      compilation.assets["analyze.md"] = {
        source() {
          return source;
        },
        size() {
          return source.length;
        },
      };
    });
  }
}

module.exports = AnalyzeWebpackPlugin;

在webpack.config.js中配置文章来源地址https://www.toymoban.com/news/detail-810127.html

const AnalyzeWebpackPlugin = require("./plugins/analyze-webpack-plugin");
//...省略
   plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, 'public/index.html')
        }),
        new AnalyzeWebpackPlugin()
    ],

到了这里,关于手写Webpack-Plugin的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索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)
  • Node.js与Webpack笔记(二)

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

    2024年03月10日
    浏览(82)
  • 第三节: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)
  • improve-gzip引入后node_modules中.cache compression-webpack-plugin占用内存过多

    1.Gzip Gzip(GNU zip)是一种常见的文件压缩格式和压缩算法,通常用于在 Web 服务器上对静态资源文件进行压缩,以减小文件大小并加快文件传输速度。在前端开发中,经常会使用 Gzip 压缩来优化网站的性能。 Gzip 压缩通过移除文件中的重复数据和不必要的信息来减小文件大小

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

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

    2024年02月07日
    浏览(41)
  • node.js下载安装和报错大全(express、淘宝镜像、webpack、Vue)

    目录 一、概述 二、操作步骤 (一)下载node.js (二) 安装node.js (三)查看环境变量 (四)查看版本信息 (五)新建全局下载包和缓存包位置 (六)配置环境变量 (七)安装express(内嵌http模块) 安装成功 安装失败 解决办法一(最好的办法)  解决办法二(其次) (八

    2024年02月01日
    浏览(75)
  • node.js的下载安装详细步骤(还有安装配套的express、淘宝镜像、webpack、Vue)

    目录 一、概述 二、操作步骤 (一)下载node.js (二) 安装node.js (三)查看环境变量 (四)查看版本信息 (五)新建全局下载包和缓存包位置 (六)配置环境变量 (七)安装express(内嵌http模块) 安装成功 安装失败 解决办法一(最好的办法)  解决办法二(其次) (八

    2024年02月09日
    浏览(72)
  • Webpack:HTML Webpack Plugin插件

            HTML Webpack Plugin 插件,在Webpack构建的前端项目中,用于简化index.html文件的创建,以免除项目打包之后手动创建/拷贝index.html到打包目录下的繁琐步骤。以下,从一个已构建好的Vue项目中的一个现象谈起,逐步深入了解此插件的使用。 目录 从Vue项目中的index.html谈起

    2024年02月07日
    浏览(39)
  • vue前端页面弹出红色报错遮罩层 Uncaught runtime errors:at handleError (webpack-internal:///./node_modules/webpack

    报错信息: 原因: 当出现编译错误或警告时,在浏览器中显示全屏覆盖。 解决方法: 在vue.config.js中添加如下配置, 重启项目 即可 https://webpack.docschina.org/configuration/dev-server/#overlay

    2024年02月05日
    浏览(59)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包