Angular的项目开发完毕后,最终的目标是将其发布到生产环境的服务器上。即使我们在开发中使用了多模块等概念,但其最终的本质仍然是一个html+css+javascript的web页面。该web页面,最终仍将被发布到web服务器上。
Angular Cli提供的`ng build`命令的作用便是将一个使用TypeScript编写的Angular项目最终变成web服务器可以提供服务、浏览器可以识别的html + css + javascript项目。
## ng build
进入项目根路径,执行`ng build`即开始进行应用的打包。打包要经过编译、压缩等过程,依个人电脑配置情况打包时间有快有慢。而我们要做的是等待以及查看提示信息:
```bash
panjie@panjies-iMac first-app % ng build
Your global Angular CLI version (11.2.13) is greater than your local version (11.0.7). The local Angular CLI version is used.
To disable this warning use "ng config -g cli.warnings.versionMismatch false".
✔ Browser application bundle generation complete.
✔ Copying assets complete.
✔ Index html generation complete.
Initial Chunk Files | Names | Size
vendor.js | vendor | 2.70 MB
scripts.js | scripts | 1.35 MB
styles.css | styles | 245.69 kB
polyfills.js | polyfills | 141.32 kB
main.js | main | 87.54 kB
runtime.js | runtime | 9.07 kB
| Initial Total | 4.53 MB
Lazy Chunk Files | Names | Size
student-student-module.js | student-student-module | 168.44 kB
clazz-clazz-module.js | clazz-clazz-module | 41.03 kB
common.js | common | 12.05 kB
Build at: 2021-06-15T02:09:23.898Z - Hash: dde0ff7b4d26726c0470 - Time: 6813ms
Warning: /Users/panjie/github/mengyunzhi/angular11-guild/first-app/src/app/student/student.component.ts depends on 'notiflix'. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies
```
运行成功后,将在根目录下生成`disk`文件夹:
```bash
panjie@panjies-iMac first-app % tree -L 1
.
├── README.md
├── angular.json
├── dist 👈
├── e2e
├── karma.conf.js
├── node_modules
├── package-lock.json
├── package.json
├── src
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.spec.json
└── tslint.json
4 directories, 9 files
```
在该文件夹下生成以当前项目名命名的文件夹
```bash
panjie@panjies-iMac first-app % tree dist
dist
└── first-app 👈
├── assets
│ └── teacher-all.json
├── clazz-clazz-module.js
├── clazz-clazz-module.js.map
├── common.js
├── common.js.map
├── fa-brands-400.eot
├── fa-brands-400.svg
├── fa-brands-400.ttf
├── fa-brands-400.woff
├── fa-brands-400.woff2
├── fa-regular-400.eot
├── fa-regular-400.svg
├── fa-regular-400.ttf
├── fa-regular-400.woff
├── fa-regular-400.woff2
├── fa-solid-900.eot
├── fa-solid-900.svg
├── fa-solid-900.ttf
├── fa-solid-900.woff
├── fa-solid-900.woff2
├── favicon.ico
├── index.html
├── main.js
├── main.js.map
├── polyfills.js
├── polyfills.js.map
├── runtime.js
├── runtime.js.map
├── scripts.js
├── scripts.js.map
├── student-student-module.js
├── student-student-module.js.map
├── styles.css
├── styles.css.map
├── vendor.js
└── vendor.js.map
2 directories, 36 files
```
该文件夹下即为最终托管到web服务器上的网页文件,把该文件配置到相关的web服务上,则可以在对应的地址上打开我们当前的应用了(下节内容)。
## ng build --prod
使用`ng build`打包的项目虽然可用,但由于未经过压缩处理。未压缩将至少导致两个问题:一、最终生成的文件不够小;二、生成的`map`文件无意中暴露了当前项目的源代码。
```bash
panjie@panjies-iMac first-app % ls -a -l -h -S| awk '{print $5, $9}'
2.8M vendor.js.map
2.7M vendor.js
1.4M scripts.js.map
1.4M scripts.js
896K fa-solid-900.svg
730K fa-brands-400.svg
608K styles.css.map
246K styles.css
200K fa-solid-900.eot
200K fa-solid-900.ttf
168K student-student-module.js
159K polyfills.js.map
154K student-student-module.js.map
141K fa-regular-400.svg
141K polyfills.js
134K fa-brands-400.eot
133K fa-brands-400.ttf
102K fa-solid-900.woff
90K fa-brands-400.woff
88K main.js
78K fa-solid-900.woff2
77K fa-brands-400.woff2
42K main.js.map
41K clazz-clazz-module.js
34K fa-regular-400.eot
33K fa-regular-400.ttf
21K clazz-clazz-module.js.map
16K fa-regular-400.woff
13K fa-regular-400.woff2
12K common.js
9.2K runtime.js.map
9.1K runtime.js
8.3K common.js.map
1.2K .
948B favicon.ico
540B index.html
96B ..
96B assets
```
也就是说`ng build`的作用是打包一个我们自用、可排查错误的项目,而非最终应用到生产环境中的项目。若打包为最终应用到生产环境中的项目,则需要执行:`ng build --prod`。
再次来到项目根文件夹(这很重要),执行:`ng build --prod`
```bash
panjie@panjies-iMac first-app % ng build --prod
Your global Angular CLI version (11.2.13) is greater than your local version (11.0.7). The local Angular CLI version is used.
To disable this warning use "ng config -g cli.warnings.versionMismatch false".
✔ Browser application bundle generation complete.
Warning: /Users/panjie/github/mengyunzhi/angular11-guild/first-app/src/app/student/student.component.ts depends on 'notiflix'. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies
Warning: budgets: initial exceeded maximum budget. Budget 500.00 kB was not met by 1.33 MB with a total of 1.82 MB.
Error: budgets: initial exceeded maximum budget. Budget 1.00 MB was not met by 837.67 kB with a total of 1.82 MB.
```
此时`ng build --prod`在执行时返回了两个waring,一个Error。而Error信息直接导致了当前命令未执行成功。
在前期学习的阶段,Warning我们大可不去管它。而`Error`错误,则需要先进行翻译,然后再根据翻译得到的提示信息尝试完成修正:
```bash
Error: budgets: initial exceeded maximum budget. Budget 1.00 MB was not met by 837.67 kB with a total of 1.82 MB.
错误:预算错误:初始值超出了预算. 总预算是1.00MB,但是当前却消耗了1.82M,超出预算的部分是837.67K。
```
其实它是在说:Angular被打包后,用户首次加载的文件太大了。当前项目设置的最大值为1MB,但在打包过程中发现,打完包后的值却是1.82M。之所以要将用户首次加载的文件控制在一定的范围内,是因为Angular充分的考虑了用户的网络情况,1M的首次加载数据能够保证用户在1M的带宽下,首次加载当前项目的时候在8秒;如果在2M带宽下,首次加载的时间在4S。
我们项目的首次加载文件之所以这么大,原因除了有一些惰性加载没有做好外,更多的原因是由于在项目启动中加入了`bootstrap`。虽然我们有办法对加载`bootstrap`做进一步的优化,但这超出了当前教程的范围(实际的生产项目我们也很少这么做)。
在此我们使用提升预算的方法来解决当前错误。项目首次加载文件预算位于`angular.json`文件中:
```json
+++ b/first-app/angular.json
@@ -57,8 +57,8 @@
"budgets": [
{
"type": "initial",
- "maximumWarning": "500kb",
- "maximumError": "1mb"
+ "maximumWarning": "1mb",
+ "maximumError": "2mb"
},
{
"type": "anyComponentStyle",
```
在此我们将警告值由500kb变更为1mb,将错误值由1mb变更为2mb。然后重新在项目根目录下运行`ng build --prod`:
```bash
panjie@panjies-iMac first-app % ng build --prod
Your global Angular CLI version (11.2.13) is greater than your local version (11.0.7). The local Angular CLI version is used.
To disable this warning use "ng config -g cli.warnings.versionMismatch false".
✔ Browser application bundle generation complete.
✔ Copying assets complete.
✔ Index html generation complete.
Initial Chunk Files | Names | Size
scripts.870ccd5bd57ddc84e32a.js | scripts | 1.29 MB
main.302cc966966378d1c107.js | main | 306.64 kB
styles.7a2b02e3a74270bbd4b1.css | styles | 199.11 kB
polyfills.7a965888daba3fbc4385.js | polyfills | 36.00 kB
runtime.c703a15d5cbc5cde45e0.js | runtime | 2.28 kB
| Initial Total | 1.82 MB
Lazy Chunk Files | Names | Size
5.bb83e225da7f321d3252.js | - | 101.33 kB
6.09fc147df954698f64ee.js | - | 9.26 kB
common.4657a0e4116b66403048.js | common | 3.02 kB
Build at: 2021-06-15T03:11:42.146Z - Hash: f1dde790ea6b2a0c613a - Time: 11913ms
Warning: /Users/panjie/github/mengyunzhi/angular11-guild/first-app/src/app/student/student.component.ts depends on 'notiflix'. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies
Warning: budgets: initial exceeded maximum budget. Budget 1.00 MB was not met by 837.67 kB with a total of 1.82 MB.
```
此时错误信息消息,打包成功。上述信息提示我们说初始化要加载的资源有5个,总大小为1.82M;惰性加载的文件有3个(共114K)。
此时打包后所有的文件列表如下:
```bash
panjie@panjies-iMac first-app % ls -a -l -h -S| awk '{print $5, $9}'
1.3M scripts.870ccd5bd57ddc84e32a.js
896K fa-solid-900.0454203f26b33fc02e2b.svg
730K fa-brands-400.991c1c761fc31f9c3252.svg
307K main.302cc966966378d1c107.js
200K fa-solid-900.6606667d9800a27eb8b5.eot
200K fa-solid-900.915a0b79c22a1c1f64da.ttf
199K styles.7a2b02e3a74270bbd4b1.css
141K fa-regular-400.f3187c7462849ed261a8.svg
134K fa-brands-400.98f20b9ec79b2fee02a3.eot
133K fa-brands-400.330e879afe4a0abb35f2.ttf
102K fa-solid-900.f4f93856730733912b1e.woff
101K 5.bb83e225da7f321d3252.js
90K fa-brands-400.5f63cb7f47b6ea89773b.woff
78K fa-solid-900.3eb06c702e27fb110194.woff2
77K fa-brands-400.6e63bd22128f27b83f22.woff2
36K polyfills.7a965888daba3fbc4385.js
34K fa-regular-400.62a07ffeac77696f17ef.eot
33K fa-regular-400.ac2367644e559de4ff33.ttf
17K 3rdpartylicenses.txt
16K fa-regular-400.ea5a41ec4a24ce93298e.woff
13K fa-regular-400.2c154b0f8c0d8d166162.woff2
9.3K 6.09fc147df954698f64ee.js
3.0K common.4657a0e4116b66403048.js
2.3K runtime.c703a15d5cbc5cde45e0.js
948B favicon.ico
928B .
606B index.html
96B ..
96B assets
```
相较于没有使用`--prod`参数,使用了该参数后打包生成的文件明显变小。同时还删除了没有用的`map`文件,如果有你兴趣打开任意一个,会发现里面的内容好像不是自己写的一样。在文件命名上,每个文件名都加入一串hash后的字符串,这种做好还可以有效的防止浏览器缓存,为日后的升级扫清了部分障碍。
## 环境变量
`ng build --prod`还使用在`environments`中的`environment.prod.ts`文件中的内容开始生效:
```typescript
export const environment = {
production: true,
size: 20
};
```
此时,如若我们将当前项目部署到web服务器上,则每页大小将是20。
## 本节资源
| 链接 | 名称 |
| ------------------------------------------------------------ | ---------------- |
| [https://github.com/mengyunzhi/angular11-guild/archive/step8.1.zip](https://github.com/mengyunzhi/angular11-guild/archive/step8.1.zip) | 本节源码 |
| [https://angular.cn/guide/build](https://angular.cn/guide/build) | 构造与本地服务器 |
- 序言
- 第一章 Hello World
- 1.1 环境安装
- 1.2 Hello Angular
- 1.3 Hello World!
- 第二章 教师管理
- 2.1 教师列表
- 2.1.1 初始化原型
- 2.1.2 组件生命周期之初始化
- 2.1.3 ngFor
- 2.1.4 ngIf、ngTemplate
- 2.1.5 引用 Bootstrap
- 2.2 请求后台数据
- 2.2.1 HttpClient
- 2.2.2 请求数据
- 2.2.3 模块与依赖注入
- 2.2.4 异步与回调函数
- 2.2.5 集成测试
- 2.2.6 本章小节
- 2.3 新增教师
- 2.3.1 组件初始化
- 2.3.2 [(ngModel)]
- 2.3.3 对接后台
- 2.3.4 路由
- 2.4 编辑教师
- 2.4.1 组件初始化
- 2.4.2 获取路由参数
- 2.4.3 插值与模板表达式
- 2.4.4 初识泛型
- 2.4.5 更新教师
- 2.4.6 测试中的路由
- 2.5 删除教师
- 2.6 收尾工作
- 2.6.1 RouterLink
- 2.6.2 fontawesome图标库
- 2.6.3 firefox
- 2.7 总结
- 第三章 用户登录
- 3.1 初识单元测试
- 3.2 http概述
- 3.3 Basic access authentication
- 3.4 着陆组件
- 3.5 @Output
- 3.6 TypeScript 类
- 3.7 浏览器缓存
- 3.8 总结
- 第四章 个人中心
- 4.1 原型
- 4.2 管道
- 4.3 对接后台
- 4.4 x-auth-token认证
- 4.5 拦截器
- 4.6 小结
- 第五章 系统菜单
- 5.1 延迟及测试
- 5.2 手动创建组件
- 5.3 隐藏测试信息
- 5.4 规划路由
- 5.5 定义菜单
- 5.6 注销
- 5.7 小结
- 第六章 班级管理
- 6.1 新增班级
- 6.1.1 组件初始化
- 6.1.2 MockApi 新建班级
- 6.1.3 ApiInterceptor
- 6.1.4 数据验证
- 6.1.5 教师选择列表
- 6.1.6 MockApi 教师列表
- 6.1.7 代码重构
- 6.1.8 小结
- 6.2 教师列表组件
- 6.2.1 初始化
- 6.2.2 响应式表单
- 6.2.3 getTestScheduler()
- 6.2.4 应用组件
- 6.2.5 小结
- 6.3 班级列表
- 6.3.1 原型设计
- 6.3.2 初始化分页
- 6.3.3 MockApi
- 6.3.4 静态分页
- 6.3.5 动态分页
- 6.3.6 @Input()
- 6.4 编辑班级
- 6.4.1 测试模块
- 6.4.2 响应式表单验证
- 6.4.3 @Input()
- 6.4.4 FormGroup
- 6.4.5 自定义FormControl
- 6.4.6 代码重构
- 6.4.7 小结
- 6.5 删除班级
- 6.6 集成测试
- 6.6.1 惰性加载
- 6.6.2 API拦截器
- 6.6.3 路由与跳转
- 6.6.4 ngStyle
- 6.7 初识Service
- 6.7.1 catchError
- 6.7.2 单例服务
- 6.7.3 单元测试
- 6.8 小结
- 第七章 学生管理
- 7.1 班级列表组件
- 7.2 新增学生
- 7.2.1 exports
- 7.2.2 自定义验证器
- 7.2.3 异步验证器
- 7.2.4 再识DI
- 7.2.5 属性型指令
- 7.2.6 完成功能
- 7.2.7 小结
- 7.3 单元测试进阶
- 7.4 学生列表
- 7.4.1 JSON对象与对象
- 7.4.2 单元测试
- 7.4.3 分页模块
- 7.4.4 子组件测试
- 7.4.5 重构分页
- 7.5 删除学生
- 7.5.1 第三方dialog
- 7.5.2 批量删除
- 7.5.3 面向对象
- 7.6 集成测试
- 7.7 编辑学生
- 7.7.1 初始化
- 7.7.2 自定义provider
- 7.7.3 更新学生
- 7.7.4 集成测试
- 7.7.5 可订阅的路由参数
- 7.7.6 小结
- 7.8 总结
- 第八章 其它
- 8.1 打包构建
- 8.2 发布部署
- 第九章 总结