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 發布部署
- 第九章 總結