【问题标题】:How can I polyfill Promise with webpack?如何使用 webpack 填充 Promise?
【发布时间】:2016-12-21 23:28:27
【问题描述】:

我正在使用 webpack 来捆绑我的 JavaScript。我依赖于使用 any-promise 的模块,例如 popsicle

这是我的代码:

var popsicle = require('popsicle');
popsicle.get('/').then(function() {
  console.log('loaded URL');
});

这在Promise 可用但IE 11 does not provide Promise 的浏览器中运行良好。所以我想用es6-promise 作为一个polyfill。

我尝试将明确的ProvidePlugin 添加到我的webpack.config.js

plugins: [
  new webpack.ProvidePlugin({
    'Promise': 'exports?global.Promise!es6-promise'
  })
]

但我仍然在 IE 11 中遇到错误:any-promise browser requires a polyfill or explicit registration e.g: require('any-promise/register/bluebird')

我尝试显式附加一个全局:

global.Promise = global.Promise || require('es6-promise');

但是 IE 11 给出了不同的错误:Object doesn't support this action

我也尝试过显式注册 es6-promise:

require('any-promise/register/es6-promise');
var popsicle = require('popsicle');

这可行,但我必须在加载popsicle 的每个文件中执行此操作。我只想将Promise 附加到window

如何确保始终使用 webpack 定义 window.Promise

Full repo demo here.

【问题讨论】:

    标签: javascript webpack internet-explorer-11 polyfills


    【解决方案1】:

    对于结合使用 babel 和 webpack 的人:你可以使用babel-polyfill

    只需执行npm install --save "babel-polyfill",然后将其作为入口点添加到您的 webpack.config.js 中:

    module.exports = {
       entry: ['babel-polyfill', './app/js']
    };
    

    或者,您可以安装 core-js 并仅引用您需要的模块,而不是使用整个 babel-polyfill。

    module.exports = {
       entry: ['core-js/stable/promise', './app/js']
    };
    

    【讨论】:

    • 谢谢。这应该被接受的答案。虽然,我的输出 JS 文件现在是 150 kB(之前 ~50 kB)。
    • @Bald 你试过 webpack 2 吗?我自己没有尝试过,但它现在应该支持摇树。这将删除已导入但在输出包中未使用的代码。因此,如果您使用 core-js 的单一导入,它可能会减小大小。
    • 不,我没有,但我会 :) 感谢您的提示。
    • Webpack v3.11、TS v2.7.x 和 node > v9,支持动态模块导入,问题是不能导入 Promise polyfill,因为动态导入也依赖于 Promises。因此我手动执行:if (!("Promise" in window)) { var head = document.getElementsByTagName("head")[0]; var script = document.createElement("script"); script.src = "https://../YourPromisePolyfill.js"; head.appendChild(script as HTMLScriptElement); } 当然可以使用 require/import 来加载包,但随后它会被捆绑并下载,即使不需要
    • 在 core-js v3 中是'core-js/stable/promise'
    【解决方案2】:

    对我有用的选项。 es6-promise-promise 旨在直接包含在 webpack 构建中。所以:

    plugins: [
      new webpack.ProvidePlugin({
        Promise: 'es6-promise-promise'
      })
    ]
    

    【讨论】:

    • 当使用ProvidePlugin然后尝试做一些require.ensure时在IE 11中仍然得到ReferenceError
    【解决方案3】:

    使用ProvidePlugin 的最近添加的property 功能的@asiniy 答案的更新和简洁版本,无需引用es6-promise-promise

        new webpack.ProvidePlugin({
            Promise: ['es6-promise', 'Promise']
        })
    

    为此,请不要忘记添加 es6-promise 作为要填充 Promise 的项目的依赖项。

    【讨论】:

      【解决方案4】:

      babel polyfill 通常可以工作,但这次是针对 vuejs(webpack1) 项目,不知何故无法工作。

      幸运的是,core-js 很有魅力。

      npm install core-js --save
      
      module.exports = {
         entry: ['core-js/fn/promise', './app/js']
      };
      

      【讨论】:

        【解决方案5】:

        更好地使用蓝鸟

        plugins: [
          new webpack.ProvidePlugin({
            Promise: 'bluebird'
          }),
        
          new webpack.NormalModuleReplacementPlugin(/es6-promise$/, 'bluebird'),
        ]
        

        【讨论】:

          【解决方案6】:

          你几乎明白了 - 在你的 webpack.config.js 中试试这个:

          plugins: [
            new webpack.ProvidePlugin({
              Promise: 'imports?this=>global!exports?global.Promise!es6-promise'
            })
          ]
          

          请注意,您需要安装imports-loaderexports-loader

          npm install --save imports-loader exports-loader

          【讨论】:

          • 这在 IE 11 中不起作用,同样的错误:any-promise browser requires a polyfill or explicit registration e.g: require('any-promise/register/bluebird')
          • 嗯,在 IE11 中为我工作,Win 8.1。稍后将尝试使用您的 repo 演示。
          • @faceyspacey.com 是的,但我最近切换到手动填充而不是通过 webpack - 这太神奇了。见github.com/stefanpenner/es6-promise#auto-polyfill
          • @GabrielFlorit 我也是。这正是我对谷歌顶部的承诺包所做的事情,哈哈
          • @GabrielFlorit 你是怎么做到的?
          【解决方案7】:

          使用 Webpack 2 这就是我的工作方式。

          首先使用npm install babel-polyfill 安装。从 NPM 5 开始--save 可以省略。

          然后修改webpack配置:

          entry: {
            app: ['babel-polyfill', './src/main.js']
          }
          

          当然./src/main.js 对于每个应用程序都是不同的。

          【讨论】:

            【解决方案8】:

            对于那些使用 CRA (create-react-app) 的人,您可以使用他们提供的 polyfill:

            react-app-polyfill

            • npm install react-app-polyfillyarn add react-app-polyfill
            • 在您的index.js 文件中:import 'react-app-polyfill/ie11';

            【讨论】:

            • @Man 你可以打开一个新问题并在那里提供更多详细信息
            【解决方案9】:

            在webpack中从babel-polyfill优化到core-js的promise代码:

            import 'core-js/library/es6/promise'; 
            

            不起作用。

            但是将代码更改为:

            import 'core-js/features/promise';
            

            它有效。

            【讨论】:

              猜你喜欢
              • 2018-04-06
              • 2015-08-11
              • 1970-01-01
              • 1970-01-01
              • 2017-06-11
              • 2016-11-16
              • 2018-04-17
              • 2020-03-02
              相关资源
              最近更新 更多