javascriptdebuggingwebpackinternet-explorer-11palemoon

Why is this an error in IE11 and Pale Moon?


I reported a Javascript bug to the FreeNAS team on their bug tracker, related to their upcoming release which won't work due to a JS syntax error on some less common browsers, but I'm curious why it's an error.

The code snippet raises a pretty well-defined error on Win8.1 default browser (IE11) and Pale Moon (Firefox based) browsers, but no error on Firefox or Vivaldi (Chrome based). What does the code actually do, and why does it trigger a reserved word error/syntax error in these browsers?

The code is hard to trace, it looks like a webpack minified file and I'm not familiar enough with the base + build systems to follow where it ultimately originates before packing.

The relevant code snippet that triggers the error looks like this in the browser consoles:

webpackJsonp([20], {

  ... long list of function defs ...

  BFiu: function(t, e, n) {
    "use strict";
    n.d(e, "a", function() {
      return r
    });
    var o = n("HcJ8");
    n.n(o);
    let i = {
      Queue: 0,
      Uploading: 1,
      Done: 2,
      Cancelled: 3
    };
    i[i.Queue] = "Queue",
    i[i.Uploading] = "Uploading",
    i[i.Done] = "Done", 
    i[i.Cancelled] = "Cancelled";
    class r {}
  },

  ... more function defs ...

},
[0]);

According to the JS console, it's the line class r{} which causes a fatal syntax error in some browsers, and kills the GUI loading script. Pale Moon states that the problem is misuse of a reserved word "class", IE11 just points to the same word and reports a syntax error. But on other browsers it's fine.

Intuitively I would expect that reserved word misuse of such a key JS word would be fairly well-defined even across notoriously different browsers and JS engines (apparently not?), so I'm intrigued. What's going on?

Ideally also (if able to help), how can I find the upstream source for this code snippet, so I can take a look at its issue/bug tracker?

Source code: The code snippet comes from a file "main.57ebfd2da123881a1a70.bundle.js" in FreeNAS 11.2-RC2. I've traced it as far as line 69 of this file in the FreeNAS build/WebUI system, where the filename is referenced apparently when webpack builds it, but I can't work out how to track back to its origin, to see which module this snippet is from, or if there's an upstream bug report on whatever project the module came from.


Solution

  • class is an ES6 (ES2015) keyword which works on most browsers, but not on ancient ones like IE (last version of IE, IE11, was released in 2013). Although PaleMoon states they're mostly ES6 compliant, it doesn't appear to support class yet - the founder's opinion is:

    Classes in JS are simply a really, really bad idea, trying to enforce OO structures from a different language to something that is simply not designed to do things that way.

    There's also no reason to use classes per se, as anything done with classes can be done with basic and completely compatible use of JS prototypes. Prototyping is there for a reason; use it.

    The general solution for devs who use "class" syntax and want their code to be compatible with IE, PaleMoon, and other non-standards-compliant browsers is to integrate Babel into their build process, which can automatically transpile a codebase's ES6+ syntax (including the "class" keyword) into ES5 syntax. For example:

    class Foo {
    }
    

    turns into

    "use strict";
    
    function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
    
    var Foo = function Foo() {
      _classCallCheck(this, Foo);
    };