知识要求
-
的基础知识(推荐阮一峰的babel入门教程)babel
- 充分理解
与babel-plugin-transform-runtime
的作用(推荐github项目首页)babel-runtime
-
基础用法(https://webpack.js.org/)webpack2
-
中webpack2
作用,babel-loader
异步加载import
问题说明
webpack
+
babel-loader
transform-runtime
正常来讲应该能实现在没有原生支持
Promise
的浏览器(如
IE
)下正常运行,但是实际在
IE11
下,还是提示
Promise
未定义的错误。网上找了一圈,没有切中要害的,于是干脆自己分析。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5iNzcTOxUDMzcTLyUTMwETNzATMzEDMxcTMwITL2kjNzczLcBTM3EDMy8CX2kjNzczLcd2bsJ2Lc12bj5ycn9Gbi52YucTMwIzcldWYtl2Lc9CX6MHc0RHaiojIsJye.png)
分析
首先确认
babel
的
transform-runtime
是否生效,在自己的
js
代码中编写
var promise = new Promise(resolve, reject)
的示例代码,发现
Promise
是有被替换的。所以问题的关键在于什么东西超出了
babel
的控制?
我想到的是
node_modules
webpack
本身生成的代码。
在使用
babel
转换
ES6
之前, 通过
node_modules
引用的第三方包都能正常使用,因此可以排除。
那么
webpack
呢,在
GOOGLE
中搜索
webpack promise not defined
,还真找到了原因,如下图所示:
图片来源: https://webpack.js.org/guides/migrating/#require-ensure-and-amd-require-are-asynchronous
当使用了
webpack
的异步加载时,
webpack
要求原生支持
Promise
,刚好我们的代码有用到。至此,原因就找到了:
webpack
生成的
new Promise
相关代码, 超出
babel
transform-runtime
的控制范围,只有导出全局的
Promise
才能解决此问题。
解决方案1
- 引入
导出全局babel-polyfill
,这种方法并不好;不仅Promise
被导出,还抛出大量其他的全局对象,可能存在冲突风险,同时文件体积比较大。Promise
解决方案2
在
js
文件开头添加
window.Promise = Promise
这一句即可,示例代码:
import 'jquery'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap'
// 将Promise抛出为全局对象
window.Promise = Promise
。。。
原理:当
babel
检查到
js
Promise
时,
transform-runtime
会将
Promise
做转换,然后将其抛出为全局对象即可达到跟
babel-polyfill
一样的效果。
参考资料
- github上babel-runtime没有正常工作的讨论
- I use ‘runtime’, but get Promise is not defined