Skip to content

Commit

Permalink
fix(@angular-devkit/build-angular): babel adjust enum plugin incorrec…
Browse files Browse the repository at this point in the history
…tly transforming loose enums

With Angular Package Format v13, we will be using a more recent version of rollup. Rollup
always suffixed exports to avoid collisions, but with the most recent version, the order
has changed slightly changed. e.g. previously for `@angular/core`, there were two instances
of the `ViewEncapsulation` enum part of the `fesm` bundle. The second instance of the enum
orginated from the compiler <--> core facade and it got renamed to avoid conflicts with the
actual declaration of `ViewEncapsulation`. Now this has changed, and the first export is
being renamed instead. This now breaks at runtime because the first export is being incorrectly
transformed by the adjust enum plugin of `build-angular`. The plugin always had this problem
of incorrectly transforming the enums, but it never surfaced because only the face enum has been
transformed (which is not used at runtime). e.g.

consider the following input in `core.mjs`:

```
var ViewEncapsulation$1;
(function (ViewEncapsulation) {
    ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated";
})(ViewEncapsulation$1 || (ViewEncapsulation$1 = {}));
```

this is transformed into:

```
var ViewEncapsulation$1 = /*#__PURE__*/(() => {
  ViewEncapsulation$1 = ViewEncapsulation$1 || {};
  ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated";
}());
```

Note how the enum assignment for `Emulated` incorrectly still uses the non-suffixed
identifier that previously was part of the callee wrapper function.
  • Loading branch information
devversion authored and clydin committed Sep 24, 2021
1 parent 8f33bdb commit 0e7277c
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
Expand Up @@ -76,9 +76,17 @@ export default function (): PluginObj {
return;
}

const enumCalleeParam = enumCallee.node.params[0];
const isEnumCalleeMatching =
types.isIdentifier(enumCalleeParam) && enumCalleeParam.name === declarationId.name;

// Loose mode rewrites the enum to a shorter but less TypeScript-like form
// Note: We only can apply the `loose` mode transformation if the callee parameter matches
// with the declaration identifier name. This is necessary in case the the declaration id has
// been renamed to avoid collisions, as the loose transform would then break the enum assignments
// which rely on the differently-named callee identifier name.
let enumAssignments: types.ExpressionStatement[] | undefined;
if (loose) {
if (loose && isEnumCalleeMatching) {
enumAssignments = [];
}

Expand Down
Expand Up @@ -240,4 +240,31 @@ describe('adjust-typescript-enums Babel plugin', () => {
options: { loose: true },
});
});

it(
'should not wrap TypeScript enums in loose mode if the declaration identifier has been ' +
'renamed to avoid collisions',
() => {
testCase({
input: `
var ChangeDetectionStrategy$1;
(function (ChangeDetectionStrategy) {
ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush";
ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default";
})(ChangeDetectionStrategy$1 || (ChangeDetectionStrategy$1 = {}));
`,
expected: `
var ChangeDetectionStrategy$1 = /*#__PURE__*/ (() => {
(function (ChangeDetectionStrategy) {
ChangeDetectionStrategy[(ChangeDetectionStrategy["OnPush"] = 0)] = "OnPush";
ChangeDetectionStrategy[(ChangeDetectionStrategy["Default"] = 1)] = "Default";
})(ChangeDetectionStrategy$1 || (ChangeDetectionStrategy$1 = {}));
return ChangeDetectionStrategy$1;
})();
`,
options: { loose: true },
});
},
);
});

0 comments on commit 0e7277c

Please sign in to comment.