mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
fix(ngcc): support alternate wrapper function layout for UMD (#43879)
Recently rollup, used by ng-packagr, changed the position of parentheses around its generated UMD wrapper functions. This commit ensures that ngcc can handle both. Fixes #43870 PR Close #43879
This commit is contained in:
parent
60f3b33b4b
commit
ec8a565655
2 changed files with 44 additions and 15 deletions
|
|
@ -511,30 +511,40 @@ export class UmdReflectionHost extends Esm5ReflectionHost {
|
|||
}
|
||||
|
||||
export function parseStatementForUmdModule(statement: ts.Statement): UmdModule|null {
|
||||
const wrapperCall = getUmdWrapperCall(statement);
|
||||
if (!wrapperCall) return null;
|
||||
const wrapper = getUmdWrapper(statement);
|
||||
if (wrapper === null) return null;
|
||||
|
||||
const wrapperFn = wrapperCall.expression;
|
||||
if (!ts.isFunctionExpression(wrapperFn)) return null;
|
||||
|
||||
const factoryFnParamIndex = wrapperFn.parameters.findIndex(
|
||||
const factoryFnParamIndex = wrapper.fn.parameters.findIndex(
|
||||
parameter => ts.isIdentifier(parameter.name) && parameter.name.text === 'factory');
|
||||
if (factoryFnParamIndex === -1) return null;
|
||||
|
||||
const factoryFn = stripParentheses(wrapperCall.arguments[factoryFnParamIndex]);
|
||||
const factoryFn = stripParentheses(wrapper.call.arguments[factoryFnParamIndex]);
|
||||
if (!factoryFn || !ts.isFunctionExpression(factoryFn)) return null;
|
||||
|
||||
return {wrapperFn, factoryFn};
|
||||
return {wrapperFn: wrapper.fn, factoryFn};
|
||||
}
|
||||
|
||||
function getUmdWrapperCall(statement: ts.Statement): ts.CallExpression&
|
||||
{expression: ts.FunctionExpression}|null {
|
||||
if (!ts.isExpressionStatement(statement) || !ts.isParenthesizedExpression(statement.expression) ||
|
||||
!ts.isCallExpression(statement.expression.expression) ||
|
||||
!ts.isFunctionExpression(statement.expression.expression.expression)) {
|
||||
return null;
|
||||
function getUmdWrapper(statement: ts.Statement):
|
||||
{call: ts.CallExpression, fn: ts.FunctionExpression}|null {
|
||||
if (!ts.isExpressionStatement(statement)) return null;
|
||||
|
||||
if (ts.isParenthesizedExpression(statement.expression) &&
|
||||
ts.isCallExpression(statement.expression.expression) &&
|
||||
ts.isFunctionExpression(statement.expression.expression.expression)) {
|
||||
// (function () { ... } (...) );
|
||||
const call = statement.expression.expression;
|
||||
const fn = statement.expression.expression.expression;
|
||||
return {call, fn};
|
||||
}
|
||||
return statement.expression.expression as ts.CallExpression & {expression: ts.FunctionExpression};
|
||||
if (ts.isCallExpression(statement.expression) &&
|
||||
ts.isParenthesizedExpression(statement.expression.expression) &&
|
||||
ts.isFunctionExpression(statement.expression.expression.expression)) {
|
||||
// (function () { ... }) (...);
|
||||
const call = statement.expression;
|
||||
const fn = statement.expression.expression.expression;
|
||||
return {call, fn};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -747,6 +747,25 @@ runInEachFileSystem(() => {
|
|||
entryPoint.packageJson.main = './bundles/valid_entry_point';
|
||||
expect(getEntryPointFormat(fs, entryPoint, browserOrMain)).toBe('umd');
|
||||
});
|
||||
|
||||
it('should match alternate UMD format', () => {
|
||||
// Note that in this format, instead of the whole wrapper being enclosed in parentheses,
|
||||
// only the wrapper function is enclosed and the call is not inside the parentheses.
|
||||
loadTestFiles([{
|
||||
name: _(
|
||||
'/project/node_modules/some_package/valid_entry_point/bundles/valid_entry_point/index.js'),
|
||||
contents: `
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core')) :
|
||||
typeof define === 'function' && define.amd ? define('@angular/common', ['exports', '@angular/core'], factory) :
|
||||
(global = global || self, factory((global.ng = global.ng || {}, global.ng.common = {}), global.ng.core));
|
||||
})(this, function (exports, core) { 'use strict'; });
|
||||
`
|
||||
}]);
|
||||
|
||||
entryPoint.packageJson.main = './bundles/valid_entry_point';
|
||||
expect(getEntryPointFormat(fs, entryPoint, browserOrMain)).toBe('umd');
|
||||
});
|
||||
});
|
||||
|
||||
it('should return `undefined` if the `browser` property is not a string', () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue