diff --git a/packages/babel-plugin-proposal-decorators/package.json b/packages/babel-plugin-proposal-decorators/package.json index 36954ddb54c5..c9c1ecf2e253 100644 --- a/packages/babel-plugin-proposal-decorators/package.json +++ b/packages/babel-plugin-proposal-decorators/package.json @@ -23,6 +23,7 @@ "@babel/helper-create-class-features-plugin": "workspace:^", "@babel/helper-plugin-utils": "workspace:^", "@babel/helper-replace-supers": "workspace:^", + "@babel/helper-split-export-declaration": "workspace:^", "@babel/plugin-syntax-decorators": "workspace:^", "charcodes": "^0.2.0" }, diff --git a/packages/babel-plugin-proposal-decorators/src/transformer-2021-12.ts b/packages/babel-plugin-proposal-decorators/src/transformer-2021-12.ts index f84ab005db41..e748c09740cf 100644 --- a/packages/babel-plugin-proposal-decorators/src/transformer-2021-12.ts +++ b/packages/babel-plugin-proposal-decorators/src/transformer-2021-12.ts @@ -2,6 +2,7 @@ import type { NodePath, Scope } from "@babel/traverse"; import { types as t, template } from "@babel/core"; import syntaxDecorators from "@babel/plugin-syntax-decorators"; import ReplaceSupers from "@babel/helper-replace-supers"; +import splitExportDeclaration from "@babel/helper-split-export-declaration"; import * as charCodes from "charcodes"; type ClassDecoratableElement = @@ -1009,24 +1010,23 @@ export default function ({ assertVersion, assumption }, { loose }) { inherits: syntaxDecorators, visitor: { - ClassDeclaration(path: NodePath, state: any) { - if (VISITED.has(path)) return; - - const newPath = transformClass(path, state, constantSuper); - - if (newPath) { - VISITED.add(newPath); + "ExportNamedDeclaration|ExportDefaultDeclaration"(path) { + const { declaration } = path.node; + if ( + declaration?.type === "ClassDeclaration" && + // When compiling class decorators we need to replace the class + // binding, so we must split it in two separate declarations. + declaration.decorators?.length > 0 + ) { + splitExportDeclaration(path); } }, - ClassExpression(path: NodePath, state: any) { + Class(path: NodePath, state: any) { if (VISITED.has(path)) return; const newPath = transformClass(path, state, constantSuper); - - if (newPath) { - VISITED.add(newPath); - } + if (newPath) VISITED.add(newPath); }, }, }; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/default-anonymous/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/default-anonymous/input.mjs new file mode 100644 index 000000000000..05db70faed30 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/default-anonymous/input.mjs @@ -0,0 +1 @@ +export default @dec class A {} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/default-anonymous/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/default-anonymous/output.mjs new file mode 100644 index 000000000000..4069495d7e58 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/default-anonymous/output.mjs @@ -0,0 +1,17 @@ +var _initClass, _dec; + +let _A; + +_dec = dec + +class A { + static { + [_A, _initClass] = babelHelpers.applyDecs(this, [], [_dec]); + } + static { + _initClass(); + + } +} + +export { _A as default }; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/default-named/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/default-named/input.mjs new file mode 100644 index 000000000000..31cdac17444e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/default-named/input.mjs @@ -0,0 +1 @@ +export default @dec class {} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/default-named/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/default-named/output.mjs new file mode 100644 index 000000000000..960e68744541 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/default-named/output.mjs @@ -0,0 +1,17 @@ +var _initClass, _dec; + +let _default2; + +_dec = dec + +class _default { + static { + [_default2, _initClass] = babelHelpers.applyDecs(this, [], [_dec]); + } + static { + _initClass(); + + } +} + +export { _default2 as default }; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/member-decorator/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/member-decorator/input.mjs new file mode 100644 index 000000000000..f72e0e9c2249 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/member-decorator/input.mjs @@ -0,0 +1,3 @@ +export class A { + @dec x; +} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/member-decorator/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/member-decorator/output.mjs new file mode 100644 index 000000000000..d2ebe06be6fc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/member-decorator/output.mjs @@ -0,0 +1,9 @@ +var _dec, _init_x; + +_dec = dec +export class A { + static { + [_init_x] = babelHelpers.applyDecs(this, [[_dec, 0, "x"]], []); + } + x = _init_x(this); +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/named/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/named/input.mjs new file mode 100644 index 000000000000..367f946714b0 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/named/input.mjs @@ -0,0 +1 @@ +export @dec class A {} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/named/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/named/output.mjs new file mode 100644 index 000000000000..21f340a53b63 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/named/output.mjs @@ -0,0 +1,17 @@ +var _initClass, _dec; + +let _A; + +_dec = dec + +class A { + static { + [_A, _initClass] = babelHelpers.applyDecs(this, [], [_dec]); + } + static { + _initClass(); + + } +} + +export { _A as A }; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/no-decorators/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/no-decorators/input.mjs new file mode 100644 index 000000000000..bc88730f95a8 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/no-decorators/input.mjs @@ -0,0 +1,4 @@ +export class A {} + +class B {} +export { B }; \ No newline at end of file diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/no-decorators/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/no-decorators/output.mjs new file mode 100644 index 000000000000..f95acfebc1c9 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/no-decorators/output.mjs @@ -0,0 +1,5 @@ +export class A {} + +class B {} + +export { B }; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/options.json new file mode 100644 index 000000000000..a18e0b8e833f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-exported/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2021-12" }]] +} diff --git a/yarn.lock b/yarn.lock index a9e4eb9e9e7b..68eaf27a56f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1309,6 +1309,7 @@ __metadata: "@babel/helper-plugin-test-runner": "workspace:^" "@babel/helper-plugin-utils": "workspace:^" "@babel/helper-replace-supers": "workspace:^" + "@babel/helper-split-export-declaration": "workspace:^" "@babel/plugin-syntax-decorators": "workspace:^" "@babel/traverse": "workspace:^" babel-plugin-polyfill-es-shims: ^0.6.0