IE11中Promise未定义错误的替代解决方案(无需babel-polyfill)
不用babel-polyfill解决IE11 Promise未定义的方案
嘿,我来帮你搞定IE11里Promise未定义的问题!毕竟IE11完全不支持ES6的Promise,咱们不用babel-polyfill也能轻松解决,下面是几个靠谱的方案:
方案1:用独立的Promise polyfill库(最推荐)
专门的Promise polyfill库体积小、针对性强,比如es6-promise或者promise-polyfill,这里以es6-promise为例:
- 先安装依赖:
npm install es6-promise --save
- 在你的入口文件(
partner/index.js)最顶部导入:
// ES6模块写法 import 'es6-promise/auto'; // 或者CommonJS写法 require('es6-promise/auto');
这个auto版本会自动检测环境——如果浏览器原生支持Promise就啥也不做,不支持就全局注入,不会污染已有环境。
- 要是不想在代码里手动导入,也可以在Webpack里用
ProvidePlugin自动注入:
修改你的Webpack配置:
var path = require('path'); var webpack = require('webpack'); // 先引入webpack模块 module.exports = { entry: path.resolve(__dirname, 'partner/index.js'), output: { path: path.resolve(__dirname, './dist'), filename: 'partner_bundle.js' }, plugins: [ new webpack.ProvidePlugin({ Promise: 'es6-promise-promise' // 用promise-polyfill的话就写 'promise-polyfill/src/polyfill' }) ], // 你的其他module配置... };
方案2:手动添加极简Promise polyfill代码
要是不想额外装依赖,直接把这段MDN上的极简Promise polyfill代码放到入口文件最前面就行:
if (typeof Promise === 'undefined') { window.Promise = function Promise(executor) { if (!(this instanceof Promise)) throw new TypeError('Promise must be called with new'); if (typeof executor !== 'function') throw new TypeError('executor must be a function'); var self = this; self._state = 'pending'; self._value = undefined; self._deferreds = []; function resolve(value) { if (value && typeof value === 'object' && value.constructor === Promise) { return value.then(resolve, reject); } setTimeout(function() { if (self._state === 'pending') { self._state = 'fulfilled'; self._value = value; for (var i = 0; i < self._deferreds.length; i++) { handle(self._deferreds[i]); } self._deferreds = null; } }, 0); } function reject(reason) { setTimeout(function() { if (self._state === 'pending') { self._state = 'rejected'; self._value = reason; for (var i = 0; i < self._deferreds.length; i++) { handle(self._deferreds[i]); } self._deferreds = null; } }, 0); } function handle(deferred) { if (self._state === 'pending') { self._deferreds.push(deferred); return; } var cb = self._state === 'fulfilled' ? deferred.onFulfilled : deferred.onRejected; if (cb === null) { (self._state === 'fulfilled' ? resolve : reject)(deferred.promise._value); return; } var ret; try { ret = cb(self._value); } catch (e) { reject(deferred.promise, e); return; } resolve(deferred.promise, ret); } function onFulfilled(value) { resolve(value); } function onRejected(reason) { reject(reason); } try { executor(onFulfilled, onRejected); } catch (reason) { reject(reason); } }; Promise.prototype.then = function(onFulfilled, onRejected) { var prom = new this.constructor(function() {}); handle({ promise: prom, onFulfilled: typeof onFulfilled === 'function' ? onFulfilled : null, onRejected: typeof onRejected === 'function' ? onRejected : null }); return prom; }; }
这段代码会在IE11里手动实现Promise的核心功能,足够日常使用。
方案3:用Babel按需引入polyfill(适合已用Babel的项目)
如果你的项目已经在用Babel编译,可以用@babel/plugin-transform-runtime配合@babel/runtime-corejs3按需引入polyfill,不会全局污染环境:
- 安装依赖:
npm install @babel/plugin-transform-runtime @babel/runtime-corejs3 --save-dev
- 修改Babel配置(比如
.babelrc或babel.config.js):
{ "presets": [ ["@babel/preset-env", { "useBuiltIns": "usage", "corejs": 3 }] ], "plugins": [ ["@babel/plugin-transform-runtime", { "corejs": 3 }] ] }
这个配置会自动检测你代码里用到的ES6+特性,只引入需要的polyfill(包括Promise),不用整个引入babel-polyfill,非常高效。
⚠️ 注意:不管用哪种方案,一定要确保polyfill代码最先执行,这样后面用到Promise的代码才能正常运行哦!
内容的提问来源于stack exchange,提问作者Rasim Avcı
相关产品推荐
相关产品推荐

