aspnet / JavaScriptServices

[Archived] This repository has been archived
Apache License 2.0
3.03k stars 518 forks source link

Add Promise polyfill for IE #386

Closed antmdvs closed 7 years ago

antmdvs commented 8 years ago

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

mttmccb commented 7 years ago

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

antmdvs commented 7 years ago

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.

arturcarvalho commented 7 years ago

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.

beatsm commented 7 years ago

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

wapplegate commented 7 years ago

@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.

wapplegate commented 7 years ago

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.

beatsm commented 7 years ago

@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 :-(

beatsm commented 7 years ago

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?

EisenbergEffect commented 7 years ago

@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!

niieani commented 7 years ago

@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;
} 
beatsm commented 7 years ago

@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

beatsm commented 7 years ago

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

niieani commented 7 years ago

Glad to hear @beatsm.

SteveSandersonMS commented 7 years ago

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.