Tarayıcı tarafından önbelleğe alınan index.html ile benzer bir sorun yaşadım veya orta cdn / proxy'ler tarafından daha karmaşık hale getirildim (F5 size yardımcı olmayacak).
Müşterinin en son index.html sürümüne sahip olduğunu% 100 doğrulayan bir çözüm aradım, neyse ki bu çözümü Henrik Peinar tarafından buldum:
https://blog.nodeswat.com/automagic-reload-for-clients-after-deploy-with-angular-4-8440c9fdd96c
Çözüm ayrıca, istemcinin tarayıcıyı günlerce açık tutması, istemcinin aralıklarla güncellemeleri kontrol etmesi ve daha yeni bir sürüm dağıtılırsa yeniden yüklenmesi durumunu da çözer.
Çözüm biraz zor ama bir cazibe gibi çalışıyor:
ng cli -- prod
bunlardan biri main. [hash] .js olarak adlandırılan karma dosyalar üreten gerçeğini kullanın
- bu karmayı içeren bir version.json dosyası oluşturun
- version.json dosyasını kontrol eden ve gerekirse yeniden yükleyen bir açısal servis VersionCheckService oluşturun.
- Dağıtımdan sonra çalıştırılan bir js betiğinin sizin için hem version.json oluşturduğunu hem de açısal hizmette hash'i değiştirdiğini unutmayın, bu nedenle manuel çalışma gerekmez, ancak post-build.js çalıştırılır.
Henrik Peinar çözümü açısal 4 için olduğu için küçük değişiklikler oldu, düzeltilen komut dosyalarını da buraya yerleştirdim:
VersionCheckService:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable()
export class VersionCheckService {
// this will be replaced by actual hash post-build.js
private currentHash = '{{POST_BUILD_ENTERS_HASH_HERE}}';
constructor(private http: HttpClient) {}
/**
* Checks in every set frequency the version of frontend application
* @param url
* @param {number} frequency - in milliseconds, defaults to 30 minutes
*/
public initVersionCheck(url, frequency = 1000 * 60 * 30) {
//check for first time
this.checkVersion(url);
setInterval(() => {
this.checkVersion(url);
}, frequency);
}
/**
* Will do the call and check if the hash has changed or not
* @param url
*/
private checkVersion(url) {
// timestamp these requests to invalidate caches
this.http.get(url + '?t=' + new Date().getTime())
.subscribe(
(response: any) => {
const hash = response.hash;
const hashChanged = this.hasHashChanged(this.currentHash, hash);
// If new version, do something
if (hashChanged) {
// ENTER YOUR CODE TO DO SOMETHING UPON VERSION CHANGE
// for an example: location.reload();
// or to ensure cdn miss: window.location.replace(window.location.href + '?rand=' + Math.random());
}
// store the new hash so we wouldn't trigger versionChange again
// only necessary in case you did not force refresh
this.currentHash = hash;
},
(err) => {
console.error(err, 'Could not get version');
}
);
}
/**
* Checks if hash has changed.
* This file has the JS hash, if it is a different one than in the version.json
* we are dealing with version change
* @param currentHash
* @param newHash
* @returns {boolean}
*/
private hasHashChanged(currentHash, newHash) {
if (!currentHash || currentHash === '{{POST_BUILD_ENTERS_HASH_HERE}}') {
return false;
}
return currentHash !== newHash;
}
}
ana AppComponent'e değiştirin:
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
constructor(private versionCheckService: VersionCheckService) {
}
ngOnInit() {
console.log('AppComponent.ngOnInit() environment.versionCheckUrl=' + environment.versionCheckUrl);
if (environment.versionCheckUrl) {
this.versionCheckService.initVersionCheck(environment.versionCheckUrl);
}
}
}
Büyüleyici, post-build.js oluşturan derleme sonrası komut dosyası:
const path = require('path');
const fs = require('fs');
const util = require('util');
// get application version from package.json
const appVersion = require('../package.json').version;
// promisify core API's
const readDir = util.promisify(fs.readdir);
const writeFile = util.promisify(fs.writeFile);
const readFile = util.promisify(fs.readFile);
console.log('\nRunning post-build tasks');
// our version.json will be in the dist folder
const versionFilePath = path.join(__dirname + '/../dist/version.json');
let mainHash = '';
let mainBundleFile = '';
// RegExp to find main.bundle.js, even if it doesn't include a hash in it's name (dev build)
let mainBundleRegexp = /^main.?([a-z0-9]*)?.js$/;
// read the dist folder files and find the one we're looking for
readDir(path.join(__dirname, '../dist/'))
.then(files => {
mainBundleFile = files.find(f => mainBundleRegexp.test(f));
if (mainBundleFile) {
let matchHash = mainBundleFile.match(mainBundleRegexp);
// if it has a hash in it's name, mark it down
if (matchHash.length > 1 && !!matchHash[1]) {
mainHash = matchHash[1];
}
}
console.log(`Writing version and hash to ${versionFilePath}`);
// write current version and hash into the version.json file
const src = `{"version": "${appVersion}", "hash": "${mainHash}"}`;
return writeFile(versionFilePath, src);
}).then(() => {
// main bundle file not found, dev build?
if (!mainBundleFile) {
return;
}
console.log(`Replacing hash in the ${mainBundleFile}`);
// replace hash placeholder in our main.js file so the code knows it's current hash
const mainFilepath = path.join(__dirname, '../dist/', mainBundleFile);
return readFile(mainFilepath, 'utf8')
.then(mainFileData => {
const replacedFile = mainFileData.replace('{{POST_BUILD_ENTERS_HASH_HERE}}', mainHash);
return writeFile(mainFilepath, replacedFile);
});
}).catch(err => {
console.log('Error with post build:', err);
});
komut dosyasını (yeni) derleme klasörüne yerleştirin, komut dosyasını kullanarak node ./build/post-build.js
dist klasörünü oluşturduktan sonrang build --prod