diff --git a/packages/babel-cli/test/fixtures/babel-external-helpers/--whitelist/stdout.txt b/packages/babel-cli/test/fixtures/babel-external-helpers/--whitelist/stdout.txt index 8b78039c1add..d75b52e29f44 100644 --- a/packages/babel-cli/test/fixtures/babel-external-helpers/--whitelist/stdout.txt +++ b/packages/babel-cli/test/fixtures/babel-external-helpers/--whitelist/stdout.txt @@ -14,6 +14,9 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); + Object.defineProperty(Constructor, "prototype", { + writable: false + }); return Constructor; } diff --git a/packages/babel-helpers/src/helpers.ts b/packages/babel-helpers/src/helpers.ts index b288be59b933..891aad0d2815 100644 --- a/packages/babel-helpers/src/helpers.ts +++ b/packages/babel-helpers/src/helpers.ts @@ -223,6 +223,7 @@ helpers.createClass = helper("7.0.0-beta.0")` export default function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); + Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } `; @@ -334,12 +335,15 @@ helpers.inherits = helper("7.0.0-beta.0")` if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - writable: true, - configurable: true - } + Object.defineProperty(subClass, "prototype", { + value: Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + writable: true, + configurable: true + } + }), + writable: false, }); if (superClass) setPrototypeOf(subClass, superClass); } diff --git a/packages/babel-plugin-transform-classes/src/transformClass.ts b/packages/babel-plugin-transform-classes/src/transformClass.ts index c25732f717a7..e1240d274c57 100644 --- a/packages/babel-plugin-transform-classes/src/transformClass.ts +++ b/packages/babel-plugin-transform-classes/src/transformClass.ts @@ -60,6 +60,7 @@ export default function transformClass( pushedInherits: false, protoAlias: null, isLoose: false, + createClassInjected: false, dynamicKeys: new Map(), @@ -93,6 +94,10 @@ export default function transformClass( }, ]); + function createClassHelper(args) { + return t.callExpression(classState.file.addHelper("createClass"), args); + } + /** * Creates a class constructor or bail out if there is none */ @@ -240,11 +245,8 @@ export default function transformClass( } args = args.slice(0, lastNonNullIndex + 1); - body.push( - t.expressionStatement( - t.callExpression(classState.file.addHelper("createClass"), args), - ), - ); + body.push(t.expressionStatement(createClassHelper(args))); + classState.createClassInjected = true; } } @@ -737,10 +739,15 @@ export default function transformClass( if (constructorOnly) { // named class with only a constructor - return t.toExpression(body[0]); + return createClassHelper([t.toExpression(body[0])]); + } + + let returnArg = t.cloneNode(classState.classRef); + if (!classState.createClassInjected) { + returnArg = createClassHelper([returnArg]); } - body.push(t.returnStatement(t.cloneNode(classState.classRef))); + body.push(t.returnStatement(returnArg)); const container = t.arrowFunctionExpression( closureParams, t.blockStatement(body, directives), diff --git a/packages/babel-plugin-transform-classes/test/fixtures/exec/prototype-descriptor.js b/packages/babel-plugin-transform-classes/test/fixtures/exec/prototype-descriptor.js new file mode 100644 index 000000000000..fa2f89348401 --- /dev/null +++ b/packages/babel-plugin-transform-classes/test/fixtures/exec/prototype-descriptor.js @@ -0,0 +1,16 @@ +class A {} +class B extends A {} + +expect(Object.getOwnPropertyDescriptor(A, "prototype")).toEqual({ + value: A.prototype, + configurable: false, + enumerable: false, + writable: false, +}); + +expect(Object.getOwnPropertyDescriptor(B, "prototype")).toEqual({ + value: B.prototype, + configurable: false, + enumerable: false, + writable: false, +});