我们平常在用webpack亦或者vue cli打包项目时,它会先删除对应的output目录,这时候如果网站的根路径正好配置于output目录,那么用户浏览到的资源将不存在,搞得用户还以为网站挂了。所以应该给用户个提示:网站在维护。

执行npm run build的时候应当显示这个页面,等build完成再显示打包成功后的页面

QQ截图20210801121909.png

流程可以这么设计:
在webpack compiler钩子在entry配置项处理过之后。这时output目录内容已被删除,在这时重新写入维护页面文件maintenance.html内容。然后再在webpack compiler钩子在编译完成(done)后删除该文件。
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const fs = require('fs');
const path = require('path');

class SystemMaintenancePlugin {
apply(compiler) {
//获取webpack的输出目录
let webpackOutputPath = compiler.options.output.path;
//开始转为系统维护状态
compiler.hooks.entryOption.tap('system-maintenance-plugin', () => {
if (!fs.existsSync(webpackOutputPath)) {
fs.mkdirSync(webpackOutputPath)
}
let content = fs.readFileSync(path.resolve(__dirname, './maintenance.html'));
let time = new Date().getTime();
//在后尾添加系统维护开始时间
content += '<script>window.startTime = ' + time + ';</script>';
let outputPath = path.join(webpackOutputPath,'./maintenance.html');
fs.writeFileSync(outputPath, content);
});
//系统维护完成
compiler.hooks.done.tap('system-maintenance-plugin', () => {
let outputPath = path.join(webpackOutputPath,'./maintenance.html')
//删除文件
if (fs.existsSync(outputPath)) {
fs.unlinkSync(outputPath);
}
});
}
}

module.exports = SystemMaintenancePlugin;

源码包括maintenance.html文件内容在附件。

使用方法:
在vue.config.js文件中加入:

1
2
3
configureWebpack: config => {
config.plugins.push(new SystemMaintenancePlugin());//SystemMaintenancePlugin 自行在文件头引入
}

附件:
SystemMaintenancePlugin.zip