aurelia/skeleton-navigation

"Out of stack space" error in IE 11

rezakov opened this issue ยท 47 comments

I'm submitting a bug report

  • Aurelia Skeleton Version
    skeleton-esnext-webpack
  • Framework Version:
    1.1.2

Please tell us about your environment:

  • Operating System:
    Windows [10]

  • Node Version:
    7.3.0

  • NPM Version:
    4.1.1
  • Webpack AND Version
    webpack 2.4.1
  • Browser:
    IE 11

  • Language:
    ESNext

Current behavior:

"Out of stack space" error occurs and the page doesn't load.
err
Expected/desired behavior:

  1. download skeleton-esnext-webpack
  2. npm install
  3. npm start webpack.build.production.serve
  • What is the expected behavior?
    Page should load properly

The error also appears in dev (npm start)

Please change the supported browser number here in your .babelrc.js file: https://github.com/aurelia/skeleton-navigation/blob/master/skeleton-esnext-webpack/.babelrc.js#L14

not ie <= 10 should be good enough.

@niieani this was the first thing I tried. No change, the error is still breaking the page.

I can confirm the bug @rezakov has reported. not ie <= 9 or 10 is not working like in the past.

Odd. We'll investigate. @jods4 might it have something to do with the new Webpack plugin or how we bootstrap Aurelia?

jods4 commented

Not that I know of.

I know some people are running Aurelia + Webpack successfully on IE. There is not much info about the source of the error in the issue...

I spotted Webpack v.2.4, I haven't tried that yet I will check compat.

jods4 commented

Have you seen aurelia/dialog#283? It's also an infinite recursion bug that was recently reported, maybe related? (maybe not)

Thanks for feedback @jods4. I guess we'll need more info. Did you, @rezakov, modify the code in any way, or is this pure skeleton?

I replicated it with a "pure skeleton" a few hours ago, although this was not the last official release but the current repo as it is today.

  • clone/download current repo (not release)
  • npm install
  • change to not ie <= 10 or not ie <= 9 in .babelec.js
  • npm start
  • localhost:8080 in browser in IE 11 will fail with the same error

The problem is with the current skeleton, and possibly also since v. 1.1.2 as @rezakov reported.

@sorenhoyer By pure skeleton do you mean @jods4's webpack example skeleton?

@niieani I noticed the issue first when I tried to upgrade our app and tested the production bundles. I later discovered that the issue appears in IE regardless of the target environment (prod or dev). Then to make sure I'm not crazy I downloaded a fresh repo from here (skeleton-esnext-webpack), then:

  1. npm install
  2. npm start (or target prod with npm webpack.build.production.serve, all the same)
  3. navigated to localhost:8080 in IE

I then tried modifying https://github.com/aurelia/skeleton-navigation/blob/master/skeleton-esnext-webpack/.babelrc.js#L14 but it made no difference.

The error Is insanely obscure. I just tried stepping through the code and it appears that the "Out of stack space" error is coming from in aurelia-loader-webpack (I think). I'll double check shortly.

image

@niieani no I just mean this current repo. :-) https://github.com/aurelia/skeleton-navigation

Thanks. We should switch out the loader-webpack to non-await-async code. Seems like the stack is running out in the generator code emitted by TypeScript. An alternative might be trying to compile it with latest TS which includes alternative emit code for async-await code.

Facing the same issue

Same here. Would highly appreciate a fix. Thanks!

This is blocking a release for us :/ Is there any way how we can help to get a fix?

@saruye The best thing would be diagnosing the reason for the problem. Once we know what's really causing the problem under IE 11, we can start working on a fix. I'm personally not using Windows, nor currently have any laptops and VMs are painfully slow to work with, so I'd appreciate help in this matter.

One thing to try would be to re-write the async-await parts of aurelia-loader-webpack into an old-style pure ES6 with .then() handling and submitting a PR to that repo (we want to do that anyway). Since the stack is running out in the generators, it seems like a good start.

jods4 commented

I wonder if async-await is the true issue, or happens to be on stack by coincidence.

I do have apps running on IE 11 in production with async-await compiled downlevel with Typescript (and previously with Babel). Never had an out-of-stack issue -- the overall setup was different though, but just saying: async-await is supposed to work and blindly rewriting to Promise might not help, or might hide the true problem.

