Ember 3 on FF 38


#1

I am building an app that has a requirement that it needs to be compatible back to Firefox 38.

When I build and run it in this old version of FF, I get the following errors:

SyntaxError: class is a reserved identifier vendor.js:125836:0
ReferenceError: define is not defined matrix-frontend.js:5:0
TypeError: (intermediate value).extend is undefined

It seems that babel is not working right.

My ember-cli-build.js looks like this:

'use strict';

const EmberApp = require('ember-cli/lib/broccoli/ember-app');

module.exports = function(defaults) {
  let app = new EmberApp(defaults, {
    babel: {
      plugins: [
        'transform-object-rest-spread'
      ]
    },
    'ember-cli-babel': {
      includePolyfill: true
    }
  });

  return app.toTree();
};

Does anyone know how I can get polyfills for class and define working to be able to run 3.X on FF38?


#2

Most likely define is missing due to the first error (RE: class being a reserved word).

  1. are you running a prod build (if you are, the default targets would make the app compatible with even IE11 which should be fine for FF38 also).
  2. have you tweaked your config/targets.js to reflect your support requirements? You should be able to add FF38…

#3

Thanks @rwjblue.

  1. Yes.
  2. The relevant parts of my targets.js are:
const browsers = [
  'last 1 Chrome versions',
  'last 1 Safari versions'
];

...

if (isCI || isProduction) {
  browsers.push('ie 11');
  browsers.push('Firefox >= 38');
} else {
  browsers.push('last 1 Firefox versions');
}

#4

I tracked down the issue to a bit of a third party plugin that does not seem to be translated:

"/path/to/node_modules/reconnecting-websocket/dist/reconnecting-websocket-cjs.js":[function(require,module,exports){
'use strict';

class Event {
    constructor(type, target) {
        this.target = target;
        this.type = type;
    }
}
class ErrorEvent extends Event {
    constructor(error, target) {
        super('error', target);
        this.message = error.message;
        this.error = error;
    }
}
class CloseEvent extends Event {
    constructor(code = 1000, reason = '', target) {
        super('close', target);
        this.wasClean = true;
        this.code = code;
        this.reason = reason;
    }
}

/*!
 * Reconnecting WebSocket
 * by Pedro Ladaria <pedro.ladaria@gmail.com>
 * https://github.com/pladaria/reconnecting-websocket
 * License MIT
 */
const getGlobalWebSocket = () => {
    if (typeof WebSocket !== 'undefined') {
        // @ts-ignore
        return WebSocket;
    }
};

So, if I remove this dependency, it seems like it will build. But, that begs the next question of why it would ignore this package.

(Forgive my ignorance if I am missing something obvious, I really am not an Ember expert)


#5

It depends how you brought that dependency into the build, was it via ember-auto-import / ember-cli-cjs-transform / app.import / other?

For example, we do not run Babel across things that were app.imported.


#6

So … I did with with something like this:

import package from 'npm:package'

Which clearly does not work. And now that I think it thru, makes sense why Ember’s build tool would not get this.

@rwjblue Thank you so much. I should have replied earlier. But as soon as I saw your post I immediately went to fix the problem and voila, and then forgot to come back to say thank you.


#7

That pattern (using "npm:package") is actually a feature of ember-browserify and it does work if you add ember-browserify. But ember-browserify is deprecated in favor of ember-auto-import, which lets you do a regular NPM import.


#8

Thanks for the heads up!