Skip to content

Commit

Permalink
fix(@angular-devkit/build-angular): account for arrow function IIFE
Browse files Browse the repository at this point in the history
Updates the logic for removing Angular metadata and pure top-level functions to account for arrow-function-based IIFEs. Currently Angular doesn't generate arrow functions, but it's being explored in angular/angular#51637.
  • Loading branch information
crisbeto authored and dgp1130 committed Sep 5, 2023
1 parent 99e153a commit 6b08efa
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 7 deletions.
Expand Up @@ -58,13 +58,13 @@ export default function (): PluginObj {
}

// The metadata function is always emitted inside a function expression
if (!path.getFunctionParent()?.isFunctionExpression()) {
return;
}
const parent = path.getFunctionParent();

// Replace the metadata function with `void 0` which is the equivalent return value
// of the metadata function.
path.replaceWith(path.scope.buildUndefinedNode());
if (parent && (parent.isFunctionExpression() || parent.isArrowFunctionExpression())) {
// Replace the metadata function with `void 0` which is the equivalent return value
// of the metadata function.
path.replaceWith(path.scope.buildUndefinedNode());
}
},
},
};
Expand Down
Expand Up @@ -79,4 +79,27 @@ describe('elide-angular-metadata Babel plugin', () => {
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && void 0 })();`,
}),
);

it(
'elides ɵsetClassMetadata inside an arrow-function-based IIFE',
testCase({
input: `
import { Component } from '@angular/core';
export class SomeClass {}
/*@__PURE__*/ (() => { i0.ɵsetClassMetadata(Clazz, [{
type: Component,
args: [{
selector: 'app-lazy',
template: 'very lazy',
styles: []
}]
}], null, null); })();
`,
expected: `
import { Component } from '@angular/core';
export class SomeClass {}
/*@__PURE__*/ (() => { void 0 })();
`,
}),
);
});
Expand Up @@ -47,7 +47,10 @@ export default function (): PluginObj {
}

const callee = path.node.callee;
if (types.isFunctionExpression(callee) && path.node.arguments.length !== 0) {
if (
(types.isFunctionExpression(callee) || types.isArrowFunctionExpression(callee)) &&
path.node.arguments.length !== 0
) {
return;
}
// Do not annotate TypeScript helpers emitted by the TypeScript compiler.
Expand Down
Expand Up @@ -65,13 +65,29 @@ describe('pure-toplevel-functions Babel plugin', () => {
}),
);

it(
'annotates top-level arrow-function-based IIFE assignments with no arguments',
testCase({
input: 'var SomeClass = (() => { function SomeClass() { } return SomeClass; })();',
expected:
'var SomeClass = /*#__PURE__*/(() => { function SomeClass() { } return SomeClass; })();',
}),
);

it(
'does not annotate top-level IIFE assignments with arguments',
testCaseNoChange(
'var SomeClass = (function () { function SomeClass() { } return SomeClass; })(abc);',
),
);

it(
'does not annotate top-level arrow-function-based IIFE assignments with arguments',
testCaseNoChange(
'var SomeClass = (() => { function SomeClass() { } return SomeClass; })(abc);',
),
);

it(
'does not annotate call expressions inside function declarations',
testCaseNoChange('function funcDecl() { const result = someFunction(); }'),
Expand Down

0 comments on commit 6b08efa

Please sign in to comment.