发布Angular应用至生产环境的方法


Posted in Javascript onDecember 10, 2018

两年前, 写过一篇使用rollup 来 为生产环境编译 Angular 2 应用 的文章, 因为当时还没有 angular-cli 项目。 而如今 Angular 已经到了 7.x 版本, 对应的工具也是非常的完善, 也就不在使用 rollup 来处理 angular 项目。

angular-cli 用起来虽然方便, 但是针对生产环境编译的话, 还是有一些地方要注意的, 接下来就介绍我在项目部署时的一些做法。

合理拆分功能模块, 按需加载

一个系统往往功能非常多, 因此就要根据项目的实际情况划分功能模块,一个功能模块对应一个 NgModule , 编译成一个独立的 js 文件, 再结合 angular 的路由技术进行按需加载,就这一功能点来说, angular 的支持已经非常的完善了。

const routes: Routes = [
  { path: '', redirectTo: '/home', pathMatch: 'full' },
  { path: 'home', loadChildren: './home/home.module#HomeModule' },
  { path: 'about', loadChildren: './about/about.module#AboutModule' },
  {
    path: 'arcgis',
    loadChildren: './arcgis/arcgis.module#ArcgisModule',
    canLoad: [EsriLoaderGuard]
  }
];

这一点经常容易被忽视, 曾经就出现过犹豫没有合理划分模块, 导致编译出来的 js 文件高达 5 兆, 造成的客户体验非常差。 (甚至还出现开发机内存不足,无法成功编译的情况)

预先压缩 js 文件

当然, 仅仅考合理划分 js 模块的话, 还往往不太够, 因为单个模块也可能会比较大, 可能会超过 1 兆, 特别是使用了一些第三方控件(ng-bootstrap, ng-zorro 等)的情况下。

针对这种情况, 通常还需要对编译生成的 js 文件进行 gzip 压缩, 因此在执行 ng build --prod 编译之后, 再继续执行下面的 shell 命令:

find dist -name "*.js" -print0 | xargs -0 gzip -k

当然, 如果发现编译生成 css 文件比较大的话, 也可以通过下面的命令进行压缩:

find dist -name "*.css" -print0 | xargs -0 gzip -k

以一个仅仅使用了 ng-bootstrap 的模板项目为例, 生成的 js 文件如下所示:

1.8K dist/ng-seed/4.1495aba38157395f4a2d.js
 1.7K dist/ng-seed/5.ec7eb27ea7c8eee53bcc.js
 482K dist/ng-seed/main.6ee651175769ea64ed5f.js
 37K dist/ng-seed/polyfills.5d61d41949cb87471fa8.js
 2.2K dist/ng-seed/runtime.c66e13242c809a55bd2f.js

其中的 main.6ee651175769ea64ed5f.js 就有 482KB , 而经过 gzip 压缩之后, 文件大小显著减小:

1.8K dist/ng-seed/4.1495aba38157395f4a2d.js
1.0K dist/ng-seed/4.1495aba38157395f4a2d.js.gz
1.7K dist/ng-seed/5.ec7eb27ea7c8eee53bcc.js
888B dist/ng-seed/5.ec7eb27ea7c8eee53bcc.js.gz
482K dist/ng-seed/main.6ee651175769ea64ed5f.js
124K dist/ng-seed/main.6ee651175769ea64ed5f.js.gz
 37K dist/ng-seed/polyfills.5d61d41949cb87471fa8.js
 12K dist/ng-seed/polyfills.5d61d41949cb87471fa8.js.gz
2.2K dist/ng-seed/runtime.c66e13242c809a55bd2f.js
1.2K dist/ng-seed/runtime.c66e13242c809a55bd2f.js.gz

main.6ee651175769ea64ed5f.js.gz 有 124KB , 只有原来的 1/4 。

一般来说, 对于 angular 项目编译出的 js 文件, gzip 压缩能减少 3/4 甚至 4/5 的体积, 这样将会显著减轻网络传输的压力。

使用 nginx 作为服务器

为什么使用 nginx 作为前端服务器呢? 原因如下:

支持传输预先压缩的 js 文件

将预先压缩好的 .js.gz 和原来的 .js 文件一起上传到服务器, 只要在 nginx 服务器的配置文件上加一句 gzip_static on; 即可启用,这样在客户端请求 .js 文件时, nginx 会先检查一下是否存在对应的 .js.gz 文件, 如果存在的话, 就直接返回 .js.gz 文件的内容, 从而省去了在服务端进行压缩的过程, 节省服务器的资源。

location /ng-app {
  root  /usr/share/nginx/html;
  index index.html index.htm;
  gzip_static on;
  try_files $uri /ng-app/index.html;
}

