我们有一个 Angular 6 应用程序。它在 Nginx 上提供。并且 SSL 已开启。
当我们部署新代码时,大多数新功能都可以正常工作,但对于某些更改则不行。例如,如果前端开发人员更新服务连接并部署它,用户必须打开隐身窗口或清除缓存才能看到新功能。
哪些类型的更改不会自动更新?为什么他们与其他人不同?
避免该问题的常见解决方案是什么?
我们有一个 Angular 6 应用程序。它在 Nginx 上提供。并且 SSL 已开启。
当我们部署新代码时,大多数新功能都可以正常工作,但对于某些更改则不行。例如,如果前端开发人员更新服务连接并部署它,用户必须打开隐身窗口或清除缓存才能看到新功能。
哪些类型的更改不会自动更新?为什么他们与其他人不同?
避免该问题的常见解决方案是什么?
问题是当一个静态文件被缓存时,它可以在它到期之前存储很长时间。如果您对站点进行更新,这可能会很麻烦,但是,由于文件的缓存版本存储在访问者的浏览器中,他们可能无法看到所做的更改。
Cache-busting通过使用唯一的文件版本标识符来告诉浏览器该文件的新版本可用,从而解决了浏览器缓存问题。因此浏览器不会从缓存中检索旧文件,而是向源服务器请求新文件。
Angular cli 通过为--output-hashing
build 命令提供一个标志来解决这个问题。
检查官方文档:https : //angular.io/cli/build
示例(旧版本)
ng build --prod --aot --output-hashing=all
以下是您可以传入的选项 --output-hashing
更新
对于较新版本的 angular(例如 Angular 10),该命令现已更新:
ng build --prod --aot --outputHashing=all
为我补充:
ng build --aot --output-hashing=all
当您的应用程序位于 CDN 和良好的缓存 nginx 配置后面时,仅构建命令是不够的。
1-第一件事是删除 html 文件的缓存(nginx):
location ~ \.(html)$ {
add_header Pragma "no-cache";
add_header Cache-Control "no-store";
add_header strict-transport-security "max-age=31536000";
add_header X-Frame-Options "SAMEORIGIN";
try_files $uri $uri/ /index.html;
}
对于静态文件(js/css ...),让缓存工作(网络性能/可用性):
location ~ \.(css|htc|less|js|js2|js3|js4)$ {
expires 31536000s;
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
try_files $uri $uri/ /index.html;
}
2- 保留 dev/prod 构建完全相同,用于测试目的。最终构建 dev 命令:
ng build --env=dev --aot=true --output-hashing=all --extract-css=true
3- 我们需要在每次部署时客户端浏览器从服务器而不是从缓存加载所有 javascript 文件,即使部署是一个小更新。就像 angular 有一些错误:https : //github.com/angular/angular-cli/issues/10641 并且发生在我身上。
我结束了使用 bash 的功能,这是我使用 package.json 文件在每个开发(prod/dev)上杀死缓存的脚本:
"scripts": {
...
"deploy_dev": "ng build --env=dev --aot=true --output-hashing=all --extract-css=true && npm run add_date",
"deploy_prd": "ng build --prod && npm run add_date",
"add_date": "npm run add_date_js && npm run add_date_css && npm run rm_bak_files",
"add_date_js": "for i in dist/*; do if [ -f $i ]; then LC_ALL=C sed -i.bak 's:js\":js?'$(date +%H%M%m%d%y)'\":g' $i; fi done",
"add_date_css": "sed -i.bak 's:css\":css?'$(date +%H%M%m%d%y)'\":g' dist/index.html",
"rm_bak_files": "find dist -name '*.bak' -exec rm -Rf {} \\;"
},
命令解释:
add_date_js:用“js?{date+%H%M%m%d%y}”查找并替换所有文件“js”
add_date_css:在dist/index.html中查找和替换“css”为“css? {date+%H%M%m%d%y}"
rm_bak_files:删除所有 .bak 文件(网络性能)
这些 sed 命令适用于 GNU/BSD/Mac。
链接:
Angular - Prod Build 不生成唯一的哈希值
sed 就地标志,适用于 Mac (BSD) 和 Linux
RE 错误:Mac OS X 上的非法字节序列
如果 shell 脚本内联
如何循环目录中的文件并更改路径和向文件名添加后缀
是否可以使用 angular-cli 构建单独的 CSS 文件?
虽然上面接受的答案会起作用,但应该angular.json
在configurations
=> <my-env-name>
=> outputHashing
=> 下设置为all
(对于生产环境)进行此调整。
简化示例:
{
"projects": {
"<my-project>": {
"architect": {
"build": {
"configurations": {
"<my-env-name>": {
"outputHashing": "all"
}
}
}
}
}
}
}
正如所述帖子中所述,此配置的可用选项:
- none : 不执行散列
- media : 只向通过 [url|file]-loaders 处理的文件添加哈希
- bundles:只向输出包添加哈希
- all:向媒体和捆绑包添加哈希