Umi: 升级新版本之后ie报错

Created on 2 May 2018  ·  31Comments  ·  Source: umijs/umi

umi-plugin-dva 升级到0.6.3

Warning: The <DvaContainer /> component appears to have a render method, but doesn't extend React.Component. This is likely to cause errors. Change DvaContainer to extend React.Component instead. 
SCRIPT5022: 引发了异常但未捕获 
umi.js, 行17111 字符5
The above error occurred in the <DvaContainer> component:
    in DvaContainer

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries. 
SCRIPT5022: 引发了异常但未捕获 

https://github.com/umijs/umi-examples/tree/master/with-dva
可重现

type(bug)

Most helpful comment

core-js 的 Object.setPrototypeOf polyfill 需要支持 __proto__ ,但 ie 10 不支持

加个更好的 polyfill 可以解决:

import '@babel/polyfill'
Object.setPrototypeOf = require('setprototypeof')

更新

https://gist.github.com/dgeibi/fbb68e241b10a92988ff554b0473611a

All 31 comments

umi 1.1.4 和 umi-plugin-dva 0.5.0 下可以正确运行

补充一句Windows 10

https://github.com/umijs/umi-examples/tree/master/with-dva 下安装
umi1.1.4 umi-plugin-dva 0.5.0 也还是有这个问题
但是在我的项目中umi1.1.4 umi-plugin-dva 0.5.0 这个环境是可以的。
@sorrycc

在群里看到其他朋友,说在mac上模拟的ie浏览器,也有这个问题

mac 上怎么模拟 IE 浏览器?

经测试发现,是 @babel/[email protected] 的问题,@babel/[email protected] 是好的。

测过 vue/cli@3 也有这个问题。

function A() {}
A.prototype.a = 'aaa';

class B extends A {}
console.log(B.prototype.a);

IE10 下输出是 undefined,IE11 是 aaa。

create-react-app@next 没有这个问题,因为他们 release 的版本用的是 7.0.0-beta.44。

👍

core-js 的 Object.setPrototypeOf polyfill 需要支持 __proto__ ,但 ie 10 不支持

加个更好的 polyfill 可以解决:

import '@babel/polyfill'
Object.setPrototypeOf = require('setprototypeof')

更新

https://gist.github.com/dgeibi/fbb68e241b10a92988ff554b0473611a

这两个问题和 class 继承应该都没问题。

@dgeibi 方案有用!
想请教下,你是如何发现这个问题的。因为我的ie报错,但一直报:‘这是一个异常’,根本定位不到哪行代码出问题的,也根本发现不了是哪个方法不兼容。

@951565664 ie 的 debug 我也不会。弄个最小 demo,结合 js 继承的知识分析 babel 生成的代码。

npm i @babel/cli @babel/core @babel/preset-env @babel/preset-react

babelrc:

{
  "presets": [
    [
      "@babel/env",
      {
        "targets": {
          "browsers": "last 2 versions"
        }
      }
    ],
    "@babel/react"
  ]
}

package.json:

{
  "scripts": {
    "build": "babel index.js -d dist"
  }
}

这个问题有结论了,先 Close 了。

umi更新1.3.之后
with-dva刚刚使用上面的方法,在加上init补丁,可以在ie上运行,
umi更新1.3

SCRIPT1002: 语法错误 
umi.js, 行57566 字符3

我好想reopen!

@951565664 更新umi还有问题吗?

@dgeibi 试了你这个方法,ie还是打不开啊

@wyj580231 umi 1.3.*这样改后还有其它问题

@sorrycc
现在的umi-antd-admin
dev环境 ie10

SCRIPT1002: 语法错误 
umi.dll.js, 行370808 字符1
SCRIPT1002: 语法错误 
umi.js, 行47389 字符3

重现项目 https://github.com/umijs/umi-antd-admin

在我们公司的项目中,
umi.dll.js, 缺少‘:’

调试时不要用 IE 吧。

build之后也不行。(捂脸)

我们项目,升级umi1.3.3 之后,build之后可以了。有问题再reopen

IE11打不开

SCRIPT1014: 无效字符
umi.js (100629,11)

-->

if (pathname.slice(-1) === '/') {
    ret = `${pathname.slice(0, -1)}/index.js`; // 这行报错?
  } else {
    ret = `${pathname}.js`;
  } // strip the start slash

@wgwxf

npm i @babel/polyfill setprototypeof --save

global.js

import "@babel/polyfill";
import "core-js/fn/array/for-each";
Object.setPrototypeOf = require('setprototypeof')
if (window.NodeList && !NodeList.prototype.forEach) {
  NodeList.prototype.forEach = function(callback, thisArg) {
    thisArg = thisArg || window;
    for (var i = 0; i < this.length; i++) {
      callback.call(thisArg, this[i], i, this);
    }
  };
}

这么加,build之后,应该是可用的。你试试

@xiaohuoni
上面 找 “dgeibi” 这个人的回答,
按照这个走,再加一个babel-polifill ie ok

@xiaohuoni 可以搞个 umi-plugin-ie10,自动注入 @babel/polyfillsetprototypeof

我有打算写一个umi-plugin-polyfill。不止IE的兼容。其实用上动画的话,或者其他东西可能有别的兼容。比如antd-pro里面就用到了url-polyfill。动画可能要添加web animation。react我不太清楚还需不需要别的什么兼容。这几天在看材料。

再出现兼容问题,可以尝试使用umi-plugin-polyfill

export default {
  plugins: [
    "umi-plugin-polyfill"
  ]
};

如果还存在其他不兼容的情况,再提ISSUES

这个问题解决了,因为babel 7针对继承做了改动,原先state = {
rendering: true,
isMobile: false,
menuData: this.getMenuData(),
}; 这样的属性是直接编译成superClass.call(this,props),而现在是编译成Object.getprototypeof(subClass).call(this);
子类本身是不会指向父函数的,所以原来的继承方式会通过Object.setPrototypeOf的方式显式的把子类的__proto__指向父函数,ie9,10不支持这个属性,却有Object.getprototypeof,需要改造下
if ('__proto__' in {}){

} else{
var old = Object.getPrototypeOf
Object.getPrototypeOf = function(param){
if(param.__proto__){
return param.__proto__
} else {
return old(param)
}
}
}
至于Object.setPrototypeOf的模拟参考上面的例子@sorrycc

@dgeibi good !!!

通过你的方法, 我解决了IE 10中如下报错:

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}
Was this page helpful?
0 / 5 - 0 ratings