最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • webpack系列之plugin实现

    正文概述 掘金(沐晓)   2020-12-04   737

    webpack 是个很强大的构建工具,其丰富灵活的配置决定了使用也不简单。在面试中经常能遇到 webpack 相关的问题,如果平常只是使用脚手架如 vue-cli 而没有好好深入学习研究 webpack 的话,估计答不上什么。我相信,如果没有深入了解,部分面试官也问不出什么。可能也就变成了两个人侃侃如何配置出入口,常见的 loader,plugin 有哪些。

    作为一名多年油条前端,一直没有正视 webpack 相关知识,面对 webpack 相关的面试题更是一问三不知。这次准备好好学习研究 webpack相关内容,并且将学习内容记录成 webpack 系列,希望可以让不了解 webpack 的小白能对其有所掌握。

    编写一个插件

    插件向第三方开发者提供了 webpack 引擎中完整的能力。专注处理 webpack 在编译过程中的某个特定任务的功能模块,可以称为插件。

    创建插件

    webpack 插件由以下组成:

    • 一个 Javascript 命名函数

    • 在插件函数的 prototype 上定义一个 apply 方法

    • 指定一个绑定到 webpack 自身的事件钩子

    • 处理 webpack 内部实例的特定数据

    • 功能完成之后调用 webpack 提供的回调

    // 一个 JavaScript 命名函数。
    function MyExampleWebpackPlugin() {
    
    };
    
    // 在插件函数的 prototype 上定义一个 `apply` 方法。
    MyExampleWebpackPlugin.prototype.apply = function(compiler) {
      // 指定一个挂载到 webpack 自身的事件钩子。
      compiler.plugin('webpacksEventHook', function(compilation /* 处理 webpack 内部实例的特定数据。*/, callback) {
        console.log("This is an example plugin!!!");
    
        // 功能完成后调用 webpack 提供的回调。
        callback();
      });
    };
    

    Compiler 和 Compilation

    在插件开发中最重要的两个资源就是 compiler 和 compilation 对象。插件的主要功能就是根据 compiler 和 compilation 得到当前配置项及编辑状态,再通过 compiler 及 compilation 给出的钩子参与编译过程。

    • compiler 对象代表了完整的 webpack 环境配置。这个对象在启动 webpack 时被一次性建立,并配置好所有可操作的设置,包括 options,loader 和 plugin。当在 webpack 环境中应用一个插件时,插件将收到此 compiler 对象的引用。可以使用它来访问 webpack 的主环境。

    • compilation 对象代表了一次资源版本构建。当运行 webpack 开发环境中间件时,每当检测到一个文件变化,就会创建一个新的 compilation,从而生成一组新的编译资源。一个 compilation 对象表现了当前的模块资源、编译生成资源、变化的文件、以及被跟踪依赖的状态信息。compilation 对象也提供了很多关键时机的回调,以供插件做自定义处理时选择使用。

    开发插件的核心就在于运用这个两个对象,其源码在

    • Compiler Source

    • Compilation Source

    基本插件架构

    插件是由「具有 apply 方法的 prototype 对象」所实例化出来的。这个 apply 方法在安装插件时,会被 webpack compiler 调用一次。apply 方法可以接收一个 webpack compiler 对象的引用,从而可以在回调函数中访问到 compiler 对象。一个简单的插件结构如下:

    function HelloWorldPlugin(options) {
      // 使用 options 设置插件实例……
    }
    
    HelloWorldPlugin.prototype.apply = function(compiler) {
      // 相当于在Done钩子中注册函数
      compiler.plugin('done', function() {
        console.log('Hello World!');
      });
    };
    
    module.exports = HelloWorldPlugin;
    

    然后,要安装这个插件,只需要在你的 webpack 配置的 plugin 数组中添加一个实例:

    var HelloWorldPlugin = require('hello-world');
    
    var webpackConfig = {
      // ... 这里是其他配置 ...
      plugins: [
        new HelloWorldPlugin({options: true})
      ]
    };
    

    访问 compilation 对象

    使用 compiler 对象时,你可以绑定提供了编译 compilation 引用的回调函数,然后拿到每次新的 compilation 对象。这些 compilation 对象提供了一些钩子函数,来钩入到构建流程的很多步骤中。

    function HelloCompilationPlugin(options) {}
    
    HelloCompilationPlugin.prototype.apply = function(compiler) {
    
      // 设置回调来访问 compilation 对象:
      compiler.plugin("compilation", function(compilation) {
    
        // 现在,设置回调来访问 compilation 中的步骤:
        compilation.plugin("optimize", function() {
          console.log("Assets are being optimized.");
        });
      });
    };
    
    module.exports = HelloCompilationPlugin;
    

    异步编译插件

    一些异步钩子需要额外使用 callBack 回调函数

    function HelloAsyncPlugin(options) {}
    
    HelloAsyncPlugin.prototype.apply = function(compiler) {
      compiler.plugin("emit", function(compilation, callback) {
    
        // 做一些异步处理……
        setTimeout(function() {
          console.log("Done with async work...");
          callback();
        }, 1000);
    
      });
    };
    
    module.exports = HelloAsyncPlugin;
    

    示例

    function FileListPlugin(options) {}
    
    FileListPlugin.prototype.apply = function(compiler) {
      compiler.plugin('emit', function(compilation, callback) {
        // 在生成文件中,创建一个头部字符串:
        var filelist = 'In this build:\n\n';
    
        // 遍历所有编译过的资源文件,
        // 对于每个文件名称,都添加一行内容。
        for (var filename in compilation.assets) {
          filelist += ('- '+ filename +'\n');
        }
    
        // 将这个列表作为一个新的文件资源,插入到 webpack 构建中:
        compilation.assets['filelist.md'] = {
          source: function() {
            return filelist;
          },
          size: function() {
            return filelist.length;
          }
        };
    
        callback();
      });
    };
    
    module.exports = FileListPlugin;
    

    欢迎到前端菜鸟群一起学习交流~516913974


    起源地下载网 » webpack系列之plugin实现

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元