Skip to content

Commit c7a9987

Browse files
petebacondarwinjasonaden
authored andcommitted
feat(ivy): ngcc - implement CommonJsRenderingFormatter (angular#30200)
PR Close angular#30200
1 parent 1bdec3e commit c7a9987

File tree

3 files changed

+511
-1
lines changed

3 files changed

+511
-1
lines changed

packages/compiler-cli/ngcc/src/packages/entry_point.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {Logger} from '../logging/logger';
1212
/**
1313
* The possible values for the format of an entry-point.
1414
*/
15-
export type EntryPointFormat = 'esm5' | 'esm2015' | 'umd';
15+
export type EntryPointFormat = 'esm5' | 'esm2015' | 'umd' | 'commonjs';
1616

1717
/**
1818
* An object containing information about an entry-point, including paths
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import {dirname, relative} from 'canonical-path';
9+
import * as ts from 'typescript';
10+
import MagicString from 'magic-string';
11+
import {Import, ImportManager} from '../../../src/ngtsc/translator';
12+
import {ExportInfo} from '../analysis/private_declarations_analyzer';
13+
import {isRequireCall} from '../host/commonjs_host';
14+
import {NgccReflectionHost} from '../host/ngcc_host';
15+
import {Esm5RenderingFormatter} from './esm5_rendering_formatter';
16+
import {stripExtension} from './utils';
17+
18+
/**
19+
* A RenderingFormatter that works with CommonJS files, instead of `import` and `export` statements
20+
* the module is an IIFE with a factory function call with dependencies, which are defined in a
21+
* wrapper function for AMD, CommonJS and global module formats.
22+
*/
23+
export class CommonJsRenderingFormatter extends Esm5RenderingFormatter {
24+
constructor(protected commonJsHost: NgccReflectionHost, isCore: boolean) {
25+
super(commonJsHost, isCore);
26+
}
27+
28+
/**
29+
* Add the imports below any in situ imports as `require` calls.
30+
*/
31+
addImports(output: MagicString, imports: Import[], file: ts.SourceFile): void {
32+
const insertionPoint = this.findEndOfImports(file);
33+
const renderedImports =
34+
imports.map(i => `var ${i.qualifier} = require('${i.specifier}');\n`).join('');
35+
output.appendLeft(insertionPoint, renderedImports);
36+
}
37+
38+
/**
39+
* Add the exports to the bottom of the file.
40+
*/
41+
addExports(
42+
output: MagicString, entryPointBasePath: string, exports: ExportInfo[],
43+
importManager: ImportManager, file: ts.SourceFile): void {
44+
exports.forEach(e => {
45+
const basePath = stripExtension(e.from);
46+
const relativePath = './' + relative(dirname(entryPointBasePath), basePath);
47+
const namedImport = entryPointBasePath !== basePath ?
48+
importManager.generateNamedImport(relativePath, e.identifier) :
49+
{symbol: e.identifier, moduleImport: null};
50+
const importNamespace = namedImport.moduleImport ? `${namedImport.moduleImport}.` : '';
51+
const exportStr = `\nexports.${e.identifier} = ${importNamespace}${namedImport.symbol};`;
52+
output.append(exportStr);
53+
});
54+
}
55+
56+
protected findEndOfImports(sf: ts.SourceFile): number {
57+
for (const statement of sf.statements) {
58+
if (ts.isExpressionStatement(statement) && isRequireCall(statement.expression)) {
59+
continue;
60+
}
61+
const declarations = ts.isVariableStatement(statement) ?
62+
Array.from(statement.declarationList.declarations) :
63+
[];
64+
if (declarations.some(d => !d.initializer || !isRequireCall(d.initializer))) {
65+
return statement.getStart();
66+
}
67+
}
68+
return 0;
69+
}
70+
}

0 commit comments

Comments
 (0)