diff --git a/packages/bazel/src/ng_module.bzl b/packages/bazel/src/ng_module.bzl index fceadb3a7d..68d008a980 100644 --- a/packages/bazel/src/ng_module.bzl +++ b/packages/bazel/src/ng_module.bzl @@ -71,6 +71,7 @@ def _ngc_tsconfig(ctx, files, srcs, **kwargs): "angularCompilerOptions": { "generateCodeForLibraries": False, "allowEmptyCodegenFiles": True, + "enableSummariesforJit": True, # FIXME: wrong place to de-dupe "expectedOut": depset([o.path for o in expected_outs]).to_list() } diff --git a/packages/compiler-cli/integrationtest/tsconfig-xi18n.json b/packages/compiler-cli/integrationtest/tsconfig-xi18n.json index 50af710615..b99e0f28b5 100644 --- a/packages/compiler-cli/integrationtest/tsconfig-xi18n.json +++ b/packages/compiler-cli/integrationtest/tsconfig-xi18n.json @@ -3,7 +3,8 @@ // For TypeScript 1.8, we have to lay out generated files // in the same source directory with your code. "genDir": ".", - "debug": true + "debug": true, + "enableSummariesForJit": true }, "compilerOptions": { diff --git a/packages/compiler-cli/src/transformers/api.ts b/packages/compiler-cli/src/transformers/api.ts index 7829f956f0..54bb786602 100644 --- a/packages/compiler-cli/src/transformers/api.ts +++ b/packages/compiler-cli/src/transformers/api.ts @@ -144,6 +144,12 @@ export interface CompilerOptions extends ts.CompilerOptions { /** generate all possible generated files */ allowEmptyCodegenFiles?: boolean; + + /** + * Whether to generate .ngsummary.ts files that allow to use AOTed artifacts + * in JIT mode. This is off by default. + */ + enableSummariesForJit?: boolean; } export interface CompilerHost extends ts.CompilerHost { diff --git a/packages/compiler-cli/src/transformers/program.ts b/packages/compiler-cli/src/transformers/program.ts index e24c4209ae..54761e238a 100644 --- a/packages/compiler-cli/src/transformers/program.ts +++ b/packages/compiler-cli/src/transformers/program.ts @@ -533,7 +533,7 @@ function getAotCompilerOptions(options: CompilerOptions): AotCompilerOptions { locale: options.i18nInLocale, i18nFormat: options.i18nInFormat || options.i18nOutFormat, translations, missingTranslation, enableLegacyTemplate: options.enableLegacyTemplate, - enableSummariesForJit: true, + enableSummariesForJit: options.enableSummariesForJit, preserveWhitespaces: options.preserveWhitespaces, fullTemplateTypeCheck: options.fullTemplateTypeCheck, allowEmptyCodegenFiles: options.allowEmptyCodegenFiles, diff --git a/packages/compiler-cli/test/ngc_spec.ts b/packages/compiler-cli/test/ngc_spec.ts index 61cd86d2f6..e787aeacf9 100644 --- a/packages/compiler-cli/test/ngc_spec.ts +++ b/packages/compiler-cli/test/ngc_spec.ts @@ -336,18 +336,21 @@ describe('ngc transformer command-line', () => { }); } - function expectAllGeneratedFilesToExist() { + function expectAllGeneratedFilesToExist(enableSummariesForJit = true) { modules.forEach(moduleName => { if (/module|comp/.test(moduleName)) { shouldExist(moduleName + '.ngfactory.js'); shouldExist(moduleName + '.ngfactory.d.ts'); - shouldExist(moduleName + '.ngsummary.js'); - shouldExist(moduleName + '.ngsummary.d.ts'); } else { shouldNotExist(moduleName + '.ngfactory.js'); shouldNotExist(moduleName + '.ngfactory.d.ts'); + } + if (enableSummariesForJit) { shouldExist(moduleName + '.ngsummary.js'); shouldExist(moduleName + '.ngsummary.d.ts'); + } else { + shouldNotExist(moduleName + '.ngsummary.js'); + shouldNotExist(moduleName + '.ngsummary.d.ts'); } shouldExist(moduleName + '.ngsummary.json'); shouldNotExist(moduleName + '.ngfactory.metadata.json'); @@ -359,10 +362,11 @@ describe('ngc transformer command-line', () => { shouldExist('emulated.css.shim.ngstyle.d.ts'); } - it('should emit generated files from sources', () => { + it('should emit generated files from sources with summariesForJit', () => { writeConfig(`{ "extends": "./tsconfig-base.json", "angularCompilerOptions": { + "enableSummariesForJit": true }, "include": ["src/**/*.ts"] }`); @@ -370,7 +374,22 @@ describe('ngc transformer command-line', () => { expect(exitCode).toEqual(0); outDir = path.resolve(basePath, 'built', 'src'); expectJsDtsMetadataJsonToExist(); - expectAllGeneratedFilesToExist(); + expectAllGeneratedFilesToExist(true); + }); + + it('should not emit generated files from sources without summariesForJit', () => { + writeConfig(`{ + "extends": "./tsconfig-base.json", + "angularCompilerOptions": { + "enableSummariesForJit": false + }, + "include": ["src/**/*.ts"] + }`); + const exitCode = main(['-p', path.join(basePath, 'tsconfig.json')], errorSpy); + expect(exitCode).toEqual(0); + outDir = path.resolve(basePath, 'built', 'src'); + expectJsDtsMetadataJsonToExist(); + expectAllGeneratedFilesToExist(false); }); it('should emit generated files from libraries', () => { @@ -408,7 +427,8 @@ describe('ngc transformer command-line', () => { writeConfig(`{ "extends": "./tsconfig-base.json", "angularCompilerOptions": { - "skipTemplateCodegen": false + "skipTemplateCodegen": false, + "enableSummariesForJit": true }, "compilerOptions": { "outDir": "built" @@ -880,7 +900,8 @@ describe('ngc transformer command-line', () => { write('tsconfig-ng.json', `{ "extends": "./tsconfig-base.json", "angularCompilerOptions": { - "generateCodeForLibraries": true + "generateCodeForLibraries": true, + "enableSummariesForJit": true }, "compilerOptions": { "outDir": "." @@ -896,7 +917,8 @@ describe('ngc transformer command-line', () => { write('lib1/tsconfig-lib1.json', `{ "extends": "../tsconfig-base.json", "angularCompilerOptions": { - "generateCodeForLibraries": false + "generateCodeForLibraries": false, + "enableSummariesForJit": true }, "compilerOptions": { "rootDir": ".", @@ -919,7 +941,8 @@ describe('ngc transformer command-line', () => { write('lib2/tsconfig-lib2.json', `{ "extends": "../tsconfig-base.json", "angularCompilerOptions": { - "generateCodeForLibraries": false + "generateCodeForLibraries": false, + "enableSummariesForJit": true }, "compilerOptions": { "rootDir": ".", @@ -941,7 +964,8 @@ describe('ngc transformer command-line', () => { write('app/tsconfig-app.json', `{ "extends": "../tsconfig-base.json", "angularCompilerOptions": { - "generateCodeForLibraries": false + "generateCodeForLibraries": false, + "enableSummariesForJit": true }, "compilerOptions": { "rootDir": ".", diff --git a/packages/compiler-cli/test/transformers/program_spec.ts b/packages/compiler-cli/test/transformers/program_spec.ts index 9db67d4aa7..eca0ae9207 100644 --- a/packages/compiler-cli/test/transformers/program_spec.ts +++ b/packages/compiler-cli/test/transformers/program_spec.ts @@ -300,7 +300,10 @@ describe('ng program', () => { export * from './main'; `, }); - const options = testSupport.createCompilerOptions({allowEmptyCodegenFiles: true}); + const options = testSupport.createCompilerOptions({ + allowEmptyCodegenFiles: true, + enableSummariesForJit: true, + }); const host = ng.createCompilerHost({options}); const written = new Map < string, { original: ts.SourceFile[]|undefined; @@ -384,11 +387,11 @@ describe('ng program', () => { testSupport.shouldExist('built/main.ngfactory.js'); testSupport.shouldExist('built/main.ngfactory.d.ts'); testSupport.shouldExist('built/main.ngsummary.json'); - testSupport.shouldNotExist('build/node_modules/lib/index.js'); - testSupport.shouldNotExist('build/node_modules/lib/index.d.ts'); - testSupport.shouldNotExist('build/node_modules/lib/index.ngfactory.js'); - testSupport.shouldNotExist('build/node_modules/lib/index.ngfactory.d.ts'); - testSupport.shouldNotExist('build/node_modules/lib/index.ngsummary.json'); + testSupport.shouldNotExist('built/node_modules/lib/index.js'); + testSupport.shouldNotExist('built/node_modules/lib/index.d.ts'); + testSupport.shouldNotExist('built/node_modules/lib/index.ngfactory.js'); + testSupport.shouldNotExist('built/node_modules/lib/index.ngfactory.d.ts'); + testSupport.shouldNotExist('built/node_modules/lib/index.ngsummary.json'); }); describe('createSrcToOutPathMapper', () => { diff --git a/packages/compiler/src/aot/compiler.ts b/packages/compiler/src/aot/compiler.ts index 2f1f7017cd..4da4cc9208 100644 --- a/packages/compiler/src/aot/compiler.ts +++ b/packages/compiler/src/aot/compiler.ts @@ -98,7 +98,9 @@ export class AotCompiler { if (this._options.allowEmptyCodegenFiles || file.directives.length || file.pipes.length || file.injectables.length || file.ngModules.length || file.exportsNonSourceFiles) { genFileNames.push(ngfactoryFilePath(file.fileName, true)); - genFileNames.push(summaryForJitFileName(file.fileName, true)); + if (this._options.enableSummariesForJit) { + genFileNames.push(summaryForJitFileName(file.fileName, true)); + } } const fileSuffix = splitTypescriptSuffix(file.fileName, true)[1]; file.directives.forEach((dirSymbol) => { @@ -376,7 +378,9 @@ export class AotCompiler { metadata: this._metadataResolver.getInjectableSummary(ref) !.type })) ]; - const forJitOutputCtx = this._createOutputContext(summaryForJitFileName(srcFileName, true)); + const forJitOutputCtx = this._options.enableSummariesForJit ? + this._createOutputContext(summaryForJitFileName(srcFileName, true)) : + null; const {json, exportAs} = serializeSummaries( srcFileName, forJitOutputCtx, this._summaryResolver, this._symbolResolver, symbolSummaries, typeData); @@ -387,11 +391,11 @@ export class AotCompiler { ])); }); const summaryJson = new GeneratedFile(srcFileName, summaryFileName(srcFileName), json); - if (this._options.enableSummariesForJit) { - return [summaryJson, this._codegenSourceModule(srcFileName, forJitOutputCtx)]; + const result = [summaryJson]; + if (forJitOutputCtx) { + result.push(this._codegenSourceModule(srcFileName, forJitOutputCtx)); } - - return [summaryJson]; + return result; } private _compileModule(outputCtx: OutputContext, ngModule: CompileNgModuleMetadata): void { diff --git a/packages/compiler/src/aot/compiler_options.ts b/packages/compiler/src/aot/compiler_options.ts index 1149a4cddf..b7bd69d320 100644 --- a/packages/compiler/src/aot/compiler_options.ts +++ b/packages/compiler/src/aot/compiler_options.ts @@ -14,7 +14,6 @@ export interface AotCompilerOptions { translations?: string; missingTranslation?: MissingTranslationStrategy; enableLegacyTemplate?: boolean; - /** TODO(tbosch): remove this flag as it is always on in the new ngc */ enableSummariesForJit?: boolean; preserveWhitespaces?: boolean; fullTemplateTypeCheck?: boolean; diff --git a/packages/compiler/src/aot/summary_serializer.ts b/packages/compiler/src/aot/summary_serializer.ts index 43de1da9bf..765b06d38d 100644 --- a/packages/compiler/src/aot/summary_serializer.ts +++ b/packages/compiler/src/aot/summary_serializer.ts @@ -15,14 +15,14 @@ import {ResolvedStaticSymbol, StaticSymbolResolver} from './static_symbol_resolv import {summaryForJitFileName, summaryForJitName} from './util'; export function serializeSummaries( - srcFileName: string, forJitCtx: OutputContext, summaryResolver: SummaryResolver, - symbolResolver: StaticSymbolResolver, symbols: ResolvedStaticSymbol[], types: { + srcFileName: string, forJitCtx: OutputContext | null, + summaryResolver: SummaryResolver, symbolResolver: StaticSymbolResolver, + symbols: ResolvedStaticSymbol[], types: { summary: CompileTypeSummary, metadata: CompileNgModuleMetadata | CompileDirectiveMetadata | CompilePipeMetadata | CompileTypeMetadata }[]): {json: string, exportAs: {symbol: StaticSymbol, exportAs: string}[]} { const toJsonSerializer = new ToJsonSerializer(symbolResolver, summaryResolver, srcFileName); - const forJitSerializer = new ForJitSerializer(forJitCtx, symbolResolver); // for symbols, we use everything except for the class metadata itself // (we keep the statics though), as the class metadata is contained in the @@ -33,18 +33,20 @@ export function serializeSummaries( // Add type summaries. types.forEach(({summary, metadata}) => { - forJitSerializer.addSourceType(summary, metadata); toJsonSerializer.addSummary( {symbol: summary.type.reference, metadata: undefined, type: summary}); }); - toJsonSerializer.unprocessedSymbolSummariesBySymbol.forEach((summary) => { - if (summaryResolver.isLibraryFile(summary.symbol.filePath) && summary.type) { - forJitSerializer.addLibType(summary.type); - } - }); - const {json, exportAs} = toJsonSerializer.serialize(); - forJitSerializer.serialize(exportAs); + if (forJitCtx) { + const forJitSerializer = new ForJitSerializer(forJitCtx, symbolResolver); + types.forEach(({summary, metadata}) => { forJitSerializer.addSourceType(summary, metadata); }); + toJsonSerializer.unprocessedSymbolSummariesBySymbol.forEach((summary) => { + if (summaryResolver.isLibraryFile(summary.symbol.filePath) && summary.type) { + forJitSerializer.addLibType(summary.type); + } + }); + forJitSerializer.serialize(exportAs); + } return {json, exportAs}; }