Getting Ember JS to work with Internet Explorer 8

It’s a sad fact of life - sometimes web apps need to support a 7 year old browser like Internet Explorer 8. The BugMuncher website feedback widget is one such web app.

BugMuncher is built on Ember JS, which supported Internet Explorer 8 up until version 2, or at least, is supposed to. Due to a recent, and frankly phallic, move by the maintainers of UglifyJS, IE 8 support is now broken in all versions of Ember JS (See this pull request for details - this post will be about 80% technical info, and 20% rant at UglifyJS.)

Installing Ember JS for IE 8 Support

If you are already running Ember JS v1.13.X but can’t get your app to run in IE 8, skip straight to Fixing what UglifyJS Broke

So, how do you get Ember JS to play ball with Internet Explorer 8? First you need to install a pre-2.0 version of Ember JS, the most recent of which is currently v1.13.13. If you follow the standard install instructions you’ll end up with v2.7.0, which is no good.

Instead, first make sure you have Node.js 0.12 or higher and npm 2.7 or higher, then do the following:

npm install ember-cli@1.13.13

You may notice I’ve omitted the usual -g global flag, this is because you may still want to be able build other projects with the latest 2.X version of Ember JS, so you won’t want the global version of Ember to be 1.13. Personally I don’t have any global versions of ember, as it stops me being able to accidentally use the wrong version.

The downside to this is that running ember-cli commands are a little more verbose, as you need to specify a path to Ember, eg: Instead of running

ember init

to create a new Ember JS project, you’ll need to run

node_modules/.bin/ember init

As long as you remember to put node_modules/.bin/ in front of every ember-cli command this shouldn’t be an issue, but you can always make a symlink to save the additional keystrokes.

Of course, if you’re happy to only use Ember 1.13, feel free to install with -g flag, and run ember-cli commands as normal.

Internet Explorer 8 not working in Ember’s production environment

Before the 30th June, 2016, the steps above would have been enough to build and deploy an Ember JS project with IE 8 support. But with the release of UglifyJS 2.7.0, the aptly named --screw-ie8 option was changed from default false to default true.

This means when developing your Ember JS app, everything will work fine in IE 8, but as soon as you build in the production environment, UglifyJS is introduced to the asset pipeline, and your app will no longer work in Internet Explorer 8. You’d think a change with such potential to wreak havoc on existing projects would have been saved until version 3.0, but no.

If you’re affected by this change, you’ll likely see a cryptic error message in IE 8, such as:

Message: Expected identifier
Line: 1
Char: 1234
Code: 0
URI: http://yoursite.com/assets/vendor-69700f8fc375f182fa7e54be303c21d2.js

And if you go the line and character in that file, you’ll probably see something innocent looking like .default. The problem is that default, along with class, private and a few others are reserved terms in IE 8, and can’t be used as object properties.

The way around this is to pass the property name as a string in square brackets, which is what UglifyJS did before v2.7:

// Works everywhere
someObject['default']

But in UglifyJS 2.7, with the --screw-ie8 option being default true, you instead get:

// Breaks in IE 8
someObject.default

Which is what causes Internet Explorer 8 to shit itself.

Fixing what UglifyJS Broke

The problem is that Ember JS uses broccoli-uglify-sourcemap, which in turn uses UglifyJS. broccoli-uglify-sourcemap specifies an UglifyJS of version 2.6.0 or higher, but below verions 3.0, which seems like a sane choice, as surely breaking changes will only happen in major releases. Right UglifyJS?

But enough ranting, how do you fix this? Once I’d found the cause of my builds not working in IE 8, the fix was actually fairly straight forward - you need to edit the file ember-cli-build.js in your Ember JS project, and where you see:

  var app = new EmberApp(defaults, {
    // Add options here
  });

Add these options to tell UglifyJS not to ‘screw IE 8’

  var app = new EmberApp(defaults, {
    // Force UglifyJS 2.7.0 + to support IE 8
    minifyJS: {
      options: {
        compress: { screw_ie8: false },
        mangle:   { screw_ie8: false },
        output:   { screw_ie8: false }
      }
    }
  });

I hope this post will help to stop anyone else wasting hours tracking down an issue that should never have been introduced in the first place.

Seriously UglifyJS, no one likes having to support Internet Explorer 8, but like it or not, some of us still have to. Inverting the default for an option that will break any Javascript app that uses Uglify and needs to support IE 8 really should have been considered a breaking change and treated as such, ie: held off until the next major release, v3.0 in this case.

I know I shouldn’t blame Uglify, it’s not like I had to pay for their library, and once I figured out what the issue was the fix was pretty easy. The real enemy is Internet Explorer 8 and it’s continued ~5% market share. I eagerly await the day I can finally drop IE 8 support from BugMuncher.

- Matt