背景:
在vue项目中,有些时候会将一些配置文件放在static目录,有时候更新了项目之后,这些配置文件往往会出现前端的缓存,则想写一个插件,在打包后,对这些文件进行重命名修改。
插件编写逻辑:
const pluginName = 'RenameConfigFileWebpackPlugin';const fs = require('fs');const path = require('path')const config = require("../config");class RenameConfigFileWebpackPlugin {constructor(option) {this.configDirectoryName = option.configDirectoryName;this.indexFileName = option.indexFileName;}afterEmit(compilation,callback){let self = this;// let assets = compilation.assets;// let outputPath = compiler.outputPath;const assetsSubDirectory = path.join(config.build.assetsRoot, config.build.assetsSubDirectory,self.configDirectoryName);const indexHtmlPath = path.resolve(config.build.assetsRoot, self.indexFileName);// list all files in the directorylet fileMapping = {};fs.readdir(assetsSubDirectory, (err, files) => {if (err) {callback(err)}files.forEach(file => {//获取文件的后缀名let fileSuffix = path.extname(file);let fileNewName = file.replace(fileSuffix,"") + "-" + new Date().getTime() + fileSuffix;fs.rename(path.resolve(assetsSubDirectory,file), path.resolve(assetsSubDirectory,fileNewName), err => {callback(err);})fileMapping[file] = fileNewName;});});fs.readFile(indexHtmlPath, "utf8", function (err, dataStr) {if (err) {callback(err)}Object.keys(fileMapping).forEach(ele => {if (dataStr.indexOf(ele) > -1) {dataStr = dataStr.replace(ele, fileMapping[ele]);}})fs.writeFile(indexHtmlPath, dataStr, function (err) {if (err) {callback(err);}})})callback()}apply(compiler) {let self = this;if (compiler.hooks) {//兼容webpack4let plugin = {name: pluginName };compiler.hooks.afterEmit.tap(plugin, (compilation,callback)=>{self.afterEmit.call(self,compilation,callback)});} else {//兼容webpack3compiler.plugin('after-emit', (compilation,callback)=>{self.afterEmit.call(self,compilation,callback)});}}}module.exports = RenameConfigFileWebpackPlugin;
插件引用使用,在webpack.prod.conf.js配置文件中配置刚写好的插件:
const RenameConfigFileWebpackPlugin = require('./RenameConfigFileWebpackPlugin')new ConsoleLogOnBuildWebpackPlugin({configDirectoryName: 'config',indexFileName: 'index.html'})
最后的成果:
总结:
在编写插件的时候要注意:
webpack3、webpack4、webpack5三个版本开发插件,注意里面方法的不一致性。弄清楚webpack核心的插件的compiler和compilation的各自作用。Webpack4编写自定义插件,两个对象上能拿到不同的资源对象。拿到需要的对象后,使用nodejs来进行相关的操作即可。ES6的class语法要熟悉。