Promise未定义坑
- 问题描述
webpack + babel-loader + transform - runtime正常来讲是可以实现没有原生支持Promise的浏览器下正常运行,但是在低版本系统中还是出现Promise未定义的错误。
- 分析
1. 确认transform-runtime是否生效在编译生成的js代码中查看到
var Promise = win.Promise || __webpack_require__(41);
说明Promise是被替换调了,说明有代码超出了babel调控制范围。
2. 问题思考
可能出问题调就是node_modules第三方依赖模块或者webpack打包生成的代码可能出问题。node_modules第三方依赖模块,可能npm包中在webpack配置中不需要babel的编译,而这些包可能需要原生的Promise支持。这种情况需要排查,进过排查没有因为npm包引起。现在只可能是webpack本身产生的代码 引起的。其中webpack官网上有描述:![]()
当webpack使用异步加载模块时,require.ensure
需要原生支持Promise,项目中有按需加载,所以才导致Promise未定义当问题。也就是说,webpack生成当new Promise相关代码,超出了babel当控制范围,需要polyfill全局的Promise解决此问题。
- 解决方案
1.引入babel-polyfill、es6-promise导出全局Promsie,这种方法可以实现导出全局Promise,但是同时也导出许多其它全局变量造成全局污染,且文件体积也比较大。
2.结合babel-runtime的转换功能来为全局Promise进行polyfill,将babel-runtime的Promise的polyfill挂载到window,即:
windwo.Promise = Promise;//添加在js文件开头
经过babel-runtime转换后
window.Promise = _promise2.default;
- 跨浏览器的思考
开发使用的chrome浏览器,只使用babel-runtime没有问题,即使不编译chrome本身也支持,但对于跨浏览器项目:
1.版本较低的IE建议使用babek-poltfill,可以对静态或者实例方法都会转换
2.对于制定都浏览器如chrome,直接使用babel-runtime即可,原生支持较好。