webpack4-page-update
Version:
个人js库
224 lines (218 loc) • 8.07 kB
JavaScript
const path = require('path');
const fs = require('fs/promises');
const prompts = require('prompts');
const dayjs = require('dayjs');
const child_process = require('child_process')
const htmlStr = (version, baseUrl, otherInfo) => {
return `
<script>
window.version = "${version}";
console.log("version", window.version);
console.log("其他信息", ${JSON.stringify(otherInfo)});
const getVersion = async () => {
const res = await fetch("${baseUrl}" + "/version.json?v=" + Date.now(), {
method: "GET"
});
const versionJson = await res.json();
if (versionJson.version != window.version) {
clearIntervalVersion();
document.querySelector(
"#weboack-page-update"
).style.display = "block";
}
};
function clearIntervalVersion() {
clearInterval(timmer);
}
getVersion();
const timmer = setInterval(getVersion, 1000 * 10);
function reloadPage() {
window.location.reload();
}
function cancel() {
clearIntervalVersion();
document.querySelector("#weboack-page-update").style.display =
"none";
}
</script>
<style>
#weboack-page-update {
display: none;
position: fixed;
z-index: 99999999;
right: 20px;
bottom: 20px;
width: 250px;
background-color: white;
border: 1px solid #ccc;
border-radius: 5px;
padding: 20px;
.title {
font-size: 18px;
color: #333;
padding-bottom: 10px;
}
.content {
padding-bottom: 15px;
}
.btns {
display: flex;
justify-content: space-between;
}
.btns .btn {
width: 80px;
height: 30px;
border: 1px solid #ccc;
border-radius: 5px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
/* 取消按钮 */
.btn:first-child {
color: #333;
border-color: #ccc;
}
/* 确认按钮 */
.btn:last-child {
color: #fff;
background-color: #1684fc;
}
}
</style>
<div id="weboack-page-update">
<div class="title">
发现新版本
</div>
<div class="content">
检测到新版本,是否更新立即使用
</div>
<div class="btns">
<button class="btn" onclick="cancel()">
取消
</button>
<button class="btn" onclick="reloadPage()">
确认
</button>
</div>
</div>
`
}
/**
* baseUrl default ""
* type default "date" 可选值"date"|"package"
*/
const plugin = (baseUrl = '', type = 'date') => {
return {
apply: (compiler) => {
compiler.plugin('emit', async (compilation, callback) => {
let version = ''
if (type === 'date') {
version = dayjs().format('YYYY-MM-DD HH:mm:ss');
}
if (type === 'package') {
const packageStr = await fs.readFile(path.resolve(module.parent.path, 'package.json'), 'utf8')
const packageJson = JSON.parse(packageStr);
version = packageJson.version;
}
const versionInfo = { version: version }
// 将 version.json 文件添加到 compilation.assets 中
compilation.assets['version.json'] = {
source: () => JSON.stringify(versionInfo, null, 2), // 文件内容
size: () => JSON.stringify(versionInfo).length // 文件大小
};
const indexOld = compilation.assets['index.html'].source();
let otherInfo = {
branch: '无',
commit: '无'
}
try {
const branch = await new Promise((resolve, reject) => {
child_process.exec('git symbolic-ref --short -q HEAD', (err, stdout) => {
if (err) {
reject(err);
} else {
resolve(stdout.trim());
}
});
});
otherInfo.branch = branch;
} catch (error) {
console.log('获取分支失败:', error)
}
try {
const commit = await new Promise((resolve, reject) => {
child_process.exec('git log -n 1 --pretty=format:"%h %ad " --date=format:"%Y-%m-%d %H:%M"', (err, stdout) => {
if (err) {
reject(err);
} else {
resolve(stdout.trim());
}
});
});
otherInfo.commit = commit;
} catch (error) {
console.log('获取commit失败:', error)
}
const indexNew = indexOld.replace('</body>', `${htmlStr(version, baseUrl,otherInfo)}</body>`);
compilation.assets['index.html'] = {
source: () => indexNew,
size: () => indexNew.length
};
// 确保回调函数被调用,通知 Webpack 继续处理
callback();
});
}
}
}
async function changeVersion() {
const reg = /"version":\s*"(.*?)"/;
let pkgStr = await fs.readFile(path.resolve(require.main.path, 'package.json'), 'utf-8');
const version = pkgStr.match(reg)[1];
let vl = version.split('-')[0].split('.');
let vr = version.split('-')[1];
const response = await prompts({
type: 'select',
name: 'value',
message: '请选择需要升级的版本规则',
choices: [
{ title: 'v1', value: 0, description: '主版本号' },
{ title: 'v1.0', value: 1, description: '次版本号' },
{ title: 'v1.0.0', value: 2, description: '修订号' },
{ title: 'v1.0.0-日期', value: 3, description: '日期' },
{ title: '不升级', value: 4, description: '不升级' }
],
initial: 0
});
if (response.value === undefined) {
process.exit(1);
}
if (response.value === 4) return console.log('只打包,不升级');
vr = dayjs().format('YYYYMMDDHHmmss');
switch (response.value) {
case 0:
vl[0] = parseInt(vl[0]) + 1;
vl[1] = 0;
vl[2] = 0;
break;
case 1:
vl[1] = parseInt(vl[1]) + 1;
vl[2] = 0;
break;
case 2:
vl[2] = parseInt(vl[2]) + 1;
break;
case 3:
break;
}
// 组合version
const newVersion = `${vl.join('.')}-${vr}`;
const newPkgStr = pkgStr.replace(reg, `"version": "${newVersion}"`);
fs.writeFile('./package.json', newPkgStr);
console.log(`当前版本为:${version},升级后版本为:${newVersion}`);
}
module.exports = {
plugin,
changeVersion
};