编写webpack插件修改vue打包后的index.html文件中配置文件静态资源引用
背景:
在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 directory
let 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) {
//兼容webpack4
let plugin = { name: pluginName };
compiler.hooks.afterEmit.tap(plugin, (compilation,callback)=>{
self.afterEmit.call(self,compilation,callback)
});
} else {
//兼容webpack3
compiler.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语法要熟悉。
webpack4
liuccn: 获取弹窗里面的的点击事件吗?这个就是一般的处理方法了。
2301_79079150: 用创建div的方式上图是不是不能添加事件获取实体了?应该怎么做呢
北梦木兮(zxt): line 的shapehao能转吗?
liuccn: 检查一下原始数据和操作步骤看是否有不一样的操作
再见南河: 为什么我的导出来是只有一个GLB文件和一个scenetree.json、一个tileset.json文件,而你的是b3dm文件,我的加载不出来呢?