Wilfred Hughes
Wilfred Hughes

Reputation: 31171

How can I polyfill Promise with webpack?

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.

Upvotes: 45

Views: 62786

Answers (9)

Kaxa
Kaxa

Reputation: 555

In webpack after optimization from babel-polyfill to core-js's promise the code:

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

does not works.

But after changing code to:

import 'core-js/features/promise';

it works.

Upvotes: 0

Jeroen Pelgrims
Jeroen Pelgrims

Reputation: 1125

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']
};

Upvotes: 69

For those using CRA (create-react-app) you could use the polyfill they provide:

react-app-polyfill

  • npm install react-app-polyfill or yarn add react-app-polyfill
  • In your index.js file: import 'react-app-polyfill/ie11';

Upvotes: 0

staafl
staafl

Reputation: 3235

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.

Upvotes: 10

Pier
Pier

Reputation: 10837

With Webpack 2 this is how I got it working.

First install with npm install babel-polyfill. Starting with NPM 5 --save can be omitted.

Then modify the webpack configuration with:

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

Of course ./src/main.js is different for every app.

Upvotes: 1

Ben
Ben

Reputation: 717

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']
};

Upvotes: 6

Alex Shwarc
Alex Shwarc

Reputation: 885

Better use Bluebird

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

  new webpack.NormalModuleReplacementPlugin(/es6-promise$/, 'bluebird'),
]

Upvotes: 5

Alex Antonov
Alex Antonov

Reputation: 15206

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'
  })
]

Upvotes: 20

Gabriel Florit
Gabriel Florit

Reputation: 2918

You almost got it - try this in your webpack.config.js:

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

Note that you will need to install imports-loader and exports-loader:

npm install --save imports-loader exports-loader

Upvotes: 1

Related Questions