react项目如何兼容ie11 。。。

959 阅读5分钟
react项目 兼容ie11 ?
  • 为啥需要兼容ie,我觉得是自己脑子不好了,慕名奇妙的觉得自己是不是需要证明一下。。。 反正是个不好的事情。

  • 下面就是为自己脑子不好做出了解答。

    首先需要了解怎么去兼容,从什么地方入手,我想到的是webpack编译,那么编译就需要了解babel,首先打开项目,当时搭建项目 babel 是7.x版本,还要安装 core-js,这些都是基本需要,当时项目做了一个按需解析兼容

 {
       test: /\.(t|j)sx?/,
       use: {
         loader: 'babel-loader',
         options: {
           presets: [
             [
               '@babel/preset-env',
               {
                 useBuiltIns: 'usage', // 按需加载
                 corejs: 3, // corejs 替代了以前的pollyfill
               },
             ],
             '@babel/preset-react',
             '@babel/preset-typescript',
           ],
           plugins: [
             '@babel/plugin-proposal-export-default-from',
             '@babel/plugin-transform-modules-commonjs',
             '@babel/plugin-transform-runtime',
             ['@babel/plugin-proposal-decorators', { legacy: true }],
             ['@babel/plugin-proposal-class-properties', { loose: true }],
             ['@babel/plugin-proposal-private-methods', { loose: true }],
             [
               '@babel/plugin-proposal-object-rest-spread',
               { loose: true, useBuiltIns: true },
             ],
             [
               '@babel/plugin-proposal-private-property-in-object',
               { loose: true },
             ],
             [
               'import',
               { libraryName: 'antd', libraryDirectory: 'lib', style: true },
             ],
             process.env.NODE_ENV !== 'production' && [
               'react-refresh/babel',
               { skipEnvCheck: true },
             ],
           ].filter(Boolean),
         },
  },

然后打包发现ie直接白屏,我就知道没那么顺利,查询度娘,了解需要在根目录.browserslistrc 添加这个文件,cover 99.5%,然后看到了,编译代码里面的()=> 函数编译成了 function,之前报错就是这个问题,心想这次应该成功了,然而报错,有点懵逼,根据ie报错找到,crypto-js 这个加密解密插件问题,因为这个插件本身编译不支持ie11,我们在babel 编译根本没有去解析,这个时候找到exclude 这个是rules 插件,让 node_modules 里面这个插件也去解析 if (id.includes('crypto-js')) return false 在exclude这个函数添加排除,然后打包,发现打包一半出现导出错误,这就心态炸裂,,,只有为什么,然后我就搞的难受,,,就明天在看了。。。

       第二天继续,,,我就不信邪了啊,,,然后继续研究,再想,babel打包的代码是默认iife的。确实没有导出,所以在插件里面也确实引用不到,看到这里又卡住了,怎么直接编译成可以导出的,自己编写这样的插件,感觉实力不到位,,,只能把babel 官网在看一下,终于找到'@babel/plugin-transform-modules-commonjs 这个插件该插件将 ECMAScript 模块转换为CommonJS。理论上应该是这个,于是抱着试试的心态,测试了一下成功了,打包正常,然后重新打开ie测试,发现一如之前一样的白屏,这个是时候心态不知道啥感觉,以上已经花了大半天的时间定位了,,,然后继续查询,发现是redux 代码里面有箭头函数,看着这个感觉有戏,继续 if (id.includes('react-redux')) return false, 感觉离成功近了。发现还是一如既往的白屏,不过还是进步了,是缺少一堆属性,差点爆粗口,当即不看了,,明天再说。

     第3天,继续,当然由于公司也有任务,只能等会公司活做完再看看,等到下午继续,这个时候已经研究到是ant-pro这个组建里面出问题了,,,里面解析是符合问题,if判断后面没有;这个符号,查询node_modules 里面确实一堆这个,不过找不到是哪个包用了,然后我把pro所有组件全部exclude了,打包之后发现没有用,那么多源码,一个个看,简直了都,真多事为自己好奇心买单,这个时候放弃,感觉前面几天全部白费了啊!有点伤,算了,明天再说了,,,这个明天直接来到现在9月11号,,,真的是醉了,还是不甘心,为啥,心中全是为啥·SCRIPT1004: 缺少 ';' 这个报错,然后想到打开issues 找到了答案,原来umi其实也有这个问题的,解决方法就是if (id.includes('fast-deep-equal')) return false 继续打包 打包成功,ie打包,这个时候报错是一下方法不支持,这个时候就知道怎么搞定了,,,毕竟我配置的按需打包是根据自己代码里面去编译按需的,考虑到是不是可以直接exclude 没有,不过觉得不靠谱,打包出现了一堆问题,还有打包非常慢,这个不适合我们项目的,然后想到通过cdn 链接 判断是在ie环境下加载https://cdn.bootcdn.net/ajax/libs/babel-polyfill/7.12.1/polyfill.min.js 这个又可以打包快,又可以在ie在加载,所以是最佳方法。说干就干,打包执行,这次我终于打开了,哈哈哈 在ie项目可以访问了,太tm开心了,不过点击菜单就发现页面加载失败,只是菜单模块可以显示了,,,页面报错是缺少flat方法,看到这个觉得比较简单的问题,网上找了一个flat方法,原型重写,重写ie打开,发现页面重要打开了,心里真的开心,点击了几个页面,正常加载,除了几个地方样式问题,这个不是问题,心里舒服了啊,,,吃饭喝酒去。。。 以下是依赖选项

    "@ant-design/icons": "^4.2.2",
    "@ant-design/pro-components": "^1.1.10",
    "@emotion/css": "^11.9.0",
    "@emotion/styled": "^11.9.3",
    "@reduxjs/toolkit": "^1.8.3",
    "ant-design": "^1.0.0",
    "antd": "^4.21.7",
    "axios": "^0.27.2",
    "core-js": "^3.6.5",
    "dayjs": "^1.9.3",
    "echarts": "^5.3.3",
    "history": "^5.0.0",
    "hox": "^1.1.5",
    "html2canvas": "^1.4.1",
    "immer": "^9.0.3",
    "lodash": "^4.17.21",
    "normalize.css": "^8.0.1",
    "nprogress": "^0.2.0",
    "react": "^16.14.0",
    "react-dom": "^16.14.0",
    "react-keepalive-router": "^1.1.3",
    "react-loadable": "^5.5.0",
    "react-redux": "^8.0.2",
    "react-router-dom": "^5.2.0",
    "redux-logger": "^3.0.6",
    "use-immer": "^0.5.2"
`