Angular < 13:如何支持 IE11
补充:从 ANGULAR V13 开始,IE11 不再受支持。如果您需要支持 IE11,请使用 ANGULAR V13 及以下版本。
在本文中,我将向您展示我使用 Angular 支持 Internet Explorer 11 的步骤。前半部分将快速展示您需要执行的步骤,后半部分将更详细地分解这些步骤,以便任何想要了解更多信息的人都能理解。最后,我将添加一些在实际应用中可能用到的额外技巧。
💪 让我们完成它
🎯 步骤 1 - 以 ES5 为目标
IE11 最多只支持 ES5。因此,我们必须更新tsconfig.json
。如果尚未更新,
请更新target
中的属性compilerOptions
以匹配以下内容:
"compilerOptions": {
...
"target": "es5"
}
🌐 第 2 步 - 更新broswerlist
打开browserlist
文件并更改以下行not IE 9-11
以匹配:
not IE 9-10
IE 11
🔧 步骤 3 - Polyfills
如果您或您的任何依赖项使用了 ES6+ 的功能,则需要对这些功能进行 polyfill。CoreJS 包含在 Angular 安装中,可用于您需要的大部分 polyfill。
打开polyfills.ts
文件并将以下内容放在顶部BROWSER POLYFILLS
:
如果您需要快速获胜(不推荐):
import 'core-js';
否则,请尝试辨别你需要哪些 polyfill。我发现这些 polyfill 满足我的用例:
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';
import 'core-js/es6/array';
import 'core-js/es7/array'; // for .includes()
我们接下来要做的就是找到靠近顶部的以下几行polyfills.ts
:
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
按照指示运行:npm install --save classlist.js
然后取消注释导入:
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
import 'classlist.js'; // Run `npm install --save classlist.js`.
如果您使用 Angular Material 或AnimationBuilder
from @angular/platform-browser/animations
,则找到以下行:
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
取消注释并运行npm install --save web-animations-js
。
您的最终polyfills.ts
文件应类似于:
/**
* This file includes polyfills needed by Angular and is loaded before the app.
* You can add your own extra polyfills to this file.
*
* This file is divided into 2 sections:
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
* file.
*
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
*
* Learn more in https://angular.io/guide/browser-support
*/
/***************************************************************************************************
* BROWSER POLYFILLS
*/
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';
import 'core-js/es6/array';
import 'core-js/es7/array'; // for .includes()
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
import 'classlist.js'; // Run `npm install --save classlist.js`.
/**
* Web Animations `@angular/platform-browser/animations`
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
*/
import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/**
* By default, zone.js will patch all possible macroTask and DomEvents
* user can disable parts of macroTask/DomEvents patch by setting following flags
* because those flags need to be set before `zone.js` being loaded, and webpack
* will put import in the top of bundle, so user need to create a separate file
* in this directory (for example: zone-flags.ts), and put the following flags
* into that file, and then add the following code before importing zone.js.
* import './zone-flags.ts';
*
* The flags allowed in zone-flags.ts are listed here.
*
* The following flags will work for all browsers.
*
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
* (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge
*
* (window as any).__Zone_enable_cross_context_check = true;
*
*/
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/
import 'zone.js/dist/zone'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS
*/
✅ 已完成
就这样!你就可以出发了!🚀🚀
您可能会遇到更多问题。本文的后半部分将讨论其中一些问题。
🤯但是为什么呢?
在我们进一步讨论可能出现的其他问题的提示之前,让我们快速了解一下上述每个步骤的原因。
- 目标 ES5:很简单,IE11 仅支持 ES5 或更低版本。因此,TypeScript 需要将你的代码转译为兼容 ES5 的代码。
- Browserlist:这个问题很有意思。我们需要声明我们支持 IE 11,但如果我们不支持 IE 9 或 10,同样重要的是明确声明我们不支持它们,否则差异加载器会包含很多废话。(感谢@wescopeland_的建议)
- Polyfill - 我们使用的一些库或编写的代码依赖于 IE11 不支持的 ECMAScript 版本功能,因此我们需要使用变通方法手动将此功能引入 ES5。这样,使用现代功能的代码才能继续正常工作。(注意:每个 polyfill 都会增加包的大小,因此在选择导入哪些 polyfill 时要谨慎)
💡 一些额外的提示
好吧,写这篇文章的动机来自于我们被要求在我们的新应用中支持 IE11。这尤其令人痛苦,因为事后才发现支持 IE11 的兼容性问题:
第三方依赖项需要支持 ES5
错误很容易就被吐到控制台里,这一点很快就显现出来了。但这确实凸显了一个有趣的问题。
现在,如果我们想在应用程序中添加一个新的依赖项或库,我们需要确保它构建到并支持 ES5,否则就不得不跳过它。这可能会限制我们未来的选择,这从来都不是理想的选择。
IE11 不支持 CSS 自定义属性
这很快就变成了地狱。IE11 不支持 CSS 自定义属性,这--primary-color: blue;
意味着我们的主题解决方案可能陷入困境。
经过大量调查,我发现可以使用 polyfill 来解决这个问题,然而,我找到的 polyfill 运行速度很慢,对包大小影响很大,而且并不完美。此外,还缺少一些功能,例如在一行代码中设置多个自定义属性。
这些 polyfill 也不适用于我们的特定用例和依赖于运行时设置自定义属性的主题解决方案。
我的解决方案是使用css-vars-ponyfill,它允许在运行时设置全局自定义属性。太棒了🔥🔥
style
在 IE11 中设置属性
style
IE11 仅允许使用其支持的 CSS 属性来设置 DOM 元素的属性。
例如,执行以下操作:
document.body.style = '--primary-color: blue; font-size: 18px';
在 IE11 上会导致以下结果,丢失--primary-color: blue
。
<body style="font-size: 18px"></body>
弹性框支持引起的样式问题
IE11 确实支持 flexbox,但它对 flexbox 的使用方式非常挑剔。我注意到,如果我想让flex: 1;
元素填满剩余空间,在 IE11 上我必须设置 full flex 属性:flex: 1 0 auto;
或类似的属性。
在 IE11 中运行 DevTools 与 zone.js 冲突
ng serve
是的。出于某种原因,在IE11 上运行时打开开发工具会与 发生冲突zone.js
;
要解决这个问题,你需要添加一个全局的ZONE FLAG
for 区域来执行一些额外的代码。
你可以在 中执行此操作polyfills.ts
。找到zone.js
导入并添加以下内容,使其看起来像这样:
(window as any).__Zone_enable_cross_context_check = true;
import 'zone.js/dist/zone'; // Included with Angular CLI.
😭 结论
这周我尝试着把它弄好,结果并不尽兴。现在终于支持上了,感觉很有成就感💪。
希望这篇文章以后能帮大家省点事!
希望您通过阅读本文有所收获,也许是一些您以前不知道的小知识。
如果您有任何疑问,请随时在下面提问或在 Twitter 上联系我:@FerryColum。
鏂囩珷鏉ユ簮锛�https://dev.to/coly010/angular-how-to-support-ie11-4924