作为后台接口的网关

nginx 支持反向代理, 可以作为后台接口的网关, 这样可以省去一些跨域调用 (cors) 的问题, 一般的反向代理配置如下:

location /api {
  proxy_pass http://api-server:8080/api;
  proxy_read_timeout 600s;
  proxy_redirect off;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
}

官方的 docker 镜像

nginx 有 docker 的官方镜像, 部署、升级都是非常的方便。 不得不说docker 确实是好东西, 用了就停不下来了。

这几点都是在项目中积累的一些小技巧, 如果想要了解细节, 请查看这个ng-seed 项目。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS高级调试技巧:捕获和分析 JavaScript Error详解
Mar 16 Javascript
了不起的node.js读书笔记之例程分析
Dec 22 Javascript
jquery实现滑屏大图定时收缩为小banner图片的广告代码
Sep 02 Javascript
js ajaxfileupload.js上传报错的解决方法
May 05 Javascript
原生JavaScript编写canvas版的连连看游戏
May 29 Javascript
jQuery中Ajax全局事件引用方式及各个事件(全局/局部)执行顺序
Jun 02 Javascript
详解jQuery插件开发方式
Nov 22 Javascript
jQuery源码分析之init的详细介绍
Feb 13 Javascript
JavaScript中Require调用js的实例分享
Oct 27 Javascript
对vue.js中this.$emit的深入理解
Feb 23 Javascript
JS双向链表实现与使用方法示例(增加一个previous属性实现)
Jan 31 Javascript
django中使用vue.js的要点总结
Jul 07 Javascript
webpack优化的深入理解
Dec 10 #Javascript
BootStrap模态框闪退问题实例代码详解
Dec 10 #Javascript
详解为生产环境编译Angular2应用的方法
Dec 10 #Javascript
深入理解Vue.js轻量高效的前端组件化方案
Dec 10 #Javascript
es6基础学习之解构赋值
Dec 10 #Javascript
vue中将html字符串转换成html后遇到的问题小结
Dec 10 #Javascript
vue的.vue文件是怎么run起来的(vue-loader)
Dec 10 #Javascript
You might like
php实现学生管理系统
2020/03/21 PHP
php表单处理操作
2017/11/16 PHP
PHP 布尔值的自增与自减的实现方法
2018/05/03 PHP
原生js事件的添加和删除的封装
2014/07/01 Javascript
用js通过url传参把数据从一个页面传到另一个页面
2014/09/01 Javascript
Javascript基础教程之break和continue语句
2015/01/18 Javascript
JavaScript数组Array对象增加和删除元素方法总结
2015/01/20 Javascript
jQuery实现分隔条左右拖动功能
2015/11/21 Javascript
angularjs创建弹出框实现拖动效果
2020/08/25 Javascript
jQuery soColorPacker 网页拾色器
2016/06/22 Javascript
WebPack基础知识详解
2017/01/16 Javascript
详解用node编写自己的cli工具
2017/05/23 Javascript
AngularJS中使用three.js的实例详解
2017/07/21 Javascript
理解Koa2中的async&await的用法
2018/02/05 Javascript
[45:14]Optic vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
Python中模块pymysql查询结果后如何获取字段列表
2017/06/05 Python
python使用mysql的两种使用方式
2018/03/07 Python
django 通过ajax完成邮箱用户注册、激活账号的方法
2018/04/17 Python
利用Python如何批量更新服务器文件
2018/07/29 Python
Linux下python3.7.0安装教程
2018/07/30 Python
Django中使用Celery的方法示例
2018/11/29 Python
Python  Django 母版和继承解析
2019/08/09 Python
解决tensorflow由于未初始化变量而导致的错误问题
2020/01/06 Python
Python如何将函数值赋给变量
2020/04/28 Python
Python建造者模式案例运行原理解析
2020/06/29 Python
python中os.remove()用法及注意事项
2021/01/31 Python
印度首选时尚目的地:Reliance Trends
2018/01/17 全球购物
C语言笔试集
2012/07/24 面试题
如何转换一个字符串到enum值
2014/04/12 面试题
护士实习鉴定范文
2013/12/22 职场文书
质检部经理岗位职责
2014/02/19 职场文书
大学生社会实践评语
2014/04/25 职场文书
2014年会计人员工作总结
2014/12/10 职场文书
银行客户经理培训心得体会
2016/01/09 职场文书
2016年优秀共产党员先进事迹材料
2016/02/29 职场文书
go使用Gin框架利用阿里云实现短信验证码功能
2021/08/04 Golang