Use legacy workaround for @babel/runtime/helpers/inheritsLoose.

IE10 does not support setting the __proto__ property of objects as an
alternative to Object.setPrototypeOf. Because Babel generates code that
uses the @babel/runtime/helpers/inheritsLoose helper, and that helper
relies on setting __proto__, subclassing fails in Babel-generated code in
IE10 (and earlier), which causes a white screen of death in newly created
Meteor apps.

This commit checks whether setting __proto__ works, and (if not) overrides
the inheritsLoose helper with an implementation that does not rely on
setting __proto__. This logic applies only in legacy browsers, thanks to
api.addFiles("legacy.js", "legacy").

Although this shim isn't perfect (for example, there is no way to set up
true inheritance of static properties), it will allow inheritance to work
in browsers that would otherwise be completely broken.

Since IE10 represents only 0.1% of the world market, we should not
overinvest in keeping it working, but this seemed like a good opportunity
to take advantage of legacy bundling, without adding any new code to the
modern bundle.
This commit is contained in:
Ben Newman
2018-05-01 19:37:59 -04:00
parent 454422f9f0
commit 8bfdea712a
2 changed files with 55 additions and 1 deletions

View File

@@ -0,0 +1,53 @@
// This module contains various legacy workarounds for @babel/runtime issues
// in older browsers. Note that this module is loaded only in legacy
// environments, and no changes are made unless they are necessary.
var hasOwn = Object.prototype.hasOwnProperty;
var helpers = {};
function assign(into, from) {
Object.keys(from).forEach(function (key) {
if (! hasOwn.call(into, key)) {
into[key] = from[key];
}
});
return into;
}
var obj = {};
obj.__proto__ = { test: obj };
var canSetProto = obj.test === obj;
if (! canSetProto) {
// Browsers that don't allow setting __proto__ (and also do not support
// Object.setPrototypeOf) cannot use the inheritsLoose @babel/runtime
// helper module, so we replace it with a similar module that works
// infinitely better in older browsers.
helpers.inheritsLoose = function (require, exports, module) {
module.exports = function (subclass, superclass) {
subclass.prototype = assign(
Object.create(superclass.prototype),
subclass.prototype
);
// This isn't true static inheritance, since static properties added
// to or removed from the superclass later will not be reflected on
// the subclass, but this approximation is the best that we can do.
assign(subclass, superclass);
};
};
}
// Install @babel/runtime/helpers/... modules that will take precedence
// over the actual modules, regardless of which gets installed first,
// because these replacement modules don't have a .js file extension.
if (Object.keys(helpers).length > 0) {
meteorInstall({
node_modules: {
"@babel": {
runtime: {
helpers: helpers
}
}
}
});
}

View File

@@ -1,7 +1,7 @@
Package.describe({
name: "babel-runtime",
summary: "Runtime support for output of Babel transpiler",
version: '1.2.2',
version: '1.3.0',
documentation: 'README.md'
});
@@ -12,5 +12,6 @@ Npm.depends({
Package.onUse(function (api) {
api.use("modules");
api.mainModule("babel-runtime.js");
api.addFiles("legacy.js", "legacy");
api.export("meteorBabelHelpers");
});