Prologue
Bonjour, chers lecteurs. Cet article est consacré au problème rencontré par les développeurs de sites Web plus ou moins sérieux, à savoir le problème de la mise à jour automatique des scripts dans le navigateur de l'utilisateur après le déploiement.
, , , , , , , . , , . – , , .
, F5, , , .
, .
, , VueJS 2.6.x, js- webpack'.
-, , github.
, , . , , .
- .
, , . , , .
Vue, /src/plugins/AutoReload. npm .
- vue-cli, : store, , axios - dayjs . Element.
– . :
- . API, (, , ). , , .
- . – , , , . , .
- . .
, VueJS Webpack. , webpack js-, . , , version.json, .
, (development/production/etc.) package.json. :
{
"AppVersion": "1.0.0",
"Build": "development",
"BundleVersion": "2020-11-07T10:42:33.731Z"
}
, vue.config.js, :
const path = require('path');
// version.json
const AutoReloadUtils = require('./src/plugins/AutoReload/versionGenerator');
AutoReloadUtils.generateVersionFile(path.resolve(path.join(__dirname, 'public/version.json')));
module.exports = {
...
};
version.json:
const path = require('path');
const fs = require('fs');
module.exports = {
/**
*
* @param {String} filename
*/
generateVersionFile: function (filename) {
// package.json
const packageJson = fs.readFileSync('./package.json');
const version = JSON.parse(packageJson).version || 0;
fs.writeFileSync(filename, `{
"AppVersion": "${version}",
"Build": "${process.env.NODE_ENV}",
"BundleVersion": "${new Date().toISOString()}"
}
`);
}
}
serve, build version.json, get-, .
№1. version.json public, VueJS « ». .
â„–2. version.json git', , .
AutoReload
:
. , , :
- Enabled – , true.
- CheckInterval – , 60. .
- Notification – , true. , «», .
- NotificationMessage – , « , .». Element, , . , , alert.
import { isBoolean } from './utils';
/**
*
*/
export default class Config {
/**
*
* @param {Object} origin
*/
constructor(origin) {
/**
*
* @type {Boolean}
*/
this.Enabled = isBoolean(origin.Enabled) ? origin.Enabled : true;
/**
*
* @type {Number}
*/
this.CheckInterval = origin.CheckInterval ?? 1 * 60;
/**
*
* @type {Boolean}
*/
this.Notification = isBoolean(origin.Notification) ? origin.Notification : true;
/**
*
* @type {String}
*/
this.NotificationMessage = origin.NotificationMessage
?? ' , .';
}
}
, – Element', create Vue:
import AutoReload from '@/plugins/AutoReload';
...
new Vue({
router,
store,
created() {
Vue.use(AutoReload, {
config: {
//
Enabled: true,
//
CheckInterval: 60,
},
router: this.$router,
vm: this,
});
},
render: h => h(App),
}).$mount('#app');
import Config from './Config';
import { getVersion } from './utils';
/** @typedef {import('./Version').default} Version */
/**
*
*/
export default class AutoReload {
/**
*
* @param {Object} options
*/
constructor(options) {
/** */
this.router = options.router;
/** Vue */
this.vm = options.vm;
/** */
this.config = new Config(options.config);
/**
*
* @type {Version}
*/
this.lastVersion = null;
/**
*
* @type {Number}
*/
this.timer = null;
}
/** */
async init() {
const config = this.config;
if (config.Enabled) {
//
this.lastVersion = await getVersion();
if (this.lastVersion && config.CheckInterval > 0) {
//
this.timer = setInterval(async () => {
this.check();
}, config.CheckInterval * 1000);
}
//
this.router.beforeEach(async (to, from, next) => {
await this.check(this.router.resolve(to).href);
next();
});
}
}
/**
*
* @param {String} href
*/
async check(href) {
//
const version = await getVersion();
if (this.lastVersion.BundleVersion != version.BundleVersion) {
//
//
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
if (this.config.Notification) {
//
await this.vm.$alert(this.config.NotificationMessage, '', {
type: 'warning',
confirmButtonText: 'OK',
closeOnClickModal: true,
closeOnPressEscape: true,
}).catch(() => { });
}
//
// , ,
// ,
this.lastVersion = await getVersion();
this.reload(href);
}
}
/**
*
* @param {String} href
*/
reload(href) {
if (href) {
window.location.href = href;
} else {
window.location.reload(true);
}
}
}
check href. , .
version.json . , , .
, F5 (window.location.reload(true)). , . , .. next() .
, .
â„–1.
version.json . «» , , URL. , version.json .
, , . , , .
, .
, : «60 », «60 ». , . , .
C# , JS . .
C#: https://pastebin.com/T1PsMy4N
JS: https://pastebin.com/a4z25b1H
:
//
var windows0 = WordForm.get(0, "", "", ""); // ""
var windows1 = WordForm.get(1, "", "", ""); // ""
var windows2 = WordForm.get(2, "", "", ""); // ""
//
var totalWindows0 = WordForm.getAsCount(0, "", "", ""); // "0 "
var totalWindows1 = WordForm.getAsCount(1, "", "", ""); // "1 "
var totalWindows2 = WordForm.getAsCount(2, "", "", ""); // "2 "
, , , . .
, - , , , . , - -, - .
? , , , , , , .
- , : , .
, , , . js- . .
, / , . , , – .
, , . , store. , , .
, , : .
, , - changelog', . , . , . , , .
, , .
, . , «», ?
? :