如何避免 Angular 被瀏覽器 cache ?
瀏覽器為了效能,會對 HTML、JavaScript 與 CSS 做 cache,其本意是好的,但對於 developer 來說,卻擔心更新到 production server 後,user 仍然是執行到被瀏覽器 cache 的 HTML、JavaScript 與 CSS,Angular 該如何解決這個問題呢 ?
Version
Angular 5.1
HTML
在經過 Angular CLI 的 ng build --prod 之後,會在 dist 目錄下產生整個 Angular 專案唯一的 index.html,擔心的是 user 執行到被瀏覽器 cache 的 index.html。
新增 HTML Meta
src/index.html
1 | <!doctype html> |
第 6 行1
2
3<meta http-equiv="Cache-Control" content="no-cache, no-store, max-age=0, must-revalidate">
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="expires" content="0" />
新增這 3 行 <meta>。
在 HTTP 1.1 規格中,有 Cache-Control 可設定瀏覽器的 cache。
在 HTTP 1.0 規格中,有 Pragma 可設定瀏覽器的 cache。
而 HTTP 1.0 與 1.1 都有 Expires 設定 cache 內容的有效期限,但在 1.1 的規格中,Cache-Control 的優先權是大於 Expires,因此可以規劃出以上通用設定,就可避免 index.html 被瀏覽器 cache。

- 開啟
src目錄下的index.html - 加入 3 行
<meta>
編譯 Angular
1 | ~/MyProject $ ng build --prod |
要放進 production server 的 code,最後會加上 --prod。

編譯後的 index.html
經過 ng build --prod 之後的 HTML、JavaScript 與 CSS 都會放在 dist 目錄下。

- 選擇
dist目錄 - 選擇
index.html,這是最後會上 production server 的index.html - 我們剛剛加入的 3 個
<meta>都還留著,因此不用每次編譯就修改index.html
只要改一次
src/index.html的<meta>,之後就不用擔心 HTML 被瀏覽器 cache 的問題
JavaScript
JavaScript 若檔名相同,瀏覽器會優先選擇使用本地的 cache 增加效能,Angular CLI 在每次 ng build --prod 之後,會重新以亂數命名 JavaScript 檔案,因此瀏覽器只能重新對 server 抓 *.js,而不會採用瀏覽器的 cache。

所有經過 ng build --prod 所 bundle 的 JavaScript 都經過亂數改掉檔名,因此瀏覽器一定會再跟 server 要新的 JavaScript。

Angular CLI 會幫我們將所引用的 JavaScript 一併改名。
CSS
CSS 若檔名相同,瀏覽器會優先選擇使用本地的 cache 增加效能,Angular CLI 在每次 ng build --prod 之後,會重新以亂數命名 CSS 檔案,因此瀏覽器只能重新對 server 抓 *.css,而不會採用瀏覽器的 cache。

所有經過 ng build --prod 所 bundle 的 CSS 都經過亂數改掉檔名,因此瀏覽器一定會再跟 server 要新的 CSS。

Angular CLI 會幫我們將所引用的 CSS 一併改名。
Conclusion
- 在開發階段時,完全不用擔心 HTML、JavaScript 與 CSS 被瀏覽器 cache 問題,Angular CLI 內建的 web server 已經幫我們處理
- 由於 JavaScript 並沒有提供
<meta>機制,因此若將 JavaScript 獨立於 HTML,就必須面臨 JavaScript 可能被瀏覽器 cache 的問題,Angular CLI 已經幫我們處理了 JavaScript 與 CSS,我們唯一需要處理的只剩下 HTML 部分,所幸 HTML 部分可簡單的用<meta>處理即可