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) | 构造与本地服务器 |