diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index a02b7da67ec7..08bdb6892f5f 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -87,6 +87,7 @@ "zone.js": "^0.9.1" }, "peerDependencies": { + "@angular/compiler-cli": ">=8.0.0-beta.0 < 9.0.0", "typescript": ">=3.1 < 3.5" } } diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/models/build-options.ts b/packages/angular_devkit/build_angular/src/angular-cli-files/models/build-options.ts index 46de94ad5e06..c35b6a1cad73 100644 --- a/packages/angular_devkit/build_angular/src/angular-cli-files/models/build-options.ts +++ b/packages/angular_devkit/build_angular/src/angular-cli-files/models/build-options.ts @@ -9,7 +9,8 @@ // TODO: cleanup this file, it's copied as is from Angular CLI. import { logging } from '@angular-devkit/core'; -import { ParsedCommandLine, ScriptTarget } from 'typescript'; +import { ParsedConfiguration } from '@angular/compiler-cli'; +import { ScriptTarget } from 'typescript'; import { AssetPatternClass, Budget, @@ -93,7 +94,7 @@ export interface WebpackConfigOptions { projectRoot: string; sourceRoot?: string; buildOptions: T; - tsConfig: ParsedCommandLine; + tsConfig: ParsedConfiguration; tsConfigPath: string; supportES2015: boolean; } diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/utilities/read-tsconfig.ts b/packages/angular_devkit/build_angular/src/angular-cli-files/utilities/read-tsconfig.ts index e4c607d7d294..9d58349af889 100644 --- a/packages/angular_devkit/build_angular/src/angular-cli-files/utilities/read-tsconfig.ts +++ b/packages/angular_devkit/build_angular/src/angular-cli-files/utilities/read-tsconfig.ts @@ -5,24 +5,30 @@ * 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 -// TODO: cleanup this file, it's copied as is from Angular CLI. -import * as ts from 'typescript'; + +import { ParsedConfiguration } from '@angular/compiler-cli'; import * as path from 'path'; -import { requireProjectModule } from '../utilities/require-project-module'; -export function readTsconfig(tsconfigPath: string) { - const projectTs = requireProjectModule(path.dirname(tsconfigPath), 'typescript') as typeof ts; - const configResult = projectTs.readConfigFile(tsconfigPath, projectTs.sys.readFile); - const tsConfig = projectTs.parseJsonConfigFileContent(configResult.config, projectTs.sys, - path.dirname(tsconfigPath), undefined, tsconfigPath); +/** + * Reads and parses a given TsConfig file. + * + * @param tsconfigPath - An absolute or relative path from 'workspaceRoot' of the tsconfig file. + * @param workspaceRoot - workspaceRoot root location when provided + * it will resolve 'tsconfigPath' from this path. + */ +export function readTsconfig(tsconfigPath: string, workspaceRoot?: string): ParsedConfiguration { + const tsConfigFullPath = workspaceRoot + ? path.resolve(workspaceRoot, tsconfigPath) + : tsconfigPath; + + // We use 'ng' instead of 'ts' here because 'ts' is not aware of 'angularCompilerOptions' + // and will not merged them if they are at un upper level tsconfig file when using `extends`. + const ng: typeof import('@angular/compiler-cli') = require('@angular/compiler-cli'); - if (tsConfig.errors.length > 0) { - throw new Error( - `Errors found while reading ${tsconfigPath}:\n ${ - tsConfig.errors.map(e => e.messageText).join('\n ') - }` - ) + const configResult = ng.readConfiguration(tsConfigFullPath); + if (configResult.errors && configResult.errors.length) { + throw new Error(ng.formatDiagnostics(configResult.errors)); } - return tsConfig; + + return configResult; } diff --git a/packages/angular_devkit/build_angular/src/browser/index.ts b/packages/angular_devkit/build_angular/src/browser/index.ts index c399c5c4be7f..7b9d192ddcb2 100644 --- a/packages/angular_devkit/build_angular/src/browser/index.ts +++ b/packages/angular_devkit/build_angular/src/browser/index.ts @@ -190,9 +190,7 @@ export function buildWebpackBrowser( normalize(workspace.getProject(projectName).root), ); - const tsConfigPath = path.resolve(getSystemPath(workspace.root), options.tsConfig); - const tsConfig = readTsconfig(tsConfigPath); - + const tsConfig = readTsconfig(options.tsConfig, context.workspaceRoot); const target = tsConfig.options.target || ScriptTarget.ES5; const buildBrowserFeatures = new BuildBrowserFeatures( getSystemPath(projectRoot), diff --git a/packages/angular_devkit/build_angular/src/extract-i18n/index.ts b/packages/angular_devkit/build_angular/src/extract-i18n/index.ts index 93b6db07b017..70b80c95034b 100644 --- a/packages/angular_devkit/build_angular/src/extract-i18n/index.ts +++ b/packages/angular_devkit/build_angular/src/extract-i18n/index.ts @@ -20,6 +20,7 @@ import { getStatsConfig, getStylesConfig, } from '../angular-cli-files/models/webpack-configs'; +import { readTsconfig } from '../angular-cli-files/utilities/read-tsconfig'; import { statsErrorsToString, statsWarningsToString } from '../angular-cli-files/utilities/stats'; import { Schema as BrowserBuilderOptions } from '../browser/schema'; import { Version } from '../utils/version'; @@ -58,6 +59,15 @@ async function execute(options: ExtractI18nBuilderOptions, context: BuilderConte await context.getBuilderNameForTarget(browserTarget), ); + // FIXME: i18n is not yet implemented in Ivy + // We should display a warning and exit gracefully. + const { options: compilerOptions } = readTsconfig(browserOptions.tsConfig, context.workspaceRoot); + if (compilerOptions.enableIvy) { + context.logger.warn('We are sorry but i18n is not yet implemented in Ivy.'); + + return { success: true }; + } + // We need to determine the outFile name so that AngularCompiler can retrieve it. let outFile = options.outFile || getI18nOutfile(options.i18nFormat); if (options.outputPath) {