diff --git a/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js b/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js index b9e88388bc..2d7102ba50 100644 --- a/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js +++ b/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js @@ -206,31 +206,42 @@ function applyTargetDecorators(path, state, decoratedProps) { ]); } +function decoratedClassToExpression({ node, scope }) { + if (!hasClassDecorators(node) && !hasMethodDecorators(node.body.body)) { + return; + } + + const ref = node.id + ? t.cloneNode(node.id) + : scope.generateUidIdentifier("class"); + + return t.variableDeclaration("let", [ + t.variableDeclarator(ref, t.toExpression(node)), + ]); +} + export default { - ClassDeclaration(path) { - const { node } = path; + ExportDefaultDeclaration(path) { + const decl = path.get("declaration"); + if (!decl.isClassDeclaration()) return; - if (!hasClassDecorators(node) && !hasMethodDecorators(node.body.body)) { - return; - } - - const ref = node.id - ? t.cloneNode(node.id) - : path.scope.generateUidIdentifier("class"); - const letDeclaration = t.variableDeclaration("let", [ - t.variableDeclarator(ref, t.toExpression(node)), - ]); - - if (path.parentPath.isExportDefaultDeclaration()) { - // Split the class declaration and the export into two separate statements. - path.parentPath.replaceWithMultiple([ - letDeclaration, + const replacement = decoratedClassToExpression(decl); + if (replacement) { + path.replaceWithMultiple([ + replacement, t.exportNamedDeclaration(null, [ - t.exportSpecifier(t.cloneNode(ref), t.identifier("default")), + t.exportSpecifier( + t.cloneNode(replacement.declarations[0].id), + t.identifier("default"), + ), ]), ]); - } else { - path.replaceWith(letDeclaration); + } + }, + ClassDeclaration(path) { + const replacement = decoratedClassToExpression(path); + if (replacement) { + path.replaceWith(replacement); } }, ClassExpression(path, state) { diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/input.mjs new file mode 100644 index 0000000000..ed42ff1394 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/input.mjs @@ -0,0 +1,4 @@ +export default class { + @foo + bar() {} +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/options.json new file mode 100644 index 0000000000..563691359c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/options.json @@ -0,0 +1,6 @@ +{ + "plugins": [ + ["proposal-decorators", { "legacy": true }], + "proposal-class-properties" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/output.mjs new file mode 100644 index 0000000000..f35dc48db9 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/output.mjs @@ -0,0 +1,10 @@ +var _class2; + +function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object['ke' + 'ys'](descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object['define' + 'Property'](target, property, desc); desc = null; } return desc; } + +let _class = (_class2 = class { + bar() {} + +}, (_applyDecoratedDescriptor(_class2.prototype, "bar", [foo], Object.getOwnPropertyDescriptor(_class2.prototype, "bar"), _class2.prototype)), _class2); + +export { _class as default };