Unless a lot of stuff is filtered, the callstack doesn't look deep judging from the scrollbar.
Makes me wonder what may fill that stack then?

Yes, agreed @jods4, async-await downlevel might not itself be the culprit, but the compilation sure is making it harder at deciphering what's really going on there.

I also am facing the same issue here on IE.

I wonder if this fixes the issue: aurelia/templating#460 (comment)

Let us know if it does

No this dosent fix this problem :( @jdanyow

image

I think the culprit here is aurelia-polyfills createCollection method as you can see in the above image.

image
here is the expanded error in the console when i ran the skeleton navigation with promise based loader-webpack

after some more debugging, it seems like it starts from core js polyfills.
image

@niieani please take a look at the these, and let me know if I can provide anything else.

jods4 commented

I can swear I've seen this before. (The collection ctor looping indefinitely.)

I'm not 100% positive but I think it was linked to an incorrect bootstrap sequence, if only I could find it back.

Otherwise we'll have to debug this once more.

jods4 commented

Found it!
There: jods4/aurelia-webpack-build#33, same issue.

The investigation was unclear but in the end it seemed that mixing polyfills, specifically babel-polyfill was problematic. Is the situation similar here?

@jods4 yes! Since babel is auto-polyfilling all usages, it might make the most sense to disable all the aurelia-polyfills?

jods4 commented

In that case, you can configure AureliaPlugin to not include any polyfill, docs:
https://github.com/jods4/aurelia-webpack-build/wiki/AureliaPlugin-options#features

Note that Aurelia actually needs some unusual polyfills like Reflect metadata apis.
There are several levels of polyfills, you might want to go for none (as the name said), or esnext (for exotic stuff that is not in ES2016).

Example:

new AureliaPlugin({ 
  features: {
    polyfills: "esnext"
  }
})

As a bonus, esnext saves around 10K of your minified build.

@jods4 using esnext polyfills doesn't help. Reflect is not polyfilled by the time its needed and ie11 errors out. After manually enabling Reflect polyfill and Object.assign polyfill, the app is finally loading in ie11

I think this would work if we polyfill everything that Aurelia needs from babel-polyfill in an entrypoint instead of requiring aurelia-polyfills.

So it seems this is a problem only for the babel version.
Thank you @suneelv and @jods4 for investigating.

We should probably fix our polyfill and perhaps add a warning in case a new polyfill tries to polyfill something that has already been polyfilled. I'll investigate the changes needed to be done to our babel skeleton.

I think aurelia-polyfills is prefered over babel-polyfill which is basically core-js.
aurelia-polyfills does not try to polyfill something that is already available regardless if it is native or polyfilled.

jods4 commented

One thing to be aware of and that I don't like is that currently the plugin puts aurelia-webpack-loader before your entry points... and because the loader needs some polyfills in IE11 it also puts aurelia-polyfills before that (but that's not all the required polyfills).

This makes it hard to put any other code, including other polyfills before that.

EDIT: to be clearer, putting a polyfill in front of your entry point won't be the first thing to run, unfortunately.

@gheoan babel-polyfill also does not try to polyfill something that is already available, if you use it in combination with babel-preset-env, which the latest skeleton-navigation does. In this sense, there's no difference in using aurelia-polyfills, and babel-polyfill is better in that it will dynamically add more polyfills as you use them in your code, based on the target browser.

@jods4 how can we leverage the minimal set of polyfills required for the loader? in other words, how can se put a polyfill in front of the first thing to run with the current configuration? should we add a configuration option to the AureliaPlugin that allows specifying arbitrary "entrypoints" that get run before Aurelia?

jods4 commented

@niieani That's something I've been thinking about for a while. I want to change it but I'm still not sure how.

Right now some options are putting your polyfills in another <script> tag before the main one, using option noWebpackLoader and managing the config and bootstrap sequence yourself, or using a Webpack plugin that puts polyfills at the top of the bundle file.

It does indeed seem to work in ie11 if you insert something like <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.23.0/polyfill.min.js"></script> in the index.ejs file, but couldn't really get option 2 and 3 working, as @jods4 suggests. Is this the suggested fix for now or do you know of a better way that works?

jods4 commented

@sorenhoyer As of Aurelia plugin RC-2 putting your polyfills in a <script> tag before the main bundle is the easiest and safest way to go.

