diff --git a/packages/babel-core/src/config/full.js b/packages/babel-core/src/config/full.js index a65a2e9ff0..0ae4ade63b 100644 --- a/packages/babel-core/src/config/full.js +++ b/packages/babel-core/src/config/full.js @@ -174,8 +174,7 @@ const loadDescriptor = makeWeakCache( let item = value; if (typeof value === "function") { - const api = Object.assign(Object.create(context), makeAPI(cache)); - + const api = Object.assign({}, context, makeAPI(cache)); try { item = value(api, options, dirname); } catch (e) { diff --git a/packages/babel-helper-plugin-utils/src/index.js b/packages/babel-helper-plugin-utils/src/index.js index d789aaafb4..e8534608d8 100644 --- a/packages/babel-helper-plugin-utils/src/index.js +++ b/packages/babel-helper-plugin-utils/src/index.js @@ -3,7 +3,7 @@ export function declare(builder) { if (!api.assertVersion) { // Inject a custom version of 'assertVersion' for Babel 6 and early // versions of Babel 7's beta that didn't have it. - api = Object.assign({}, api, { + api = Object.assign(copyApiObject(api), { assertVersion(range) { throwVersionError(range, api.version); }, @@ -14,6 +14,33 @@ export function declare(builder) { }; } +function copyApiObject(api) { + // Babel >= 7 <= beta.41 passed the API as a new object that had + // babel/core as the prototype. While slightly faster, it also + // means that the Object.assign copy below fails. Rather than + // keep complexity, the Babel 6 behavior has been reverted and this + // normalizes all that for Babel 7. + let proto = null; + if (typeof api.version === "string" && /^7\./.test(api.version)) { + proto = Object.getPrototypeOf(api); + if ( + proto && + (!has(proto, "version") || + !has(proto, "transform") || + !has(proto, "template") || + !has(proto, "types")) + ) { + proto = null; + } + } + + return Object.assign({}, proto, api); +} + +function has(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); +} + function throwVersionError(range, version) { if (typeof range === "number") { if (!Number.isInteger(range)) {