How can I polyfill Promise with webpack?

59,902

Solution 1

For people using babel in combination with webpack: you can use babel-polyfill

Just do npm install --save "babel-polyfill" and then add it as an entry point in your webpack.config.js:

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

Or, instead of using the entire babel-polyfill you can install core-js and reference only the module you need.

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

Solution 2

Option that worked for me. es6-promise-promise is designed to be included directly to the webpack builds. So:

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

Solution 3

An updated and concise version of @asiniy's answer using the recently added property feature of ProvidePlugin, without the need to reference es6-promise-promise:

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

For this to work don't forget to add es6-promise as a dependency of the project you want to polyfill Promise in.

Solution 4

babel polyfill usually works, but this time for a vuejs(webpack1) project, somehow not working.

Fortunately, core-js works as a charm.

npm install core-js --save

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

Solution 5

Better use Bluebird

plugins: [
  new webpack.ProvidePlugin({
    Promise: 'bluebird'
  }),

  new webpack.NormalModuleReplacementPlugin(/es6-promise$/, 'bluebird'),
]
Share:
59,902

Related videos on Youtube

Wilfred Hughes
Author by

Wilfred Hughes

By day, I work on Hacklang. By night, I tinker with obscure programming languages and make Emacs do silly things. Blog: Wilfred Hughes::Blog

Updated on July 09, 2022

Comments

  • Wilfred Hughes
    Wilfred Hughes almost 2 years

    I'm using webpack to bundle up my JavaScript. I'm depending on modules like popsicle which use any-promise.

    Here's my code:

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

    This works fine in browsers where Promise is available, but IE 11 does not provide Promise. So I want to use es6-promise as a polyfill.

    I tried adding an explicit ProvidePlugin to my webpack.config.js:

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

    But I still get the error in IE 11: any-promise browser requires a polyfill or explicit registration e.g: require('any-promise/register/bluebird').

    I tried explicitly attaching a global:

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

    But IE 11 gives a different error: Object doesn't support this action.

    I also tried explicitly registering es6-promise:

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

    This works, but I have to do it in every single file that loads popsicle. I want to just attach Promise to window.

    How can I ensure window.Promise is always defined, using webpack?

    Full repo demo here.

  • Wilfred Hughes
    Wilfred Hughes almost 8 years
    That doesn't work in IE 11, same error: any-promise browser requires a polyfill or explicit registration e.g: require('any-promise/register/bluebird')
  • Gabriel Florit
    Gabriel Florit almost 8 years
    Hmm, worked for me in IE11, Win 8.1. Will try with your repo demo in a bit.
  • Gabriel Florit
    Gabriel Florit over 7 years
    @faceyspacey.com yes, but I recently switched to polyfilling manually instead of via webpack - it's too much magic. See github.com/stefanpenner/es6-promise#auto-polyfill.
  • faceyspacey.com
    faceyspacey.com over 7 years
    @GabrielFlorit me too. that's exactly what i did with the promise package at the top of google lol
  • Bald
    Bald over 7 years
    Thank you. This should be accepted answer. Although, my output JS file is now 150 kB (before ~50 kB).
  • Jeroen Pelgrims
    Jeroen Pelgrims over 7 years
    @Bald Have you tried webpack 2? I haven't tried it myself but it should now support tree shaking. This will remove code that is imported but unused in the bundle that is output. So if you use the single import from core-js it might reduce the size.
  • Bald
    Bald over 7 years
    No, I haven't, but I will :) Thanks for the hint.
  • McSas
    McSas over 7 years
    @GabrielFlorit How did you that?
  • antoine129
    antoine129 over 6 years
    still getting a ReferenceError in IE 11 when using the ProvidePlugin and then trying to do some require.ensure
  • Legends
    Legends over 6 years
    Webpack v3.11, TS v2.7.x and node > v9, supports dynamic module imports, the problem is that you cannot import the Promise polyfill, because the dynamic import depends also on Promises. Therefor I do it manually: 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); } You can of course use require/import to load the package, but then it gets bundeled and will be downloaded, even when not needed
  • Mario Pérez Alarcón
    Mario Pérez Alarcón about 5 years
    @Man you could open a new question and give more details there
  • Dave James Miller
    Dave James Miller almost 5 years
    In core-js v3 it's 'core-js/stable/promise'.
  • Luke
    Luke over 3 years
    Babel-polyfill is deprecated in favour of core-js