4

在本周的项目中, 由于涉及到ie兼容, 需要使用ie浏览器测试, 但是发现通过ng serve启动的项目在ie中无法显示, 只有一个空白的页面, 但是ng build的项目却能打开, 开始的时候自己也没多想, 一直将就着用打包的方式来调试, 还是在潘老师找到解决办法, 并要求去解决这个问题后才去学习解决这个问题

解决办法

在仔细看了angular的官方文档后, 发现angular早已替我们考虑了这个问题, 并直接给出了解决办法

差异化加载

你在开发过程中使用 TypeScript 编写的代码会被编译并打包成 ES2015,这种 JavaScript 语法兼容大多数浏览器。 所有现代浏览器都支持 ES2015 和更新的版本,但是大多数情况下,你仍然要让用户能从不支持它的浏览器中访问你的应用。 当以老式浏览器为目标时,腻子脚本(polyfills)可以提供一些老式浏览器中不存在的功能,从而抹平这种差距。

为了最大限度地提高兼容性,你可以发布一个包含所有已编译代码的发布包(bundle),以及所有可能会用到的腻子脚本。用户如果在支持大量最新 JavaScript 特性的现代浏览器中使用此应用,就不应该为这些他们用不到的包带来的额外体积付出代价。差异化加载就是解决这个问题的。Angular CLI 8 及更高版本默认就支持它。

差异化加载是一种策略,它能让你的应用支持多种浏览器,但是只加载当前浏览器必须用到的代码。 当(默认)启用了差异化加载时,CLI 会构建出两个单独的包,作为你要发布的应用的一部分。

  • 第一个包是使用现代的 ES2015 语法,它能发挥现代浏览器内置支持的优势,发布更少的腻子脚本,因此打包尺寸更小。
  • 第二个包使用老式的 ES5 语法,包含所有必要的腻子脚本。其打包尺寸更大,但是支持老式浏览器。

我们可以看到一个全新得angular项目打包后的目录如下:
image.png

如何知道使用那些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 版及更高版本已默认支持构建差异化加载的发布包。工作空间中的每个应用项目,都可以根据其中的browserslisttsconfig.json配置文件来决定发布包的构建方式。

更多相关内容,可以查看官方文档

让ng serve支持ie10

看到这里, 还是没说为什么ng serve不行, 原因就是:

在 Angular CLI 版本 8 和更高版本中,默认情况下会为ng build命令启用差异化加载。但是,ng serveng testng e2e命令只会生成一个 ES2015 版本

所以我们解决这个问题可以通过两种方式:

  1. 直接修改ts编译为js时的版本, 让他变成支持ie的es5, 不过这会导致禁用差异化加载, 这方面的知识请查看差异化加载的官方文档
  2. 为ng serve 进行单独的配置

新建一个tsconfig

tsconfig.json旁新建一个tsconfig.es5.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "target": "es5"
  }
}

image.png

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

参考文章

angular 官方文档--部署


笙歌会停
1k 声望45 粉丝

代码成就万世基积沙镇海 梦想永在凌云意意气风发