React+Antd 项目兼容ie8的几座大山

新公司的业务是面向政府项目,然而政府项目的需求现状是会需要去兼容ie9以下版本。大量未升级的XP版本即使强制使用浏览器最高版本也只有到ie8。那么基于客户要求至上的原则,花费精力在低版本ie兼容上还是存在合理性的。

一、 技术栈选型

前后端分离对于IE兼容项目尤其是要兼容到IE8以下版本就是奇葩的存在,在整个babel编译过程从ES6 -> ES5 -> ES3之外,还要修复兼容一系列IE低版本本身不支持的api. 以及一系列怪异的样式问题。

然而工作还是要继续,恰当的技术选型就比较关键了,现在比较主流的处理方式就是做版本库降级,例如: react v0.16.4 + webpack v1.15.0 + react-router v2.3.0 + babel-polyfill + es5-shim等一系列降级库和垫片来处理。

在这里我们采用司徒正妹的anujs库,作为IE兼容狂魔的代表作我们都知道avalon。其实他还设计了一个基于React16版本的库,也就是anujs. 我们可以通过它来实现 react16 + webpack4.x + reach-router 来使用最新的前后端分离的工程技术栈进行开发。突然感觉到了一丝强大。

二、 webpack 环境搭建

这里我们基于react-dev-utils搭建一个类似于create-react-app的脚手架。这里为什么不直接用create-react-app呢? 这里主要有三个原因:

  1. 我们希望webpack工程能具有一定的灵活性
  2. 防止部分脚手架功能导致IE报错。
  3. 同时进行多项目的统一脚手架配置。
    (我们最近的改版项目涉及到30多个省市的项目,每个项目近乎独立,所以在jenkins自动化部署上,最好能配置单一脚手架实现多项目托管。)

三、IE兼容条目

compat.js

主要基于es-shim库做一些函数API兼容并加入Map定义的覆盖,UA的IE判断等。

分割打包initial模式的模块

  1. object-create-ie8(替代es-sham)
  2. object-defineproperty-ie8 (兼容object.defineproperty)
  3. console-polyfill (兼容console)
  4. bluebird (兼容Promise)
  5. fetch-polyfill2 (兼容fetch请求)

anujs的React兼容体系

  1. ReactIE - 对React16添加了一些特殊事件的兼容补丁与innerHTML的修复处理
  2. createClass - 对React的createClass进行兼容
  3. Reach-router - 对react路由进行兼容,值得注意的是IE9以下只能使用hash模式 (也可以使用低版本的react-router)

webpack的plugin

es3ify-plugin - 修复关键字在IE8中不能作为属性名和方法名,例如modue.default而default作为关键字会在IE8中报错。

四、Antd1.11.x的兼容

react的兼容只是顺利进行IE版本开发的一半,下面针对一些UI库还需要进行一些处理。

  1. rc-calendar - Picker.js - forcus报错 空对象 更换rc-calendar v7.5.3

  2. 点击下拉select报错 - dom-align - v.1.6.7 - rc-align - v.2.3.6

  3. select下拉样式错误 - dom-align fixTop修复

  4. pagination 报错 - 使用 rc-pagination 1.8.10版本

  5. Map 在IE11有自己的实现定义且区别于ES6的Map, 所以要重新定义Map

  6. window.matchMedia 未定义, 安装media-match 兼容

  7. IE10下面antd form组件中的input事件在placeholder为中文的情况下初始化会执行自动执行,导致二次渲染。