From 9496a0791a51dc6a146238e581717b6c373e77d2 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Tue, 20 Aug 2019 11:07:00 +0100 Subject: [PATCH 1/8] test: fix external source map test for Ivy --- .../browser/vendor-source-map_spec_large.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/angular_devkit/build_angular/test/browser/vendor-source-map_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/vendor-source-map_spec_large.ts index 8ba110e5354f..7d479a525b40 100644 --- a/packages/angular_devkit/build_angular/test/browser/vendor-source-map_spec_large.ts +++ b/packages/angular_devkit/build_angular/test/browser/vendor-source-map_spec_large.ts @@ -9,8 +9,7 @@ import { Architect } from '@angular-devkit/architect'; import * as path from 'path'; import { browserBuild, createArchitect, host, veEnabled } from '../utils'; -// DISABLED_FOR_IVY These should pass but are currently not supported -(veEnabled ? describe : xdescribe)('Browser Builder external source map', () => { +describe('Browser Builder external source map', () => { const target = { project: 'app', target: 'build' }; let architect: Architect; @@ -30,8 +29,9 @@ import { browserBuild, createArchitect, host, veEnabled } from '../utils'; }; const { files } = await browserBuild(architect, host, target, overrides); - const sourcePath = JSON.parse(await files['vendor.js.map']).sources[0]; - expect(path.extname(sourcePath)).toBe('.ts', `${sourcePath} extention should be '.ts'`); + const sourcePaths: string[] = JSON.parse(await files['vendor.js.map']).sources; + const hasTsSourcePaths = sourcePaths.some(p => path.extname(p) == '.ts'); + expect(hasTsSourcePaths).toBe(true, `vendor.js.map should have '.ts' extentions`); }); it(`works when using deprecated 'vendorSourceMap'`, async () => { @@ -44,8 +44,9 @@ import { browserBuild, createArchitect, host, veEnabled } from '../utils'; }; const { files } = await browserBuild(architect, host, target, overrides); - const sourcePath = JSON.parse(await files['vendor.js.map']).sources[0]; - expect(path.extname(sourcePath)).toBe('.ts', `${sourcePath} extention should be '.ts'`); + const sourcePaths: string[] = JSON.parse(await files['vendor.js.map']).sources; + const hasTsSourcePaths = sourcePaths.some(p => path.extname(p) == '.ts'); + expect(hasTsSourcePaths).toBe(true, `vendor.js.map should have '.ts' extentions`); }); it('does not map sourcemaps from external library when disabled', async () => { @@ -58,7 +59,8 @@ import { browserBuild, createArchitect, host, veEnabled } from '../utils'; }; const { files } = await browserBuild(architect, host, target, overrides); - const sourcePath = JSON.parse(await files['vendor.js.map']).sources[0]; - expect(path.extname(sourcePath)).toBe('.js', `${sourcePath} extention should be '.ts'`); + const sourcePaths: string[] = JSON.parse(await files['vendor.js.map']).sources; + const hasTsSourcePaths = sourcePaths.some(p => path.extname(p) == '.ts'); + expect(hasTsSourcePaths).toBe(false, `vendor.js.map not should have '.ts' extentions`); }); }); From 4c7477b61a78760ef5b6d15a1abd2c07e0821b26 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Tue, 20 Aug 2019 13:29:44 +0100 Subject: [PATCH 2/8] test: re-enable lazy route error tests for Ivy --- .../test/browser/lazy-module_spec_large.ts | 98 ++++++++++--------- 1 file changed, 54 insertions(+), 44 deletions(-) diff --git a/packages/angular_devkit/build_angular/test/browser/lazy-module_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/lazy-module_spec_large.ts index bcd5aa4b5fc4..2cc708bbd577 100644 --- a/packages/angular_devkit/build_angular/test/browser/lazy-module_spec_large.ts +++ b/packages/angular_devkit/build_angular/test/browser/lazy-module_spec_large.ts @@ -45,6 +45,14 @@ describe('Browser Builder lazy modules', () => { ); } + function hasMissingModuleError(logger: TestLogger) { + // TS type error when using import(). + return logger.includes('Cannot find module') || + // Webpack error when using import() on a rebuild. + // There is no TS error because the type checker is forked on rebuilds. + logger.includes('Module not found'); + } + const cases: [string, Record][] = [ ['string', lazyModuleStringImport], ['function', lazyModuleFnImport], @@ -63,50 +71,6 @@ describe('Browser Builder lazy modules', () => { expect('lazy-lazy-module.js' in files).toBe(true); }); - it('should show error when lazy route is invalid on watch mode AOT', async () => { - if (!veEnabled && name === 'string') { - pending('Does not apply to Ivy.'); - - return; - } - - // DISABLED_FOR_IVY - These should pass but are currently not supported - if (!veEnabled) { - pending('Broken in Ivy'); - - return; - } - - host.writeMultipleFiles(lazyModuleFiles); - host.writeMultipleFiles(imports); - host.replaceInFile('src/app/app.module.ts', 'lazy.module', 'invalid.module'); - - const logger = new TestLogger('rebuild-lazy-errors'); - const overrides = { watch: true, aot: true }; - const run = await architect.scheduleTarget(target, overrides, { logger }); - await run.output - .pipe( - timeout(15000), - tap(buildEvent => expect(buildEvent.success).toBe(false)), - tap(() => { - // Webpack error when using loadchildren string syntax. - const hasMissingModuleError = - logger.includes('Could not resolve module') || - // TS type error when using import(). - logger.includes('Cannot find module') || - // Webpack error when using import() on a rebuild. - // There is no TS error because the type checker is forked on rebuilds. - logger.includes('Module not found'); - expect(hasMissingModuleError).toBe(true, 'Should show missing module error'); - logger.clear(); - host.appendToFile('src/main.ts', ' '); - }), - take(2), - ) - .toPromise(); - await run.stop(); - }); - it('supports lazy bundle for lazy routes with AOT', async () => { host.writeMultipleFiles(lazyModuleFiles); host.writeMultipleFiles(imports); @@ -124,6 +88,52 @@ describe('Browser Builder lazy modules', () => { }); } + // Errors for missing lazy routes are only supported with function syntax. + // `ngProgram.listLazyRoutes` will ignore invalid lazy routes in the route map. + describe(`Load children errors with function syntax`, () => { + it('should show error when lazy route is invalid', async () => { + host.writeMultipleFiles(lazyModuleFiles); + host.writeMultipleFiles(lazyModuleFnImport); + host.replaceInFile('src/app/app.module.ts', 'lazy.module', 'invalid.module'); + + const logger = new TestLogger('build-lazy-errors'); + const run = await architect.scheduleTarget(target, {}, { logger }); + const output = await run.result; + expect(output.success).toBe(false); + expect(hasMissingModuleError(logger)).toBe(true, 'Should show missing module error'); + }); + + it('should show error when lazy route is invalid on watch mode AOT', async () => { + host.writeMultipleFiles(lazyModuleFiles); + host.writeMultipleFiles(lazyModuleFnImport); + + let buildNumber = 0; + const logger = new TestLogger('rebuild-lazy-errors'); + const overrides = { watch: true, aot: true }; + const run = await architect.scheduleTarget(target, overrides, { logger }); + await run.output + .pipe( + timeout(15000), + tap(buildEvent => { + buildNumber++; + switch (buildNumber) { + case 1: + expect(buildEvent.success).toBe(true); + host.replaceInFile('src/app/app.module.ts', 'lazy.module', 'invalid.module'); + logger.clear(); + break; + case 2: + expect(buildEvent.success).toBe(false); + break; + } + }), + take(2), + ) + .toPromise(); + await run.stop(); + }); + }); + it(`supports lazy bundle for import() calls`, async () => { host.writeMultipleFiles({ 'src/lazy-module.ts': 'export const value = 42;', From 9f2458d88f4c77fb5b133ec7f5e794bf8eb737d4 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Tue, 20 Aug 2019 13:43:07 +0100 Subject: [PATCH 3/8] fix(@ngtools/webpack): don't warn on extra files in errored compilations --- packages/ngtools/webpack/src/angular_compiler_plugin.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ngtools/webpack/src/angular_compiler_plugin.ts b/packages/ngtools/webpack/src/angular_compiler_plugin.ts index d4accb00b5cc..383aa9abae5c 100644 --- a/packages/ngtools/webpack/src/angular_compiler_plugin.ts +++ b/packages/ngtools/webpack/src/angular_compiler_plugin.ts @@ -596,7 +596,8 @@ export class AngularCompilerPlugin { // Only do the unused TS files checks when under Ivy // since previously we did include unused files in the compilation // See: https://github.com/angular/angular-cli/pull/15030 - if (!this._compilerOptions.enableIvy) { + // Don't do checks for compilations with errors, since that can result in a partial compilation. + if (!this._compilerOptions.enableIvy || compilation.errors.length > 0) { return; } From c633026738cdd0c3eda3490baf2a749829e1d67b Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Tue, 20 Aug 2019 15:05:13 +0100 Subject: [PATCH 4/8] test: add issue for disabled Ivy AOT rebuild test --- .../build_angular/test/browser/rebuild_spec_large.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/angular_devkit/build_angular/test/browser/rebuild_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/rebuild_spec_large.ts index 950766aa140c..d1abf2efbc20 100644 --- a/packages/angular_devkit/build_angular/test/browser/rebuild_spec_large.ts +++ b/packages/angular_devkit/build_angular/test/browser/rebuild_spec_large.ts @@ -268,7 +268,7 @@ describe('Browser Builder rebuilds', () => { it('rebuilds after errors in AOT', async () => { // DISABLED_FOR_IVY - These should pass but are currently not supported if (!veEnabled) { - pending('Broken in Ivy'); + pending('Broken in Ivy: https://github.com/angular/angular/issues/32214'); return; } From 6311334ce6d58c7def650a69d59332b9890c40db Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Tue, 20 Aug 2019 15:14:06 +0100 Subject: [PATCH 5/8] test: fix basic aot e2e to run with Ivy --- tests/legacy-cli/e2e/tests/basic/aot.ts | 17 +++++++++++++---- tests/legacy-cli/e2e_runner.ts | 2 -- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/legacy-cli/e2e/tests/basic/aot.ts b/tests/legacy-cli/e2e/tests/basic/aot.ts index 33c2c08ec462..a4dd67d5018d 100644 --- a/tests/legacy-cli/e2e/tests/basic/aot.ts +++ b/tests/legacy-cli/e2e/tests/basic/aot.ts @@ -1,10 +1,19 @@ +import { getGlobalVariable } from '../../utils/env'; import { expectFileToMatch } from '../../utils/fs'; import { ng } from '../../utils/process'; export default async function () { await ng('build', '--aot=true'); - await expectFileToMatch('dist/test-project/main-es5.js', - /platformBrowser.*bootstrapModuleFactory.*AppModuleNgFactory/); - await expectFileToMatch('dist/test-project/main-es2015.js', - /platformBrowser.*bootstrapModuleFactory.*AppModuleNgFactory/); + + if (getGlobalVariable('argv')['ve']) { + await expectFileToMatch('dist/test-project/main-es5.js', + /platformBrowser.*bootstrapModuleFactory.*AppModuleNgFactory/); + await expectFileToMatch('dist/test-project/main-es2015.js', + /platformBrowser.*bootstrapModuleFactory.*AppModuleNgFactory/); + } else { + await expectFileToMatch('dist/test-project/main-es5.js', + /platformBrowser.*bootstrapModule.*AppModule/); + await expectFileToMatch('dist/test-project/main-es2015.js', + /platformBrowser.*bootstrapModule.*AppModule/); + } } diff --git a/tests/legacy-cli/e2e_runner.ts b/tests/legacy-cli/e2e_runner.ts index de1d01624901..d498102e31b7 100644 --- a/tests/legacy-cli/e2e_runner.ts +++ b/tests/legacy-cli/e2e_runner.ts @@ -99,8 +99,6 @@ if (!argv.ve) { // - The test itself is not applicable to Ivy // As we transition into using Ivy as the default this list should be reassessed. allTests = allTests - // The basic AOT check is different with Ivy and being checked in /experimental/ivy.ts. - .filter(name => !name.endsWith('tests/basic/aot.ts')) // Ivy doesn't support i18n externally at the moment. .filter(name => !name.includes('tests/i18n/')) .filter(name => !name.endsWith('tests/build/aot/aot-i18n.ts')) From 40aeefc1926f7ccd10eda4abdef6e3e01c1a7335 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Tue, 20 Aug 2019 15:16:38 +0100 Subject: [PATCH 6/8] test: move dynamic import exclusion to test --- tests/legacy-cli/e2e/tests/build/dynamic-import.ts | 6 ++++++ tests/legacy-cli/e2e_runner.ts | 2 -- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/legacy-cli/e2e/tests/build/dynamic-import.ts b/tests/legacy-cli/e2e/tests/build/dynamic-import.ts index ff0d29a5cc9c..cfa72e03e0ed 100644 --- a/tests/legacy-cli/e2e/tests/build/dynamic-import.ts +++ b/tests/legacy-cli/e2e/tests/build/dynamic-import.ts @@ -1,10 +1,16 @@ import * as fs from 'fs'; +import { getGlobalVariable } from '../../utils/env'; import { writeFile } from '../../utils/fs'; import { ng } from '../../utils/process'; import { updateJsonFile } from '../../utils/project'; export default async function() { + if (!(getGlobalVariable('argv')['ve'])) { + // Only applicable to VE. Does not apply to Ivy. + return; + } + // Add a lazy module await ng('generate', 'module', 'lazy'); await updateJsonFile('angular.json', workspaceJson => { diff --git a/tests/legacy-cli/e2e_runner.ts b/tests/legacy-cli/e2e_runner.ts index d498102e31b7..fdb202b3e6db 100644 --- a/tests/legacy-cli/e2e_runner.ts +++ b/tests/legacy-cli/e2e_runner.ts @@ -102,8 +102,6 @@ if (!argv.ve) { // Ivy doesn't support i18n externally at the moment. .filter(name => !name.includes('tests/i18n/')) .filter(name => !name.endsWith('tests/build/aot/aot-i18n.ts')) - // The additional lazy modules array does not work with Ivy because it's not needed. - .filter(name => !name.endsWith('tests/build/dynamic-import.ts')) // We don't have a platform-server usage story yet for Ivy. // It's contingent on lazy loading and factory shim considerations that are still being // discussed. From d4bb898f28231d8699e5e3d3d5e0551630ff453c Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Tue, 20 Aug 2019 17:25:33 +0100 Subject: [PATCH 7/8] test: update server builder specs --- .../test/server/base_spec_large.ts | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/angular_devkit/build_angular/test/server/base_spec_large.ts b/packages/angular_devkit/build_angular/test/server/base_spec_large.ts index 2b6e903d6519..1bbdab21716e 100644 --- a/packages/angular_devkit/build_angular/test/server/base_spec_large.ts +++ b/packages/angular_devkit/build_angular/test/server/base_spec_large.ts @@ -13,8 +13,7 @@ import { BrowserBuilderOutput } from '../../src/browser'; import { createArchitect, host, veEnabled } from '../utils'; -// DISABLED_FOR_IVY These should pass but are currently not supported -(veEnabled ? describe : xdescribe)('Server Builder', () => { +describe('Server Builder', () => { const target = { project: 'app', target: 'server' }; let architect: Architect; @@ -33,7 +32,12 @@ import { createArchitect, host, veEnabled } from '../utils'; const fileName = join(outputPath, 'main.js'); const content = virtualFs.fileBufferToString(host.scopedSync().read(normalize(fileName))); - expect(content).toMatch(/AppServerModuleNgFactory/); + + if (veEnabled) { + expect(content).toMatch(/AppServerModuleNgFactory/); + } else { + expect(content).toMatch(/AppServerModule\.ngModuleDef/); + } await run.stop(); }); @@ -68,16 +72,10 @@ import { createArchitect, host, veEnabled } from '../utils'; it('supports sourcemaps', async () => { const overrides = { sourceMap: true }; - const run = await architect.scheduleTarget(target, overrides); const output = await run.result as BrowserBuilderOutput; expect(output.success).toBe(true); - - const fileName = join(outputPath, 'main.js'); - const content = virtualFs.fileBufferToString(host.scopedSync().read(normalize(fileName))); - expect(content).toMatch(/AppServerModuleNgFactory/); expect(host.scopedSync().exists(join(outputPath, 'main.js.map'))).toBeTruthy(); - await run.stop(); }); @@ -144,7 +142,11 @@ import { createArchitect, host, veEnabled } from '../utils'; const fileName = join(outputPath, 'main.js'); const content = virtualFs.fileBufferToString(host.scopedSync().read(normalize(fileName))); - expect(content).toMatch(/AppServerModuleNgFactory/); + if (veEnabled) { + expect(content).toMatch(/AppServerModuleNgFactory/); + } else { + expect(content).toMatch(/AppServerModule\.ngModuleDef/); + } }), take(1), ).toPromise(); From fa50eb8556213cf93e131b317c222be25dd1691f Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Tue, 20 Aug 2019 17:28:22 +0100 Subject: [PATCH 8/8] test: add issue for broken app-shell test --- .../build_angular/src/app-shell/index.ts | 61 +++++++++---------- .../test/app-shell/app-shell_spec_large.ts | 1 + tests/legacy-cli/e2e_runner.ts | 1 + 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/app-shell/index.ts b/packages/angular_devkit/build_angular/src/app-shell/index.ts index d71db512caa2..75fb4d9c18be 100644 --- a/packages/angular_devkit/build_angular/src/app-shell/index.ts +++ b/packages/angular_devkit/build_angular/src/app-shell/index.ts @@ -15,13 +15,13 @@ import { JsonObject, experimental, join, normalize, resolve, schema } from '@ang import { NodeJsSyncHost } from '@angular-devkit/core/node'; import * as fs from 'fs'; import * as path from 'path'; +import { readTsconfig } from '../angular-cli-files/utilities/read-tsconfig'; import { augmentAppWithServiceWorker } from '../angular-cli-files/utilities/service-worker'; import { BrowserBuilderOutput } from '../browser'; import { Schema as BrowserBuilderSchema } from '../browser/schema'; import { ServerBuilderOutput } from '../server'; import { Schema as BuildWebpackAppShellSchema } from './schema'; - async function _renderUniversal( options: BuildWebpackAppShellSchema, context: BuilderContext, @@ -31,40 +31,48 @@ async function _renderUniversal( const browserIndexOutputPath = path.join(browserResult.outputPath || '', 'index.html'); const indexHtml = fs.readFileSync(browserIndexOutputPath, 'utf8'); const serverBundlePath = await _getServerModuleBundlePath(options, context, serverResult); - const root = context.workspaceRoot; + // Get browser target options. + const browserTarget = targetFromTargetString(options.browserTarget); + const rawBrowserOptions = await context.getTargetOptions(browserTarget); + const browserBuilderName = await context.getBuilderNameForTarget(browserTarget); + const browserOptions = await context.validateOptions( + rawBrowserOptions, + browserBuilderName, + ); + + // Determine if browser app was compiled using Ivy. + const { options: compilerOptions } = readTsconfig(browserOptions.tsConfig, context.workspaceRoot); + const ivy = compilerOptions.enableIvy; + // Initialize zone.js const zonePackage = require.resolve('zone.js', { paths: [root] }); await import(zonePackage); // Load platform server module renderer const platformServerPackage = require.resolve('@angular/platform-server', { paths: [root] }); - const renderModuleFactory = await import(platformServerPackage) + const renderOpts = { + document: indexHtml, + url: options.route, + }; + + // Render app to HTML using Ivy or VE + const html = await import(platformServerPackage) // tslint:disable-next-line:no-implicit-dependencies - .then((m: typeof import('@angular/platform-server')) => m.renderModuleFactory); + .then((m: typeof import('@angular/platform-server')) => + ivy + ? m.renderModule(require(serverBundlePath).AppServerModule, renderOpts) + : m.renderModuleFactory(require(serverBundlePath).AppServerModuleNgFactory, renderOpts), + ); - const AppServerModuleNgFactory = require(serverBundlePath).AppServerModuleNgFactory; + // Overwrite the client index file. const outputIndexPath = options.outputIndexPath ? path.join(root, options.outputIndexPath) : browserIndexOutputPath; - // Render to HTML and overwrite the client index file. - const html = await renderModuleFactory(AppServerModuleNgFactory, { - document: indexHtml, - url: options.route, - }); - fs.writeFileSync(outputIndexPath, html); - const browserTarget = targetFromTargetString(options.browserTarget); - const rawBrowserOptions = await context.getTargetOptions(browserTarget); - const browserBuilderName = await context.getBuilderNameForTarget(browserTarget); - const browserOptions = await context.validateOptions( - rawBrowserOptions, - browserBuilderName, - ); - if (browserOptions.serviceWorker) { const host = new NodeJsSyncHost(); // Create workspace. @@ -81,10 +89,7 @@ async function _renderUniversal( if (!projectName) { throw new Error('Must either have a target from the context or a default project.'); } - const projectRoot = resolve( - workspace.root, - normalize(workspace.getProject(projectName).root), - ); + const projectRoot = resolve(workspace.root, normalize(workspace.getProject(projectName).root)); await augmentAppWithServiceWorker( host, @@ -99,7 +104,6 @@ async function _renderUniversal( return browserResult; } - async function _getServerModuleBundlePath( options: BuildWebpackAppShellSchema, context: BuilderContext, @@ -121,7 +125,6 @@ async function _getServerModuleBundlePath( } } - async function _appShellBuilder( options: JsonObject & BuildWebpackAppShellSchema, context: BuilderContext, @@ -139,7 +142,7 @@ async function _appShellBuilder( try { const [browserResult, serverResult] = await Promise.all([ - browserTargetRun.result as {} as BrowserBuilderOutput, + (browserTargetRun.result as {}) as BrowserBuilderOutput, serverTargetRun.result, ]); @@ -154,12 +157,8 @@ async function _appShellBuilder( return { success: false, error: err.message }; } finally { // Just be good citizens and stop those jobs. - await Promise.all([ - browserTargetRun.stop(), - serverTargetRun.stop(), - ]); + await Promise.all([browserTargetRun.stop(), serverTargetRun.stop()]); } } - export default createBuilder(_appShellBuilder); diff --git a/packages/angular_devkit/build_angular/test/app-shell/app-shell_spec_large.ts b/packages/angular_devkit/build_angular/test/app-shell/app-shell_spec_large.ts index 2dde22816f1e..8213aa8f1af0 100644 --- a/packages/angular_devkit/build_angular/test/app-shell/app-shell_spec_large.ts +++ b/packages/angular_devkit/build_angular/test/app-shell/app-shell_spec_large.ts @@ -13,6 +13,7 @@ import { createArchitect, host, veEnabled } from '../utils'; // DISABLED_FOR_IVY These should pass but are currently not supported +// See https://github.com/angular/angular-cli/issues/15383 for details. (veEnabled ? describe : xdescribe)('AppShell Builder', () => { const target = { project: 'app', target: 'app-shell' }; let architect: Architect; diff --git a/tests/legacy-cli/e2e_runner.ts b/tests/legacy-cli/e2e_runner.ts index fdb202b3e6db..b828747018ec 100644 --- a/tests/legacy-cli/e2e_runner.ts +++ b/tests/legacy-cli/e2e_runner.ts @@ -105,6 +105,7 @@ if (!argv.ve) { // We don't have a platform-server usage story yet for Ivy. // It's contingent on lazy loading and factory shim considerations that are still being // discussed. + // Broken currently https://github.com/angular/angular-cli/issues/15383 .filter(name => !name.endsWith('tests/build/platform-server.ts')) .filter(name => !name.endsWith('tests/build/build-app-shell.ts')) .filter(name => !name.endsWith('tests/build/build-app-shell-with-schematic.ts'));