[英]How to reload templates (html) when releasing a new version of a SPA?
我目前在發布新版本的 SPA 時遇到了麻煩,因為瀏覽器正在緩存 html 模板。
我的 SPA 使用 Angular 1.5、ocLazyload 和 ui-router。 我已經將 gulp 任務配置為使用緩存破壞技術(使用gulp-rev ),並且它運行得非常好,至少在腳本和 css 文件中是這樣。 但是,當我們對 html 文件進行更改時,瀏覽器會不斷加載舊版本。 有時,即使使用 Ctrl+F5 刷新頁面也無法解決問題,並且一直顯示舊版本的 html。
此外,將瀏覽器配置為不緩存 html 文件是不可取的(特別是對於移動設備),因為 html 更改可能不會經常發生。
有沒有什么好的解決方案可以解決這個問題,只有在有新版本的時候才獲取 html 文件?
提前致謝!
我在我參與的一個項目中遇到了這個問題。 我試過這些方法。
方法一:設置不同狀態的緩存屬性false。
var core = angular.module('app.core');
core.cofigure(configure);
configure.$inject = ['$stateProvider'];
// Configuration Function
function configure($stateProvider){
$stateProvider
.state('login', {
url: '/login/:redirect/:viewId',
cache: false, // Here i have set the cache property to false
templateUrl: 'app/layout/login.html'
})
.state('home', {
url: "/home",
cache: false, // Here also
abstract: true,
templateUrl: 'app/layout/container.html'
});
}
現在這個方法很好,但它在隨機時間和 Internet Explorer 中不起作用。
方法 2:向模板 URL 添加時間戳。
// I created a timestamp string with the current time.
var date = new Date().getTime().toString();
$stateProvider
.state('login', {
url: '/login/:redirect/:viewId',
cache: false,
// Now i append it here
templateUrl: 'app/layout/login.html' +'?' + date
})
.state('home', {
url: "/home",
cache: false,
abstract: true,
templateUrl: 'app/layout/container.html' + '?' + date // Here also.
});
這種方法是我們在搜索此問題的可能修復方法后決定的。 然而,在這種情況下不會發生緩存。 模板文件的每個 GET 請求都是不同的,它將保證加載的模板將是更新的模板。 但是,如果您正在構建具有大量模板且客戶端性能至關重要的 Web 應用程序,則此方法將無濟於事。
方法 3:需要模板
我推薦這種方法。 您可以在應用程序中使用require.js來在 javascript 執行時加載模板。 這將在為開發目的運行應用程序時以及在您為生產而縮小代碼時加載模板。 由於模板已加載到 javascript 代碼中,因此在部署到生產環境時也不必保留 html 模板文件。
$stateProvider
.state('login', {
url: '/login/:redirect/:viewId',
// Note 'template' and not 'templateUrl'
template: require('app/layout/login.html')
})
.state('home', {
url: "/home",
abstract: true,
template: require('app/layout/container.html')
});
當您使用 gulp 時,您可以使用gulp-angular-templateCache
,它是一個 gulp 插件,用於收集所有 html 文件,將它們連接到一個 javascript 文件中,然后根據文件路徑將它們添加到 AngularJS 的$templateCache
。
gulp.task('default', function () {
return gulp.src('app/**/*.html')
.pipe(templateCache({
module: 'yourModuleName'
}))
.pipe(gulp.dest('dist'));
});
生成的 JavaScript 文件包含如下內容:
angular.module('yourModuleName').run([$templateCache,
function($templateCache) {
$templateCache.put('app/path/to/some-template.html",
// some-template.html content comes here (escaped)
);
}
]);
您現在可以將此文件添加到您的包中,對 html 文件的任何更改都將更新您的包的內容,從而導致更新的緩存破壞者。
但是如果你不想更新整個包,你可以將它們分開並確保文件在你的包之后被加載。
注意:一旦其中一個發生更改,上述兩種方法都會破壞所有 html 文件的緩存,但是所有這些 html 文件都是使用單個調用檢索的。
另一種方法是將緩存破壞者添加到您的 html 文件並更新該文件的所有用法以包括緩存破壞者的哈希。 但我並不是很喜歡這種方法。
編輯:第一種方法是我在基於 gulp 的項目中使用的方法。 但是,最近我將 AngularJS 與 Webpack 一起使用(請參閱我的入門),並且我使用的方法與 Midhun Darvin 的第 3 種方法(請參閱此處)相當,但我使用的不是requirejs
,而是webpack
。 但是,請記住,這種方法(使用requirejs
或webpack
)會導致將 html 文件添加到包含 angularjs 代碼的 javascript 文件中。 這意味着對 javascript 文件的任何更改都將停止所有 html 文件的緩存,因為緩存破壞者將被更新。
我推薦一種類似於@Midhun Darvin 的選項 2 的方法(所以我使用他們的代碼作為基礎)。 不要使用日期,而是使用版本號。 每次發布時,您只需要記住更新版本號,所有 html 文件的緩存都會被破壞。
// update this with every release
var version = 0.1.0;
// make make this easier so you don't have to add query strings to all your template calls
var v = "?v=" + version;
$stateProvider
.state('login', {
url: '/login/:redirect/:viewId',
cache: false,
templateUrl: 'app/layout/login.html' + v // version added to bust cache
})
.state('home', {
url: "/home",
cache: false,
abstract: true,
templateUrl: 'app/layout/container.html' + v // version added to bust cache
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.