精华内容
下载资源
问答
  • webpack插件怎么手写

    2020-09-09 17:18:01
    webpack插件没什么好说的,用过的都知道怎么配置,只是不知道内部怎么执行。今天学一学插件的一些机制,手写一个插件并不难。 之前介绍过了,webpack本质上是一种事件流机制,核心就是tapable,通过注册事件,触发回...

    webpack插件没什么好说的,用过的都知道怎么配置,只是不知道内部怎么执行。今天学一学插件的一些机制,手写一个插件并不难。

    之前介绍过了,webpack本质上是一种事件流机制,核心就是tapable,通过注册事件,触发回调,完成插件在不同生命周期的调用,内部也是通过大量的插件实现的。tapable内部暴露的方法挺多的,主要就是同步和异步,异步分为并行和串行。可以去GitHub上面看看:

    https://github.com/webpack/tapable#tapable

    这些方法都有用法示例,本来想写写使用方法,发现GitHub上面都有了,就不写了:

    const {
    
    	SyncHook,
    
    	SyncBailHook,
    
    	SyncWaterfallHook,
    
    	SyncLoopHook,
    
    	AsyncParallelHook,
    
    	AsyncParallelBailHook,
    
    	AsyncSeriesHook,
    
    	AsyncSeriesBailHook,
    
    	AsyncSeriesWaterfallHook
    
     } = require("tapable");
    
    

    在写插件之前,不得不提一下compiler和compilation:

    compiler对象代表了完整的 webpack 环境配置,可以访问整个环境。这个对象在启动 webpack 时被一次性建立,并配置好所有可操作的设置(options、loader、plugin等)。使用插件时将收到此 compiler 对象的引用。

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

    使用插件就是new一个,所以插件其实就是一个类(构造函数或者class类),内部在prototype定义一个apply方法(会直接调用),并提供compiler,通过compiler提供的hooks注册事件和在相应的回调里面进行操作。而compiler提供的compilation的重要属性是assets,表示所有的静态资源。

    关于提供的hook和参数,可以在webpack>lib>Compiler.js搜hooks,其实compiler和compilation都是继承tapable。

    关于hooks分别表示什么阶段可以去官网查看:https://www.webpackjs.com/api/compiler-hooks/

    还需要明确一下,tapable里面提供的几个hook,同步的(sync开头)注册是tap,异步的(async开头)有tap、tapAsync、tapPromise,后面两个提供了回调函数。

    引入自己的插件:

    const MyPlugin = require(’./plugins/my-plugin.js’)

    plugins里面使用:

    new MyPlugin({
    
      name: 'wade plugin'
    
    })
    

    my-plugin.js里面:

    class MyPlugin {
    
        constructor(options) {
    
            this.options = options;
    
        }
    
        apply(compiler){
    
            compiler.hooks.done.tap('MyPlugin', (stats) => {
    
                console.log('MyPlugin ', this.options);
    
            });
    
        }
    
    }
    
    
    
    module.exports = MyPlugin;
    

    apply提供了compiler,done是编译完成,同步的调用tap,第一个参数没什么意义,一般写自己插件名字,stats里面对象就多了,有 options、 outputOptions等,可以自己命令行那边看看。

    异步的:

    class MyPlugin {
    
        constructor(options) {
    
            this.options = options;
    
        }
    
        apply(compiler){
    
            compiler.hooks.done.tapAsync('DonePlugin', (stats, callback) => {
    
                console.log('Hello ', this.options.name);
    
                setTimeout(() => {console.log(1);}, 1000);
    
                setTimeout(() => {console.log(2);}, 2000);
    
                setTimeout(() => {console.log(3);}, 3000);
    
                setTimeout(() => {
    
                    callback();
    
                }, 4000)
    
            });
    
        }
    
    }
    
    
    
    module.exports = MyPlugin;
    

    可以看看控制台,看看效果。

    一般自己写插件会在emit和afterEmit进行一些操作,这两个钩子的参数是compilation,里面有assets是静态资源,可以进行操作:

    compiler.hooks.emit.tap('DonePlugin', (compilation) => {
    
       let assets = compilation.assets;
    
        console.log(assets);
    
    });
    

    比如我想给bundle.js添加一个字符串:

    let content = assets['bundle.js'].source();
    
    assets['bundle.js'] = {
    
        source(){
    
            return '"build by wade"\r\n' + content
    
        },
    
        size(){
    
            return content.length;
    
        }
    
    }
    

    打包结果:

    比如创建一个文件:

    let creatContent = '创建一个文件';
    
    assets['creat.js'] = {
    
        source(){
    
            return creatContent
    
        },
    
        size(){
    
            return creatContent.length
    
        }
    
    }
    


    上面都是没什么意义的操作,只是想表达插件的一些方法,比如可以在文件生成之后进行压缩,或者自动化部署到服务器之类的插件。真正写一些有用的插件还是需要根据具体清空具体实现代码,可能还需要引入一些外部的插件,比如进行请求需要引入ajax或者axios,压缩要引入JSZip等。

    展开全文
  • webpack 插件怎么写

    2019-04-17 10:13:00
    摘要 现在项目大部分都使用webpack 进行编译,一方面 webpack 生命力比较旺盛,另一方面 webpack 的生态非常完善。...那就来一个业务定制化的webpack 插件吧。 官方文档可见: https://webpack.js.org/cont...

    摘要

    现在项目大部分都使用webpack 进行编译,一方面 webpack 生命力比较旺盛,另一方面 webpack 的生态非常完善。我们90%的场景都能够满足。但有时候也会遇到一些特定的业务场景,比如有时候会遇到需要对编译后的文件进行一些文件注入 等其他特定化的需求。怎么办呢?那就来写一个业务定制化的webpack 插件吧。

    官方文档可见: https://webpack.js.org/contribute/writing-a-plugin/#creating-a-plugin

    如何编写插件

    首先我们了解下一个插件的主要结构

    class DtoolPlugin {
        // 构造函数,进行参数校验等功能
        constructor(args) {}
        
        // 定义插件执行的方法体,主要逻辑都在这里完成,webpack 会自动调用此方法
        apply(compiler) {}
    
    }

    下面我们来看下 compiler 这个关键对象,compile 提供了 webpack 一系列操作的钩子函数,下面说一说常用的hooks

    官方文档可见:https://webpack.js.org/api/compiler-hooks/#watching

    下面以真实案例来讲解

        apply(compiler) {
                const metaParams = this.metaParams;
            const tester = {test: this.test};
    
            compiler.hooks.compilation.tap('DtoolPlugin', (compilation) => {
                    compilation.hooks.optimizeChunkAssets.tapAsync('DtoolPlugin', (chunks, done) => {
                        wrapChunks(compilation, chunks);
                        done();
                    })
                });
                // 注入文件方法
                function wrapChunks(compilation, chunks) {
                    chunks.forEach(chunk => {
                        const args = {
                            hash: compilation.hash,
                            chunkhash: chunk.hash
                        };
                        chunk.files.forEach(fileName => {
                            if (ModuleFilenameHelpers.matchObject(tester, fileName)) {
                                const content = 'xxxxx';
                                // 注入内容
                                // assets 对象是编译后的对象,以文件名为key , 值为文件内容 、 文件size 等一系列信息, 通过asset 可以对文件名字 , 文件内容做变更
                                compilation.assets[fileName] = new ConcatSource(
                                    compilation.assets[fileName],
                                    String(content),
                                );
                        }
                    });
                });
            }
        }
    

    hooks 调用的时候有个类型 plugin types 支持 tap , 有些支持异步类型 tapAsync tapPromise

    compiler.hooks.run.tapAsync('MyPlugin', (source, target, routesList, callback) => {
      console.log('Asynchronously tapping the run hook.');
      callback();
    });
    
    compiler.hooks.run.tapPromise('MyPlugin', (source, target, routesList) => {
      return new Promise(resolve => setTimeout(resolve, 1000)).then(() => {
        console.log('Asynchronously tapping the run hook with a delay.');
      });
    });
    
    compiler.hooks.run.tapPromise('MyPlugin', async (source, target, routesList) => {
      await new Promise(resolve => setTimeout(resolve, 1000));
      console.log('Asynchronously tapping the run hook with a delay.');
    });
    

    转载于:https://www.cnblogs.com/huxiaoyun90/p/10721779.html

    展开全文
  • webpack插件没什么好说的,用过的都知道怎么配置,只是不知道内部怎么执行。今天学一学插件的一些机制,手写一个插件并不难。之前介绍过了,webpack本质上是一种事件流机制,核心就是tapable,通过注册事件,触发回...

    f24942cedb79595ba5e6775455d2bfa7.png

    webpack插件没什么好说的,用过的都知道怎么配置,只是不知道内部怎么执行。今天学一学插件的一些机制,手写一个插件并不难。

    之前介绍过了,webpack本质上是一种事件流机制,核心就是tapable,通过注册事件,触发回调,完成插件在不同生命周期的调用,内部也是通过大量的插件实现的。tapable内部暴露的方法挺多的,主要就是同步和异步,异步分为并行和串行。可以去GitHub上面看看:

    https://github.com/webpack/tapable#tapable

    这些方法都有用法示例,本来想写写使用方法,发现GitHub上面都有了,就不写了:

    const {

    SyncHook,

    SyncBailHook,

    SyncWaterfallHook,

    SyncLoopHook,

    AsyncParallelHook,

    AsyncParallelBailHook,

    AsyncSeriesHook,

    AsyncSeriesBailHook,

    AsyncSeriesWaterfallHook

     } = require("tapable");

    在写插件之前,不得不提一下compiler和compilation:

    compiler对象代表了完整的 webpack 环境配置,可以访问整个环境。这个对象在启动 webpack 时被一次性建立,并配置好所有可操作的设置(options、loader、plugin等)。使用插件时将收到此 compiler 对象的引用。

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

    使用插件就是new一个,所以插件其实就是一个类(构造函数或者class类),内部在prototype定义一个apply方法(会直接调用),并提供compiler,通过compiler提供的hooks注册事件和在相应的回调里面进行操作。而compiler提供的compilation的重要属性是assets,表示所有的静态资源。

    关于提供的hook和参数,可以在webpack>lib>Compiler.js搜hooks,其实compiler和compilation都是继承tapable。

    a86014d8a72dfba48797b1513d673118.png

    关于hooks分别表示什么阶段可以去官网查看:https://www.webpackjs.com/api/compiler-hooks/

    还需要明确一下,tapable里面提供的几个hook,同步的(sync开头)注册是tap,异步的(async开头)有tap、tapAsync、tapPromise,后面两个提供了回调函数。

    引入自己的插件:

    const MyPlugin = require('./plugins/my-plugin.js')

    plugins里面使用:

    new MyPlugin({

      name: 'wade plugin'

    })

    my-plugin.js里面:

    class MyPlugin {

        constructor(options) {

            this.options = options;

        }

        apply(compiler){

            compiler.hooks.done.tap('MyPlugin', (stats) => {

                console.log('MyPlugin ', this.options);

            });

        }

    }

    module.exports = MyPlugin;

    apply提供了compiler,done是编译完成,同步的调用tap,第一个参数没什么意义,一般写自己插件名字,stats里面对象就多了,有 options、 outputOptions等,可以自己命令行那边看看。

    异步的:

    class MyPlugin {

        constructor(options) {

            this.options = options;

        }

        apply(compiler){

            compiler.hooks.done.tapAsync('DonePlugin', (stats, callback) => {

                console.log('Hello ', this.options.name);

                setTimeout(() => {console.log(1);}, 1000);

                setTimeout(() => {console.log(2);}, 2000);

                setTimeout(() => {console.log(3);}, 3000);

                setTimeout(() => {

                    callback();

                }, 4000)

            });

        }

    }

    module.exports = MyPlugin;

    可以看看控制台,看看效果。

    一般自己写插件会在emit和afterEmit进行一些操作,这两个钩子的参数是compilation,里面有assets是静态资源,可以进行操作:

    compiler.hooks.emit.tap('DonePlugin', (compilation) => {

       let assets = compilation.assets;

        console.log(assets);

    });

    fc65429cbad23230b1b09b1c8a64fa5d.png

    比如我想给bundle.js添加一个字符串:

    let content = assets['bundle.js'].source();

    assets['bundle.js'] = {

        source(){

            return '"build by wade"\r\n' + content

        },

        size(){

            return content.length;

        }

    }

    打包结果:

    18d60f4c821f949f2ef773e6cf155e52.png

    比如创建一个文件:

    let creatContent = '创建一个文件';

    assets['creat.js'] = {

        source(){

            return creatContent

        },

        size(){

            return creatContent.length

        }

    }

    03806683c65bab365c9db7817d37fc4c.png

    5b3d57a3e0119f35c23cbd6de3e01ddd.png

    上面都是没什么意义的操作,只是想表达插件的一些方法,比如可以在文件生成之后进行压缩,或者自动化部署到服务器之类的插件。真正写一些有用的插件还是需要根据具体清空具体实现代码,可能还需要引入一些外部的插件,比如进行请求需要引入ajax或者axios,压缩要引入JSZip等。

    (完)

    Coding 个人笔记

    f946001727cf4949e36446f708053a12.png

    展开全文
  • webpack插件没什么好说的,用过的都知道怎么配置,只是不知道内部怎么执行。今天学一学插件的一些机制,手写一个插件并不难。之前介绍过了,webpack本质上是一种事件流机制,核心就是tapable,通过注册事件,触发回...

    webpack插件没什么好说的,用过的都知道怎么配置,只是不知道内部怎么执行。今天学一学插件的一些机制,手写一个插件并不难。

    之前介绍过了,webpack本质上是一种事件流机制,核心就是tapable,通过注册事件,触发回调,完成插件在不同生命周期的调用,内部也是通过大量的插件实现的。tapable内部暴露的方法挺多的,主要就是同步和异步,异步分为并行和串行。可以去GitHub上面看看:

    https://github.com/webpack/tapable#tapable

    这些方法都有用法示例,本来想写写使用方法,发现GitHub上面都有了,就不写了:

    const {

    SyncHook,

    SyncBailHook,

    SyncWaterfallHook,

    SyncLoopHook,

    AsyncParallelHook,

    AsyncParallelBailHook,

    AsyncSeriesHook,

    AsyncSeriesBailHook,

    AsyncSeriesWaterfallHook

    } = require("tapable");

    在写插件之前,不得不提一下compiler和compilation:

    compiler对象代表了完整的 webpack 环境配置,可以访问整个环境。这个对象在启动 webpack 时被一次性建立,并配置好所有可操作的设置(options、loader、plugin等)。使用插件时将收到此 compiler 对象的引用。

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

    使用插件就是new一个,所以插件其实就是一个类(构造函数或者class类),内部在prototype定义一个apply方法(会直接调用),并提供compiler,通过compiler提供的hooks注册事件和在相应的回调里面进行操作。而compiler提供的compilation的重要属性是assets,表示所有的静态资源。

    关于提供的hook和参数,可以在webpack>lib>Compiler.js搜hooks,其实compiler和compilation都是继承tapable。

    97287f349ae60ab66d6d79fe3eccf59b.png

    关于hooks分别表示什么阶段可以去官网查看:https://www.webpackjs.com/api/compiler-hooks/

    还需要明确一下,tapable里面提供的几个hook,同步的(sync开头)注册是tap,异步的(async开头)有tap、tapAsync、tapPromise,后面两个提供了回调函数。

    引入自己的插件:

    const MyPlugin = require('./plugins/my-plugin.js')

    plugins里面使用:

    new MyPlugin({
    name: 'wade plugin'
    })

    my-plugin.js里面:

    class MyPlugin {
    constructor(options) {
    this.options = options;
    }
    apply(compiler){
    compiler.hooks.done.tap('MyPlugin', (stats) => {
    console.log('MyPlugin ', this.options);
    });
    }
    }
    module.exports = MyPlugin;

    apply提供了compiler,done是编译完成,同步的调用tap,第一个参数没什么意义,一般写自己插件名字,stats里面对象就多了,有 options、 outputOptions等,可以自己命令行那边看看。

    异步的:

    class MyPlugin {
    constructor(options) {
    this.options = options;
    }
    apply(compiler){
    compiler.hooks.done.tapAsync('DonePlugin', (stats, callback) => {
    console.log('Hello ', this.options.name);
    setTimeout(() => {console.log(1);}, 1000);
    setTimeout(() => {console.log(2);}, 2000);
    setTimeout(() => {console.log(3);}, 3000);
    setTimeout(() => {
    callback();
    }, 4000)
    });
    }
    }
    module.exports = MyPlugin;

    可以看看控制台,看看效果。

    一般自己写插件会在emit和afterEmit进行一些操作,这两个钩子的参数是compilation,里面有assets是静态资源,可以进行操作:

    compiler.hooks.emit.tap('DonePlugin', (compilation) => {
    let assets = compilation.assets;
    console.log(assets);
    });

    a6edc73f440611e4e7d5588aed9fe971.png

    比如我想给bundle.js添加一个字符串:

    let content = assets['bundle.js'].source();
    assets['bundle.js'] = {
    source(){
    return '"build by wade"rn' + content
    },
    size(){
    return content.length;
    }
    }

    打包结果:

    4528c7e565bad8de7d16f55bd3b465d1.png

    比如创建一个文件:

    let creatContent = '创建一个文件';
    assets['creat.js'] = {
    source(){
    return creatContent
    },
    size(){
    return creatContent.length
    }
    }

    7fde6a71c352071fd487a99cf39d8208.png

    7280217f818e3f4fc7242ba6c2a1c317.png

    上面都是没什么意义的操作,只是想表达插件的一些方法,比如可以在文件生成之后进行压缩,或者自动化部署到服务器之类的插件。真正写一些有用的插件还是需要根据具体清空具体实现代码,可能还需要引入一些外部的插件,比如进行请求需要引入ajax或者axios,压缩要引入JSZip等。

    展开全文
  • 借此,我们可以学习一下webpack 插件怎么写。 本来以为比较简单,但还是花了我一个上午的时间。 首先,我们需要初始化环境 yarn init -y yarn add webpack webpack-cli -D 复制代码 webpack.config.js 配置如下...
  • 本文只会针对 Webpack 插件展开,没有 Webpack 基础的同学...How,怎么编写一个 Webpack 插件Why,为什么要编写 Webpack 插件Where,Webpack 插件实战,离线包什么是 Webpack 插件一个标准的 Webpack4 配置应该是下...
  • 可以通过直属性,也可以通过vue中的plugin install上去。例如<code>Vue.prototype.$_ = lodash</code>,在应用了vue的应用上下文中,可以通过this.$_获得对lodash的引用。</li><li>在vue中&...
  • 什么是webpack它是一个模块打包器,也可以...今天我们先不弄那么复杂,我们就介绍webpack怎么分析ES6的模块依赖,怎么把ES6的代码转成ES5的。实现由于ES6转ES5中需要用到babel,所以要用到一下插件npm install @b...
  • 什么是webpack ...今天我们先不弄那么复杂,我们就介绍webpack怎么分析ES6的模块依赖,怎么把ES6的代码转成ES5的。 实现 由于ES6转ES5中需要用到babel,所以要用到一下插件 npm insta...
  • 上一篇中仅仅说了使用HtmlWebpackPlugin来处理html模板,...具体怎么做呢? 如果weboack不能直接去支持这么,需要一个html-loader作为中介; 那么第一步需要先初始化这个loader: npn install html-loade...
  • 打包后,把打包后的文件塞到html里面,并把结果放到webpack打包输出后的文件夹下面 怎么指定src下的html文件 ...// webpack 是node出来的 node的写法 let path = require('path'); // console.log(pat...
  • 参考: 细说 webpack 之流程篇 webpack之plugin内部运行机制 ...怎么写webpack插件   在写webpack的插件时,内部必须要实现一个apply方法,传入compiler参数,就可以通过调用plugin方法,在对应的事件...
  • 那里面的script标签还是死的index.bundle.js文件,那么怎么把他们变成动态的index.html文件,这个动态生成的index.html文件会动态引入我们打包后生成的js文件呢?,我们可以使用插件html-webpack-plugin,首先...
  • webpack入门宝典

    2018-03-07 16:54:00
    如果你以前没怎么接触过Webpack,而你又你对webpack感兴趣,那么动手跟着本文中那个贯穿始终的例子一次,完以后你会发现你已明明白白的走进了Webpack的大门。 // 一个常见的webpack配置文件 c...
  • 准备写个webpack的plugin,打开官网文档https://www.webpackjs.com/contribute/writing-a-plugin,发现有点蒙圈,看完文档好像知道怎么写,但又写不出来,所以看下html-webpack-plugin的实现,从而整体了解下插件的...
  • webpack常见面试题

    2021-03-04 14:48:10
    如何提高webpack的构建速度如何利用webpack来优化前端性能使用webpack开发时,你用过哪些可以提高效率的插件?模块热更新了解吗?说明其原理?source map是什么?生产环境怎么用?长缓存 什么是bu
  • 在vue项目中配置webpack

    千次阅读 2019-05-19 13:54:41
    在刚接触 webpack 的时候一直觉得这个打包工具是个可有可无的东西,不仅要许多的配置代码,还要安装各种插件来使用。后来接触的次数多了,觉得如果没有 webpack 的打包是很难完成工作的,因此这次来总结一下 ...
  • 我们需要借助 webpack 内置的插件 CommonsChunkPlugin。 首先 webpack 执行存在一部分运行时代码,即一部分初始化的工作,就像之前单文件中的 </p><pre><code><strong>webpack_require</strong...
  • 这一篇来讲解一下webpack的htmlWebpackHtml插件的使用。 先来思考一个实际问题:我们现在在index.html引用的js文件是死的。但是我们每次打包后的文件都是动态的,那么我们怎么让他们结合起来呢? 这就要借助...
  • 前言 最近打算一款webpack压缩图片的插件,但是需要数据对比,原始数据和压缩后的数据以及压缩的比例相关信息,于是想到了webpack打包的时候不就有相关的输出嘛,于是查看了一下webpack怎么输出信息的。...
  • 为什么读webpack源码 因为前端框架离不开webpack,天天都在用的东西啊,怎能...想源码,不看源码怎么行,虽然现在还不知道什么,就算不什么,看看别人的总可以吧 知道世界的广阔,那么多插件,那么多软件开...
  • 还没)探讨下对于Node.js作为后端的项目工程化、模块化、前后端共享代码、自动化部署的做法。 关于前端工程 下面是百科关于“;8KWAhpkQgUuyqAdcnb0Y380yJ5Ol8pY1-cGPR_...
  • 学了webpack之后,以后要在项目中装其他乱七八糟的插件的时候也不会一脸懵逼,不知道这些东西怎么配置的,免得每次配东西都要百度。话不多说,开始学习吧! 这是根据知乎上看到的文章的,我照着教程走了一遍,为了...
  • 所以我自己借鉴了下webpack插件了个基于<code>HtmlWebpackPlugin的内联资源插件<a href="https://github.com/shaodahong/html-webpack-inline-assets-plugin">html-webpack-inline-assets-plugin</a></p> ...
  • 博客不知道啥时候写的了,一直在草稿箱没写完,突然感觉今年过去大半了,又没怎么写博客。写写完,有始有终 1.代码分离升级 原来项目代码分离是通过下面的配置,基于bundle-loader插件,通过router.jsx的配置...
  • 这一章讲打包体积优化,这个也算是最重要的一章了,我之前可是花了很多时间去查资料怎么优化打包体积的,不同版本的webpack之间还有一些区别,所以也算踩了很多的坑,所以这一章会比较长。 这边我大概了一下页面...

空空如也

空空如也

1 2 3 4
收藏数 73
精华内容 29
关键字:

webpack插件怎么写