在本周的项目中, 因为涉及到ie兼容, 须要使用ie浏览器测试, 可是发现经过ng serve
启动的项目在ie中没法显示, 只有一个空白的页面, 可是ng build
的项目却能打开, 开始的时候本身也没多想, 一直将就着用打包的方式来调试, 仍是在潘老师找到解决办法, 并要求去解决这个问题后才去学习解决这个问题html
在仔细看了angular的官方文档后, 发现angular早已替咱们考虑了这个问题, 并直接给出了解决办法json
你在开发过程当中使用 TypeScript 编写的代码会被编译并打包成 ES2015,这种 JavaScript 语法兼容大多数浏览器。 全部现代浏览器都支持 ES2015 和更新的版本,可是大多数状况下,你仍然要让用户能从不支持它的浏览器中访问你的应用。 当以老式浏览器为目标时,腻子脚本(polyfills)能够提供一些老式浏览器中不存在的功能,从而抹平这种差距。浏览器
为了最大限度地提升兼容性,你能够发布一个包含全部已编译代码的发布包(bundle),以及全部可能会用到的腻子脚本。用户若是在支持大量最新 JavaScript 特性的现代浏览器中使用此应用,就不该该为这些他们用不到的包带来的额外体积付出代价。差别化加载就是解决这个问题的。Angular CLI 8 及更高版本默认就支持它。app
差别化加载是一种策略,它能让你的应用支持多种浏览器,可是只加载当前浏览器必须用到的代码。 当(默认)启用了差别化加载时,CLI 会构建出两个单独的包,做为你要发布的应用的一部分。ide
- 第一个包是使用现代的 ES2015 语法,它能发挥现代浏览器内置支持的优点,发布更少的腻子脚本,所以打包尺寸更小。
- 第二个包使用老式的 ES5 语法,包含全部必要的腻子脚本。其打包尺寸更大,可是支持老式浏览器。
咱们能够看到一个全新得angular项目打包后的目录以下:学习
<!--index.html--> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Angular</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> </head> <body> <app-root></app-root> <script src="runtime-es2015.js" type="module"></script> <script src="runtime-es5.js" nomodule defer></script> <script src="polyfills-es5.js" nomodule defer></script> <script src="polyfills-es2015.js" type="module"></script> <script src="styles-es2015.js" type="module"></script> <script src="styles-es5.js" nomodule defer></script> <script src="vendor-es2015.js" type="module"></script> <script src="vendor-es5.js" nomodule defer></script> <script src="main-es2015.js" type="module"></script> <script src="main-es5.js" nomodule defer></script> </body> </html>
每一个 script 标签都有一个type="module"
或nomodule
属性。原生支持 ES 模块的浏览器只会加载带有该类型属性的脚本,而忽略那些带有nomodule
属性的脚本。而老式浏览器只会加载带有nomodule
属性的脚本,而忽略那些 type 为module
的脚本标签。测试
须要注意的是有的浏览器所有代码都会下载, 但只会根据上述属性执行适当的脚本。
Angular CLI 第 8 版及更高版本已默认支持构建差别化加载的发布包。工做空间中的每一个应用项目,均可以根据其中的browserslist
和tsconfig.json
配置文件来决定发布包的构建方式。ui
更多相关内容,能够查看官方文档es5
看到这里, 仍是没说为何ng serve
不行, 缘由就是:spa
在 Angular CLI 版本 8 和更高版本中,默认状况下会为ng build
命令启用差别化加载。可是,ng serve
,ng test
和ng e2e
命令只会生成一个 ES2015 版本
因此咱们解决这个问题能够经过两种方式:
在tsconfig.json
旁新建一个tsconfig.es5.json
{ "extends": "./tsconfig.json", "compilerOptions": { "target": "es5" } }
angular.json
中的build
下的configurations
添加配置"es5": { "tsConfig": "./tsconfig.es5.json" }
angular.json
中的server
下的configurations
添加配置"es5": { "browserTarget": "AppName:build:es5" }
注意
:记得修改AppName
为你的项目得名字, 好比若个人项目为angular
则为:
"es5": { "browserTarget": "angular:build:es5" }
而后就可使用下面命令启动项目了
// 或者 ng serve -c es5 ng serve --configuration es5