jods4 commented

Webpack plugin 2.0 RC3 has simpler entry point management.
I put up information in this new wiki page:
https://github.com/jods4/aurelia-webpack-build/wiki/Polyfills

I think this should make this scenario much simpler. Include babel polyfills before everything else in the entry point and I think it should work. As a bonus you should be able to remove Aurelia's own polyfills as well.

It would be nice to have a confirmation if someone from this thread can check. Note that you need to compile the RC 3 branch yourself (npm run build), the contents of dist are only committed when we publish a new version.

@jods4 That wiki page on polyfills should be added to the official documentation.

jods4 commented

@gheoan I mirror everything in the official Aurelia repo:
https://github.com/aurelia/webpack-plugin/wiki/Polyfills

The official docs (hub) have not been updated for our 2.0 plugins at all... yet!

thanks @sorenhoyer your solution fixed this issue for me

Hi, I was having this same issue and found an alternative workaround:

  1. On package.json html-webpack-plugin should be updated to version 2.30.1.
  2. On webpack.config add a new 'polyfill' entry like so:
entry: {
  app: ['aurelia-bootstrapper'],
  vendor: ['bluebird', 'jquery', 'bootstrap'],
  polyfill: ['babel-polyfill']
},
  1. Again, on webpack.config, add the following to HtmlWebpackPlugin configuration:
      chunks: ['polyfill', 'app', 'vendor'],
      chunksSortMode: 'manual'

After doing this, the issue should have been gone. But then another issue arises on IE11, related to missing Fetch API...don't worry it can be fixed adding whatwg-fetch polyfill.

The trick is that the new html-webpack-plugin supports chunksSortMode = 'manual', which keeps the order of the chunks as defined by the chunks array.

Hope this helps somebody.

I fixed this by removing import 'babel-polyfill'; from main.js, that's it....

I just wonder why this fixed the issue....

(this gave me the hint: jods4/aurelia-webpack-build#33 (comment))

@martincapello

Thanks, your solution worked! I didn't need to do your third step, though. The first two were enough.

@ryanpm40 first two steps worked for me. I had issues when I did the third

My entrypoints

entry: {
    polyfill: ['babel-polyfill'],
    app: ['isomorphic-fetch', 'aurelia-bootstrapper'],
    vendor: ['bluebird', 'jquery', './styles/bootstrap/js/bootstrap.min']
  },

Edit: Actually, this was only fine when doing a production build, it's still broken (for a different reason) when running the webpack dev server.

This is what worked for me. I think what's happening here is babel-polyfill is being favored over aurelia-polyfills, or perhaps somehow supporting it. When running locally with what I listed in the comment above I had issues in both ie and chrome with the platform module loader not being available.

entry: {
app: ['babel-polyfill', 'aurelia-bootstrapper'],
vendor: ['isomorphic-fetch', 'bluebird', 'jquery', './styles/bootstrap/js/bootstrap.min']
},

jods4 commented

@waywardz Yes, as I said above starting with Aurelia plugins RC3, putting the babel polyfills in front of your entry point should just work.
That's intuitively what you would do and I'm glad it now works but it required some contraptions in Aurelia's boot code.

@niieani @EisenbergEffect From the plugin perspective this is fixed. If (or once) the skeleton is updated I think this issue can be closed.

@jods4 first off, thank you for your investigation and efforts into looking into and fixing this.

Above, did you mean aurelia-polyfills instead of aurelia plugins? Or are you referring to aurelia webpack plugin?

I am using the following versions of each:
aurelia-polyfills: 1.2.2
aurelia-webpack-plugin: 2.0.0-rc.5

I was just pointing out that for me, the suggestions in this thread where a separate entrypoint was added prior to the app entrypoint didn't work (when running locally) and instead I had to put the babel-polyfill in the app entry point but I believe what I put above forces it to load prior to aurelia bootstrapper.

Are you saying that what I've got above, specifically

app: ['babel-polyfill', 'aurelia-bootstrapper'],

is what you would expect folks to have to do going forward?

jods4 commented

@waywardz I meant plugins, as I tweak the generated entry point to make it work more intuitively.

Yes, that's one way I expect people to include their polyfills.

Using multiple entrypoints is also an option, but you must be sure to include them in correct order in your HTML page.