• 教你开发一个webpack plugin


    我们经常使用到webpack的插件功能,那如何开发一个自定义的插件呢?首先创建插件比创建 loader 更加高级,webpack 插件由以下组成:
    • 一个 JavaScript 命名函数。
    • 在插件函数的 prototype 上定义一个 apply 方法。
    • 指定一个绑定到 webpack 自身的事件钩子
    • 处理 webpack 内部实例的特定数据。
    • 功能完成后调用 webpack 提供的回调。
    下面就一点点的带你开发一个自定义的webpack plugin.
    先说说webpack插件中的两位重要人物,Compiler和Compliation
    • compiler 对象代表了完整的 webpack 环境配置。这个对象在启动 webpack 时被一次性建立,并配置好所有可操作的设置,包括 options,loader 和 plugin。当在 webpack 环境中应用一个插件时,插件将收到此 compiler 对象的引用。可以使用它来访问 webpack 的主环境。
    • compilation 对象代表了一次资源版本构建。当运行 webpack 开发环境中间件时,每当检测到一个文件变化,就会创建一个新的 compilation,从而生成一组新的编译资源。一个 compilation 对象表现了当前的模块资源、编译生成资源、变化的文件、以及被跟踪依赖的状态信息。compilation 对象也提供了很多关键时机的回调,以供插件做自定义处理时选择使用。
    基础插件架构
    ///src/plugins/helloPlugin.js
    // 命名函数。
    function HelloPlugin(options) {
        // 使用 options 设置插件实例……
        console.log(options);
    }
    
    //插件函数的 prototype 上定义一个 apply 方法
    HelloPlugin.prototype.apply = compiler => {
        //hooks
         compiler.hooks.done.tap('HelloPlugin', status => {
            console.log(status.toJson());
    
        })
        
        // 旧版本的相关钩子
        //compiler.plugin('done' , () => {
          //  console.log('hello world');
        //})
    
        // 设置回调来访问 compilation 对象:
        //compiler.plugin('compilation', compilation => {
    
            // 现在,设置回调来访问 compilation 中的步骤:
           // compilation.plugin('optimize', () => {
                console.log('optimize');
            //})
    
        //})
    }
    
    module.exports = HelloPlugin
    

      

    //webpack.config.js
    
    const HelloPlugin = require('./src/plugins/helloPlugin')
    plugins: [
            new HelloPlugin({options:true})
        ]
    

      

    这样基础架构就搭建完成了.
    认识一下事件钩子
    生命周期钩子函数,是由 compiler 暴露,可以通过如下方式访问:
    compiler.hooks.someHook.tap(...)
    

      

    取决于不同的钩子类型,也可以在某些钩子上访问 tapAsync 和 tapPromise。
    例如
    // 在处理来自webpack选项的entry配置后调用
        compiler.hooks.entryOption.tap('HelloPlugin', (context, entry) => {
            console.log(1,context, entry);
        })
     
    也支持自定义钩子函数
    // 自定义hook
     const SyncHook = require('tapable').SyncHook;
    // 具有 `apply` 方法……
    if (compiler.hooks.myCustomHook) throw new Error('Already in use');
    compiler.hooks.myCustomHook = new SyncHook(['a', 'b', 'c'])
    // 在你想要触发钩子的位置/时机下调用……
    compiler.hooks.myCustomHook.call(a, b, c);  
    

      

    学会了webpack的事件生命周期钩子函数,那么下面我们就开始着手写一个webpack插件.
    生成一个展示打包完成后的文件列表,ok,直接上代码
    // 命名函数。
    function HelloPlugin(options) {
        // 使用 options 设置插件实例……
        console.log(options);
    }
    
    //插件函数的 prototype 上定义一个 apply 方法
    HelloPlugin.prototype.apply = compiler => {
        // 在将资产释放到输出目录后调用。
        compiler.hooks.emit.tapAsync('HelloPlugin', (compilation, callback) => {
            let fileList = `## in this build:
    
    `
    
            console.log(compilation.assets);
            const assets = compilation.assets
            for(let key in assets){
                console.log(key);
                fileList+=`${key}
    `
            }
            compilation.assets['fileList.md'] = {
                source:()=>{return fileList},
                size:() => {return fileList.length}
            }
            callback()
        })
    }
    module.exports = HelloPlugin
    

      

    看,根据不同的webpack生命周期事件钩子函数,处理不同的逻辑,就可以完成一个webpack的plugin了,你学会了吗?
    关于深入学习请参考:

  • 相关阅读:
    同类分布[AHOI2009]
    简单记录一下ruby 循环
    ruby中的respond to ?用法
    ruby中的return方法及class实例方法的initialize方法
    ruby中的字符串分隔符--split
    三次握手+四次挥手
    DNS服务器的简介——2
    HTTP-报文结构解析
    ruby中的三目操作符和include?操作
    ruby中的extend 和 include
  • 原文地址:https://www.cnblogs.com/yiyi17/p/12161593.html
Copyright © 2020-2023  润新知