When compiling libraries, this feature extracts the minimal information from the directives/pipes/modules of the library into `.ngsummary.json` files, so that applications that use this library only need to be recompiled if one of the summary files change, but not on every change of the libraries (e.g. one of the templates). Only works if individual codegen for libraries is enabled, see the `generateCodeForLibraries: false` option. Closes #12787
101 lines
3.5 KiB
JavaScript
101 lines
3.5 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* @license
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
/* tslint:disable:no-console */
|
|
|
|
// Must be imported first, because angular2 decorators throws on load.
|
|
import 'reflect-metadata';
|
|
|
|
import * as path from 'path';
|
|
import * as ts from 'typescript';
|
|
import * as assert from 'assert';
|
|
import {tsc} from '@angular/tsc-wrapped/src/tsc';
|
|
import {AngularCompilerOptions, CodeGenerator, CompilerHostContext, NodeCompilerHostContext} from '@angular/compiler-cli';
|
|
|
|
/**
|
|
* Main method.
|
|
* Standalone program that executes the real codegen and tests that
|
|
* ngsummary.json files are used for libraries.
|
|
*/
|
|
function main() {
|
|
console.log(`testing usage of ngsummary.json files in libraries...`);
|
|
const basePath = path.resolve(__dirname, '..');
|
|
const project = path.resolve(basePath, 'tsconfig-build.json');
|
|
const readFiles: string[] = [];
|
|
|
|
class AssertingHostContext extends NodeCompilerHostContext {
|
|
readFile(fileName: string): string {
|
|
readFiles.push(path.relative(basePath, fileName));
|
|
return super.readFile(fileName);
|
|
}
|
|
readResource(s: string): Promise<string> {
|
|
readFiles.push(path.relative(basePath, s));
|
|
return super.readResource(s);
|
|
}
|
|
}
|
|
|
|
const config = tsc.readConfiguration(project, basePath);
|
|
config.ngOptions.basePath = basePath;
|
|
// This flag tells ngc do not recompile libraries.
|
|
config.ngOptions.generateCodeForLibraries = false;
|
|
|
|
console.log(`>>> running codegen for ${project}`);
|
|
codegen(config, (host) => new AssertingHostContext())
|
|
.then((exitCode: any) => {
|
|
console.log(`>>> codegen done, asserting read files`);
|
|
assertSomeFileMatch(readFiles, /^node_modules\/.*\.ngsummary\.json$/);
|
|
assertNoFileMatch(readFiles, /^node_modules\/.*\.html$/);
|
|
assertNoFileMatch(readFiles, /^node_modules\/.*\.css$/);
|
|
|
|
assertNoFileMatch(readFiles, /^src\/.*\.ngsummary\.json$/);
|
|
assertSomeFileMatch(readFiles, /^src\/.*\.html$/);
|
|
assertSomeFileMatch(readFiles, /^src\/.*\.css$/);
|
|
console.log(`done, no errors.`);
|
|
process.exit(exitCode);
|
|
})
|
|
.catch((e: any) => {
|
|
console.error(e.stack);
|
|
console.error('Compilation failed');
|
|
process.exit(1);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Simple adaption of tsc-wrapped main to just run codegen with a CompilerHostContext
|
|
*/
|
|
function codegen(
|
|
config: {parsed: ts.ParsedCommandLine, ngOptions: AngularCompilerOptions},
|
|
hostContextFactory: (host: ts.CompilerHost) => CompilerHostContext) {
|
|
const host = ts.createCompilerHost(config.parsed.options, true);
|
|
|
|
// HACK: patch the realpath to solve symlink issue here:
|
|
// https://github.com/Microsoft/TypeScript/issues/9552
|
|
// todo(misko): remove once facade symlinks are removed
|
|
host.realpath = (path) => path;
|
|
|
|
const program = ts.createProgram(config.parsed.fileNames, config.parsed.options, host);
|
|
|
|
return CodeGenerator.create(config.ngOptions, {
|
|
} as any, program, host, hostContextFactory(host)).codegen();
|
|
}
|
|
|
|
function assertSomeFileMatch(fileNames: string[], pattern: RegExp) {
|
|
assert(
|
|
fileNames.some(fileName => pattern.test(fileName)),
|
|
`Expected some read files match ${pattern}`);
|
|
}
|
|
|
|
function assertNoFileMatch(fileNames: string[], pattern: RegExp) {
|
|
const matches = fileNames.filter(fileName => pattern.test(fileName));
|
|
assert(
|
|
matches.length === 0,
|
|
`Expected no read files match ${pattern}, but found: \n${matches.join('\n')}`);
|
|
}
|
|
|
|
main();
|