资讯专栏INFORMATION COLUMN

浅谈webpack之plugin,webpack-manifest-plugin源码解读

william / 3898人阅读

摘要:注册方法之后,当执行了当前的,那么挂载正在当前上的方法就会被执行。比如在开始编译之前,就能触发钩子,就用到了当前的。上面都是前置知识,下面通过解读一个源码来巩固下。先看一段简单的源码。,是众多的的一个,官网的解释是编译创建之后,执行插件。

通过解读webpack-manifest-plugin,了解下plugin机制

先简单说一下这个插件的功能,生成一份资源清单的json文件,如下


如果是服务器端构造的html,就可以根据当前的manifest,引入css和js文件,而且这个文件是必须的,否则服务器端压根不知道hash之后的JS文件名字和CSS名字。

简单说下webpack执行,取得webpack.config.js的配置和默认配置合并,然后执行plugin,这里的执行其实只是简单的绑定hooks,并非执行里面的逻辑,先看下源代码,再给大家撸一撸这里面的细节。

compiler实例会作为参数传递,可以看到new 之后,他就立刻去遍历的plugin,然后plugin.apply(compiler)去执行了当前的plugin。难道说
plugin在这里就执行了?说对也不对,看一段最简单的plugin的demo

 apply(compiler) {
    compiler.hooks.compilation.tap("xxx", (compilation) => {
     do something
    });
  }

官网的demo,用的compiler.plugin,但这个方法已经不推荐使用了,用hooks代替,更语义化一点。
看上面的代码,apply执行后,其实只是在对应的hooks上注册了一个方法而已,xxx可以理解为一个plugin的标识。注册方法之后,当webpack执行了当前的hooks,那么挂载正在当前hooks上的方法就会被执行。
这个有点类似于发布订阅模式了
综上所述,webpack在 compiler被创建的之后,立刻就去遍历了plugin,就是想要尽早的注册方法,否则挂载在一些hooks上的方法就没办法被正确触发。比如

在webpack开始编译之前,就能触发beforeRun钩子,webpack-manifest-plugin就用到了当前的hook。因此虽然plugin注册的早,但真正的执行顺序在于它绑定的到底是什么样的钩子。无关于它在webpack配置中plugin里面的顺序。

上面都是前置知识,下面通过解读一个plugin源码来巩固下。

先看一段简单的源码。
这里他注册了好几个钩子,我们一个一个来说。
compiler.hooks.webpackManifestPluginAfterEmit = new SyncWaterfallHook(["manifest"]); 这里是自定义一个hooks,webpack允许自定义hooks,这个hooks是干嘛的,这是给其他组件用的,意思就是,我注册了一个这样的hooks,其他组件就能通过tap绑定对应的方法,仅此而已。

 compiler.hooks.compilation.tap(pluginOptions, function (compilation) {
      compilation.hooks.moduleAsset.tap(pluginOptions, moduleAsset);
    });

hooks.compilation,compilations是compiler众多的hooks的一个,官网的解释是:编译(compilation)创建之后,执行插件。简单的可以理解为某段编译过程(一个文件或者一个chunk),一次webpack,会触发多次的compilation, 而compilation下面又有N多的hooks,具体有哪些可以看官网,这里的moduleAsset,官网的解释是:一个模块中的一个资源被添加到编译中。比如图片资源。
moduleAsset回调函数接收到了两个参数,一个是filename,就是hash后的图片名字,将filename,保存到一个全局对象中。但这里的资源并不包括JS,CSS,需要在其他的hooks中处理。

compiler.hooks.emit.tap(pluginOptions, emit);

emit的钩子官网解释是:生成资源到 output 目录之前。 说白了就是把构建好的JS和CSS文件写入到dist目录之前触发的hooks。
同样的emit函数里面能够拿到 compilation。 compilation.chunks是一个数组,代表着每一个chunk,通常是entry里面定义的文件,以及通过splitChunks,拆开的chunk。chunk里面能拿到一个files字段,里面存到就是生成的css和js名字。

compiler.hooks.emit.tap("xxx", (compilation) => {
      compilation.chunks.forEach((chunk) => {
        console.log(chunk.files);
      });
    });

到这里webpack-manifest-plugin的主功能就差不多了,将上面得到的各种hash后的name保存到对象里面,key就是chunk名(不一定准),但key具体是什么不重要,到时候服务器端遍历json的时候,判断value的后缀即可,到底是js,css或者其他什么的一目了然。
webpack-manifest-plugin还有一些细节处理,比如取到了publicPath,结合拿到的fileName,组成了文件的真正地址。

plugin其实还可以展开很多内容讲,但官网都有,很多时候也不用我们去写plugin,网上大把,我们只需要知道,他的基本原理即可。
hooks,订阅发布等。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102889.html

相关文章

  • 傻傻分不清的Manifest

    摘要:的英文含义是名单种技术的确都是把当做清单使用缓存清单清单打包资源路径清单打包清单只不过是在不同的场景中使用特定的清单来完成某些功能所以,学好英文是多么重要,这样才不会傻傻分不清到底是干啥的 在前端,说到manifest,其实是有歧义的,就我了解的情况来说,manifest可以指代下列含义: html标签的manifest属性: 离线缓存(目前已被废弃) PWA: 将Web应用程序...

    printempw 评论0 收藏0
  • webpack4详细教程,从无到有搭建react脚手架(四)

    摘要:相关链接详细教程,从无到有搭建脚手架一详细教程,从无到有搭建脚手架二详细教程,从无到有搭建脚手架三管理打包后目录结构打包结构如下修改配置通过相对目录对资源命名前加上目录名,效果后面的步骤在这里需要安装一个大型的包,以为例安装为第三 相关链接 webpack4详细教程,从无到有搭建react脚手架(一) webpack4详细教程,从无到有搭建react脚手架(二) webpack4详细...

    chnmagnus 评论0 收藏0
  • Webpack中hash的用法

    摘要:在的配置项中,可能会见到这样的字符。的情况的可以指定。值是特定于整个构建过程的。。因此,以上两个值中更推荐的是。中的则和前面的一样,指定了结果的截取长度。的情况被引用的通过来得到带的文件。所以,这可能并不是我们想要的。 在webpack的配置项中,可能会见到hash这样的字符。 当存在hash配置的时候,webpack的输出将可以得到形如这样的文件: page1_bundle_54e8...

    苏丹 评论0 收藏0
  • 基于webpack构建的angular 1.x 工程(一)webpack

    摘要:基于构建的工程一篇现在都已经出到的版本了,可我对它的认识还是停留在的版本。然后是写启动的命令行,也就是上面的这样写的意思是,当你输入你的命令名字就会让执行你对应命令的语句。我们首先把基本的配置引进来。 基于webpack构建的angular 1.x 工程(一)webpack篇   现在AngularJS都已经出到4.x的版本了,可我对它的认识还是停留在1.x的版本。   之前用它是为...

    Anleb 评论0 收藏0
  • 浅谈webpack4.0 性能优化

    摘要:中在性能优化所做的努力,也大抵围绕着这两个大方向展开。因此,将依赖模块从业务代码中分离是性能优化重要的一环。大型库是否可以通过定制功能的方式减少体积。这又违背了性能优化的基础。接下来可以抓住一些细节做更细的优化。中,为默认启动这一优化。 前言:在现实项目中,我们可能很少需要从头开始去配置一个webpack 项目,特别是webpack4.0发布以后,零配置启动一个项目成为一种标配。正因为...

    leanxi 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<