Javascriptservices: Add Promise polyfill for IE

Created on 16 Oct 2016  路  14Comments  路  Source: aspnet/JavaScriptServices

The fetchdata route blows up with the following error in IE if there is no Promise polyfill:

SCRIPT5009: 'Promise' is undefined

http://caniuse.com/#search=promise

All 14 comments

Can't you just add it yourself if you need to support IE? Bluebird is a good one.

That's a valid point, but the same could be said for #365, right? IMO, it seems incorrect that the /fetchdata route wouldn't work OOTB in IE11.

I agree with @antmdvs that it would make sense that this should work out of the box. If the template is broken for IE11, it raises the question of what else was overlooked.

I don't mind having to add a promise library but guidance to what to update with webpack would be good.

I have added in the webpack.config.vendor.js

entry: {
        vendor: [
            'aurelia-event-aggregator',
            'aurelia-fetch-client',
            'aurelia-framework',
            'aurelia-history-browser',
            'aurelia-logging-console',
            'aurelia-pal-browser',
            'aurelia-polyfills',
            'aurelia-route-recognizer',
            'aurelia-router',
            'aurelia-templating-binding',
            'aurelia-templating-resources',
            'aurelia-templating-router',
            'bluebird',
            'bootstrap',
            'bootstrap/dist/css/bootstrap.css',
            'jquery'
        ],
  },

And in my boot.ts:

import { Aurelia } from 'aurelia-framework';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap';
import * as Bluebird from 'bluebird';
Bluebird.config({ warnings: false });
declare const IS_DEV_BUILD: boolean; // The value is supplied by Webpack during the build
export function configure(aurelia: Aurelia) {
    aurelia.use.standardConfiguration();
    if (IS_DEV_BUILD) {
        aurelia.use.developmentLogging();
    }
    aurelia.start().then(() => aurelia.setRoot('app/components/app/app'));
}

But still get SCRIPT5009: 'Promise' is undefined

Thanks

@beatsm Have you found a solution for this? I'm also looking to add the promise polyfill to the ReactRedux template. Any help would be appreciated.

I was able to include babel-polfill to fix this issue in IE11. I included "babel-polyfill" in package.json. Here is the boot-client.tsx:

import "./css/site.css";
import "./sass/stylesheet.scss";
import "bootstrap";
import * as React from "react";
import * as ReactDOM from "react-dom";
import { browserHistory, Router } from "react-router";
import { Provider } from "react-redux";
import { syncHistoryWithStore } from "react-router-redux";
import routes from "./routes";
import configureStore from "./configureStore";
import { IApplicationState } from "./store";
import "babel-polyfill";

const initialState = (window as any).initialReduxState as IApplicationState;
const store = configureStore(initialState);
const history = syncHistoryWithStore(browserHistory, store);

ReactDOM.render(
   <Provider store={store}>
      <Router history={history} children={routes} />
   </Provider>,
   document.getElementById("react-app")
);

The polyfill added to webpack.config.vendor.js:

    entry: {
       vendor: [
          "bootstrap",
          "bootstrap/dist/css/bootstrap.css",
          "domain-task",
          "event-source-polyfill",
          "react",
          "react-dom",
          "react-router",
          "redux",
          "redux-thunk",
          "react-router-redux",
          "redux-typed",
          "style-loader",
          "jquery",
          "babel-polyfill"
       ]
    }

Not sure if this is the best way to go about it, however.

@Singularity222 No, sorry I still have not found a way to get this to work. I am using the Aurelia template and in a work environment where IE is the most prevalent browser. This makes me sad :-(

If anybody is interested. For the Aurelia template I had to patch the aurelia-bootstrapper-webpack.js with the following:

var Promise = require('bluebird');

Promise.config({    
    warnings: false,    
    longStackTraces: false
});

if (!window.Promise) {
    window.Promise = Promise;
} 

This is loaded before the app giving me the headache. Not sure this is the recommended way but can't link to a CDN in my environment and don't want to copy the node_modules to wwwroot.

@EisenbergEffect - Is this normal or have I done something stupid?

@niieani is probably the best person to comment. I should also note that we have some new webpack updates coming that will add full HMR :) And then server rendering is coming soon too :) Yay!

@beatsm the best way to globally polyfill Promise is to add this plugin to your Webpack config:

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

This will replace all calls to Promise with the web equivalent of require('bluebird').

If you want to additionally expose a global Promise which is a reference to Bluebird, you can also add a loader:

module: {
  rules: {
    { test: /[\/\\]node_modules[\/\\]bluebird[\/\\].+\.js$/, loader: 'expose-loader?Promise' }
  }
}

You'll need to npm install expose-loader.

It's the equivalent of your:

if (!window.Promise) {
    window.Promise = Promise;
} 

@niieani Thanks for taking the time.

Have you actually tried this? If you have, then I must be doing something wrong.

I added that into the webpack.config.js which didn't work. I then added it to the webpack.config.vendor.js, still no joy and then tried adding it to both. At this point I just hacked the aurelia-bootstrapper-webpack.js as it seems to executes before anything else and doesn't take the plugin into account.

Regards

@niieani - Got it to work in the webpack.config.js using the plugin, I was just doing it wrong.

Glad to hear @beatsm.

Glad you got that aspect of it working. Thanks for letting us know!

As for the original matter of Promise polyfill, I'll close this in favour of #484 which describes it more generally.

Was this page helpful?
0 / 5 - 0 ratings