发布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 相关文章推荐
ie focus bug 解决方法
Sep 03 Javascript
jQuery中:last选择器用法实例
Dec 30 Javascript
JavaScript中的数据类型转换方法小结
Oct 26 Javascript
浅谈JavaScript 浏览器对象
Jun 03 Javascript
AngularJs IE Compatibility 兼容老版本IE
Sep 01 Javascript
Jquery AJAX POST与GET之间的区别详细介绍
Oct 17 Javascript
基于Bootstrap table组件实现多层表头的实例代码
Sep 07 Javascript
vue axios 在页面切换时中断请求方法 ajax
Mar 05 Javascript
vue.js 实现评价五角星组件的实例代码
Aug 13 Javascript
koa2实现登录注册功能的示例代码
Dec 03 Javascript
vue.js中使用echarts实现数据动态刷新功能
Apr 16 Javascript
Vuex 模块化使用详解
Jul 31 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的header和asp中的redirect比较
2006/10/09 PHP
PHP Header用于页面跳转要注意的几个问题总结
2008/10/03 PHP
ThinkPHP关于session的操作方法汇总
2014/07/18 PHP
关于 Laravel Redis 多个进程同时取队列问题详解
2017/12/25 PHP
PHP基于openssl实现非对称加密代码实例
2020/06/19 PHP
JQuery Easyui Tree的oncheck事件实现代码
2010/05/28 Javascript
jquery 学习之二 属性(html()与html(val))
2010/11/25 Javascript
Script的加载方法小结
2011/01/12 Javascript
jquery的$getjson调用并获取远程的JSON字符串问题
2012/12/10 Javascript
js编码、解码函数介绍及其使用示例
2013/09/05 Javascript
Jquery Ajax解析XML数据(同步及异步调用)简单实例
2014/02/12 Javascript
jQuery DOM操作实例
2014/03/05 Javascript
JavaScript实现获取dom中class的方法
2015/02/09 Javascript
js简单网速测试方法完整实例
2015/12/15 Javascript
easyui tree带checkbox实现单选的简单实例
2016/11/07 Javascript
JavaScript实现事件的中断传播和行为阻止方法示例
2017/01/20 Javascript
input获取焦点时底部菜单被顶上来问题的解决办法
2017/01/24 Javascript
node.js利用redis数据库缓存数据的方法
2017/03/01 Javascript
js实现点击按钮复制文本功能
2020/07/20 Javascript
如何以Angular的姿势打开Font-Awesome详解
2018/04/22 Javascript
vue+axios+mock.js环境搭建的方法步骤
2018/08/28 Javascript
vue element 中的table动态渲染实现(动态表头)
2019/11/21 Javascript
jquery实现直播弹幕效果
2019/11/28 jQuery
用Angular实现一个扫雷的游戏示例
2020/05/15 Javascript
[01:54]TI4西雅图DOTA2选手欢迎晚宴 现场报道
2014/07/08 DOTA
Python读大数据txt
2016/03/28 Python
小白入门篇使用Python搭建点击率预估模型
2018/10/12 Python
Python中函数的基本定义与调用及内置函数详解
2019/05/13 Python
Python使用import导入本地脚本及导入模块的技巧总结
2019/08/07 Python
Europcar英国:英国汽车和货车租赁
2017/01/21 全球购物
大学生求职简历的自我评价范文
2013/10/12 职场文书
乡镇防汛工作汇报
2014/10/28 职场文书
发票退票证明
2015/06/24 职场文书
和领导吃饭祝酒词
2015/08/11 职场文书
2016元旦主持人开场白
2015/12/03 职场文书
微信小程序结合ThinkPHP5授权登陆后获取手机号
2021/11/23 PHP