webpack插件开发

记一次webpack插件开发

需求背景,由于public里面包含另外一个项目,每次项目里面的index.html 都被缓存在客户端造成所以使用一个插件改造打包后路径,并修改文件md5

webpack插件开发_第1张图片

开始编写插件

新建一个puglin文件,放在哪里无所谓,只要你能找到就可以了

class SetScriptMD5Plugin {
   // apply 函数   compiler-联系webpack 过程中的上下文
    apply(compiler) {
        
    }
}
module.exports = SetScriptMD5Plugin;
标记插入

因为这次需要修改的地方还是挺多的,所以把他统一起来,用一个全局变量去存储做统一管理

根目录下的=> public => index.html

webpack插件开发_第2张图片
加入一行注释标识,等一下会把修改文件名后的路径加进来,代码如下

window.gameUrl = './../game_engine/laya/index-${hash}.html'

中间的hash 就是我们需要生成的md5

开始改造plugin

class SetScriptMD5Plugin {
    apply(compiler) {
    // 监听webpack 打包时候的钩子,选择在编译的时候
        compiler.hooks.compilation.tap('SetScriptMD5Plugin', (compilation, callback) => {
            // 插件逻辑 调用compilation提供的plugin方法,监听在生成html 文件的时候获取index.html的上下文
            compilation.plugin('html-webpack-plugin-before-html-processing', (htmlPluginData) => {});
        });
    }
}
module.exports = SetScriptMD5Plugin;

获取文件的hash

// SetScriptMD5Plugin.js
const fs = require('fs');
const md5 = require('js-md5');

class SetScriptMD5Plugin {
    apply(compiler) {
    	// 找到需要hash的文件夹, 模糊搜索到你原来的文件
    	// 为什么要模糊搜索呢,因为第二次编译的时候,原来的文件已经是添加过hash的值了,所以不可以写死index.html
        const files = fs.readdirSync('./public/game_engine/laya');
        let targetName = null;
        files.forEach((item) => {
            if (/^index(\S)*.html$/.test(item)) {
                targetName = item;
            }
        });
        // 读取文件buffer
        const buffer =  fs.readFileSync(`./public/game_engine/laya/${targetName}`);
        // 生成md5
        const hash = md5(buffer);
		// 监听webpack 打包时候的钩子,选择在编译的时候
        compiler.hooks.compilation.tap('SetScriptMD5Plugin', (compilation, callback) => {
            // 插件逻辑 调用compilation提供的plugin方法
            compilation.plugin('html-webpack-plugin-before-html-processing', (htmlPluginData) => {
                // 读取并修改 script 上 src 列表
                const result = `window.gameUrl = './../game_engine/laya/index-${hash}.html'`;
                // 注入上面的代码
                const resultHTML = htmlPluginData.html.replace('// SetScriptTimestampPlugin inset script', result);
                // 返回修改后的结果
                htmlPluginData.html = resultHTML;
            });
        });
    }
}
module.exports = SetScriptMD5Plugin;
把md5值添加到原来更改的index.html文件

现在md5已经生成好了,window.gameUrl = 路径(也已经有了md5了),现在就是还差一个把原来文件的文件名修改

我们也是可以通过钩子直接修改

  compiler.hooks.environment.tap('doneChangeMD5', (compilation, callback) => {
            fs.renameSync(`./public/game_engine/laya/${targetName}`, `./public/game_engine/laya/index-${hash}.html`);
        });

那么已经完成拉

// SetScriptMD5Plugin.js
const fs = require('fs');
const md5 = require('js-md5');

class SetScriptMD5Plugin {
    apply(compiler) {
        const files = fs.readdirSync('./public/game_engine/laya');
        let targetName = null;
        files.forEach((item) => {
            if (/^index(\S)*.html$/.test(item)) {
                targetName = item;
            }
        });
        const buffer =  fs.readFileSync(`./public/game_engine/laya/${targetName}`);
        const hash = md5(buffer);

        compiler.hooks.compilation.tap('SetScriptMD5Plugin', (compilation, callback) => {
            // 插件逻辑 调用compilation提供的plugin方法
            compilation.plugin('html-webpack-plugin-before-html-processing', (htmlPluginData) => {
                // 读取并修改 script 上 src 列表
                const result = `window.gameUrl = './../game_engine/laya/index-${hash}.html'`;
                const resultHTML = htmlPluginData.html.replace('// SetScriptTimestampPlugin inset script', result);
                // 返回修改后的结果
                htmlPluginData.html = resultHTML;
            });
        });

        compiler.hooks.environment.tap('doneChangeMD5', (compilation, callback) => {
            fs.renameSync(`./public/game_engine/laya/${targetName}`, `./public/game_engine/laya/index-${hash}.html`);
        });
    }
}
module.exports = SetScriptMD5Plugin;

我们来看看效果

  • 更改前

webpack插件开发_第3张图片

  • 更改后
    webpack插件开发_第4张图片

看看页面效果

  • 更改前
    webpack插件开发_第5张图片

  • 更改后
    webpack插件开发_第6张图片

完事了,加油打工人

你可能感兴趣的:(前端知识,前端工具,vue,node.js,html)