在本周的项目中, 由于涉及到ie兼容, 需要使用ie浏览器测试, 但是发现通过ng serve
启动的项目在ie中无法显示, 只有一个空白的页面, 但是ng build
的项目却能打开, 开始的时候自己也没多想, 一直将就着用打包的方式来调试, 还是在潘老师找到解决办法, 并要求去解决这个问题后才去学习解决这个问题
解决办法
在仔细看了angular的官方文档后, 发现angular早已替我们考虑了这个问题, 并直接给出了解决办法
差异化加载
你在开发过程中使用 TypeScript 编写的代码会被编译并打包成 ES2015,这种 JavaScript 语法兼容大多数浏览器。 所有现代浏览器都支持 ES2015 和更新的版本,但是大多数情况下,你仍然要让用户能从不支持它的浏览器中访问你的应用。 当以老式浏览器为目标时,腻子脚本(polyfills)可以提供一些老式浏览器中不存在的功能,从而抹平这种差距。
为了最大限度地提高兼容性,你可以发布一个包含所有已编译代码的发布包(bundle),以及所有可能会用到的腻子脚本。用户如果在支持大量最新 JavaScript 特性的现代浏览器中使用此应用,就不应该为这些他们用不到的包带来的额外体积付出代价。差异化加载就是解决这个问题的。Angular CLI 8 及更高版本默认就支持它。
差异化加载是一种策略,它能让你的应用支持多种浏览器,但是只加载当前浏览器必须用到的代码。 当(默认)启用了差异化加载时,CLI 会构建出两个单独的包,作为你要发布的应用的一部分。
- 第一个包是使用现代的 ES2015 语法,它能发挥现代浏览器内置支持的优势,发布更少的腻子脚本,因此打包尺寸更小。
- 第二个包使用老式的 ES5 语法,包含所有必要的腻子脚本。其打包尺寸更大,但是支持老式浏览器。
我们可以看到一个全新得angular项目打包后的目录如下:
如何知道使用那些js代码呢
<!--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
配置文件来决定发布包的构建方式。
更多相关内容,可以查看官方文档
让ng serve支持ie10
看到这里, 还是没说为什么ng serve
不行, 原因就是:
在 Angular CLI 版本 8 和更高版本中,默认情况下会为ng build
命令启用差异化加载。但是,ng serve
,ng test
和ng e2e
命令只会生成一个 ES2015 版本
所以我们解决这个问题可以通过两种方式:
- 直接修改ts编译为js时的版本, 让他变成支持ie的es5, 不过这会导致禁用差异化加载, 这方面的知识请查看差异化加载的官方文档
- 为ng serve 进行单独的配置
新建一个tsconfig
在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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。