Prolog
Guten Tag, liebe Leser. Dieser Artikel befasst sich mit einem Problem, mit dem Entwickler mehr oder weniger schwerwiegender Websites konfrontiert sind, nämlich dem Problem der automatischen Aktualisierung von Skripten im Browser des Benutzers nach der Bereitstellung.
, , , , , , , . , , . – , , .
, 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', . , . , . , , .
, , .
, . , «», ?
? :