发布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 相关文章推荐
基于jQuery实现的水平和垂直居中的div窗口
Aug 08 Javascript
解析jQuery的三种bind/One/Live事件绑定使用方法
Dec 30 Javascript
分享一款基于jQuery的视频播放插件
Oct 09 Javascript
jQuery中removeAttr()方法用法实例
Jan 05 Javascript
详解AngularJS中的http拦截
Feb 09 Javascript
javascript实现简单的on事件绑定
Aug 23 Javascript
微信小程序 Windows2008 R2服务器配置TLS1.2方法
Dec 05 Javascript
JQuery form表单提交前验证单选框是否选中、删除记录时验证经验总结(整理)
Jun 09 jQuery
jQuery实现checkbox的简单操作
Nov 18 jQuery
VUE 配置vue-devtools调试工具及安装方法
Sep 30 Javascript
Elementui表格组件+sortablejs实现行拖拽排序的示例代码
Aug 28 Javascript
vue调用微信JSDK 扫一扫,相册等需要注意的事项
Jan 03 Vue.js
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 urlencode()与urldecode()函数字符编码原理详解
2011/12/06 PHP
php重定向的三种方法分享
2012/02/22 PHP
php生成随机密码自定义函数代码(简单快速)
2014/05/10 PHP
windows的文件系统机制引发的PHP路径爆破问题分析
2014/07/28 PHP
php实现的双向队列类实例
2014/09/24 PHP
Thinkphp搭建包括JS多语言的多语言项目实现方法
2014/11/24 PHP
关于URL最大长度限制的相关资料查证
2014/12/23 PHP
php实现读取和写入tab分割的文件
2015/06/01 PHP
PHP文件上传问题汇总(文件大小检测、大文件上传处理)
2015/12/24 PHP
php导出csv文件,可导出前导0实例代码
2016/11/16 PHP
php基于dom实现读取图书xml格式数据的方法
2017/02/03 PHP
php关联数组与索引数组及其显示方法
2018/03/12 PHP
PHP sdk文档处理常用代码示例解析
2020/12/09 PHP
jquery 子窗口操作父窗口的代码
2009/09/21 Javascript
jQuery 1.5 源码解读 面向中高阶JSER
2011/04/05 Javascript
jquery实现隐藏与显示动画效果/输入框字符动态递减/导航按钮切换
2013/07/01 Javascript
jquery实现textarea输入框限制字数的方法
2015/01/15 Javascript
理解jquery事件冒泡
2016/01/03 Javascript
JavaScript仿flash遮罩动画效果
2016/06/15 Javascript
使用JavaScript实现表格编辑器(实例讲解)
2017/08/02 Javascript
Angular @HostBinding()和@HostListener()用法
2018/03/05 Javascript
webpack@v4升级踩坑(小结)
2018/10/08 Javascript
vue使用一些外部插件及样式的配置代码
2019/11/18 Javascript
用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动
2015/11/05 Python
基于scrapy的redis安装和配置方法
2018/06/13 Python
python 标准差计算的实现(std)
2019/07/29 Python
Python 函数list&read&seek详解
2019/08/28 Python
python退出循环的方法
2020/06/18 Python
简单了解python关键字global nonlocal区别
2020/09/21 Python
廉政教育心得体会
2014/01/01 职场文书
《走一步再走一步》教学反思
2014/02/15 职场文书
法人代表委托书
2014/04/04 职场文书
2014小学生国庆65周年演讲稿
2014/09/21 职场文书
天气温馨提示语
2015/07/14 职场文书
自己搭建resnet18网络并加载torchvision自带权重的操作
2021/05/13 Python
Python Pandas pandas.read_sql_query函数实例用法分析
2021/06/21 Python