diff --git a/packages/compiler-cli/ngcc/index.ts b/packages/compiler-cli/ngcc/index.ts index 9e5127f1ad..693b16438d 100644 --- a/packages/compiler-cli/ngcc/index.ts +++ b/packages/compiler-cli/ngcc/index.ts @@ -7,13 +7,12 @@ */ import {CachedFileSystem, NodeJSFileSystem, setFileSystem} from '../src/ngtsc/file_system'; -import {AsyncNgccOptions, NgccOptions, SyncNgccOptions} from './src/command_line_options'; import {mainNgcc} from './src/main'; +import {AsyncNgccOptions, NgccOptions, SyncNgccOptions} from './src/ngcc_options'; -export {AsyncNgccOptions, NgccOptions, SyncNgccOptions} from './src/command_line_options'; export {ConsoleLogger} from './src/logging/console_logger'; export {Logger, LogLevel} from './src/logging/logger'; -export {PathMappings} from './src/utils'; +export {AsyncNgccOptions, NgccOptions, PathMappings, SyncNgccOptions} from './src/ngcc_options'; export function process(options: AsyncNgccOptions): Promise; export function process(options: SyncNgccOptions): void; diff --git a/packages/compiler-cli/ngcc/src/command_line_options.ts b/packages/compiler-cli/ngcc/src/command_line_options.ts index fd133e65a9..826538584a 100644 --- a/packages/compiler-cli/ngcc/src/command_line_options.ts +++ b/packages/compiler-cli/ngcc/src/command_line_options.ts @@ -8,129 +8,10 @@ */ import * as yargs from 'yargs'; -import {resolve, setFileSystem, CachedFileSystem, NodeJSFileSystem, FileSystem} from '../../src/ngtsc/file_system'; +import {resolve, setFileSystem, CachedFileSystem, NodeJSFileSystem} from '../../src/ngtsc/file_system'; import {ConsoleLogger} from './logging/console_logger'; -import {LogLevel, Logger} from './logging/logger'; -import {PathMappings} from './utils'; - -/** - * The options to configure the ngcc compiler for synchronous execution. - */ -export interface SyncNgccOptions { - /** The absolute path to the `node_modules` folder that contains the packages to process. */ - basePath: string; - - /** - * The path to the primary package to be processed. If not absolute then it must be relative to - * `basePath`. - * - * All its dependencies will need to be processed too. - * - * If this property is provided then `errorOnFailedEntryPoint` is forced to true. - */ - targetEntryPointPath?: string; - - /** - * Which entry-point properties in the package.json to consider when processing an entry-point. - * Each property should hold a path to the particular bundle format for the entry-point. - * Defaults to all the properties in the package.json. - */ - propertiesToConsider?: string[]; - - /** - * Whether to process all formats specified by (`propertiesToConsider`) or to stop processing - * this entry-point at the first matching format. Defaults to `true`. - */ - compileAllFormats?: boolean; - - /** - * Whether to create new entry-points bundles rather than overwriting the original files. - */ - createNewEntryPointFormats?: boolean; - - /** - * Provide a logger that will be called with log messages. - */ - logger?: Logger; - - /** - * Paths mapping configuration (`paths` and `baseUrl`), as found in `ts.CompilerOptions`. - * These are used to resolve paths to locally built Angular libraries. - * - * Note that `pathMappings` specified here take precedence over any `pathMappings` loaded from a - * TS config file. - */ - pathMappings?: PathMappings; - - /** - * Provide a file-system service that will be used by ngcc for all file interactions. - */ - fileSystem?: FileSystem; - - /** - * Whether the compilation should run and return asynchronously. Allowing asynchronous execution - * may speed up the compilation by utilizing multiple CPU cores (if available). - * - * Default: `false` (i.e. run synchronously) - */ - async?: false; - - /** - * Set to true in order to terminate immediately with an error code if an entry-point fails to be - * processed. - * - * If `targetEntryPointPath` is provided then this property is always true and cannot be - * changed. Otherwise the default is false. - * - * When set to false, ngcc will continue to process entry-points after a failure. In which case it - * will log an error and resume processing other entry-points. - */ - errorOnFailedEntryPoint?: boolean; - - /** - * Render `$localize` messages with legacy format ids. - * - * The default value is `true`. Only set this to `false` if you do not want legacy message ids to - * be rendered. For example, if you are not using legacy message ids in your translation files - * AND are not doing compile-time inlining of translations, in which case the extra message ids - * would add unwanted size to the final source bundle. - * - * It is safe to leave this set to true if you are doing compile-time inlining because the extra - * legacy message ids will all be stripped during translation. - */ - enableI18nLegacyMessageIdFormat?: boolean; - - /** - * Whether to invalidate any entry-point manifest file that is on disk. Instead, walk the - * directory tree looking for entry-points, and then write a new entry-point manifest, if - * possible. - * - * Default: `false` (i.e. the manifest will be used if available) - */ - invalidateEntryPointManifest?: boolean; - - /** - * An absolute path to a TS config file (e.g. `tsconfig.json`) or a directory containing one, that - * will be used to configure module resolution with things like path mappings, if not specified - * explicitly via the `pathMappings` property to `mainNgcc`. - * - * If `undefined`, ngcc will attempt to load a `tsconfig.json` file from the directory above the - * `basePath`. - * - * If `null`, ngcc will not attempt to load any TS config file at all. - */ - tsConfigPath?: string|null; -} - -/** - * The options to configure the ngcc compiler for asynchronous execution. - */ -export type AsyncNgccOptions = Omit&{async: true}; - -/** - * The options to configure the ngcc compiler. - */ -export type NgccOptions = AsyncNgccOptions|SyncNgccOptions; +import {LogLevel} from './logging/logger'; +import {NgccOptions} from './ngcc_options'; export function parseCommandLineOptions(args: string[]): NgccOptions { const options = diff --git a/packages/compiler-cli/ngcc/src/dependencies/dts_dependency_host.ts b/packages/compiler-cli/ngcc/src/dependencies/dts_dependency_host.ts index 5d23c596a7..7eef7f3a38 100644 --- a/packages/compiler-cli/ngcc/src/dependencies/dts_dependency_host.ts +++ b/packages/compiler-cli/ngcc/src/dependencies/dts_dependency_host.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ import {AbsoluteFsPath, FileSystem} from '../../../src/ngtsc/file_system'; -import {PathMappings} from '../utils'; +import {PathMappings} from '../ngcc_options'; import {EsmDependencyHost} from './esm_dependency_host'; import {ModuleResolver} from './module_resolver'; diff --git a/packages/compiler-cli/ngcc/src/dependencies/module_resolver.ts b/packages/compiler-cli/ngcc/src/dependencies/module_resolver.ts index 82fc8e5f3c..4409ece280 100644 --- a/packages/compiler-cli/ngcc/src/dependencies/module_resolver.ts +++ b/packages/compiler-cli/ngcc/src/dependencies/module_resolver.ts @@ -6,7 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ import {absoluteFrom, AbsoluteFsPath, dirname, FileSystem, isRoot, join, resolve} from '../../../src/ngtsc/file_system'; -import {isRelativePath, PathMappings, resolveFileWithPostfixes} from '../utils'; +import {PathMappings} from '../ngcc_options'; +import {isRelativePath, resolveFileWithPostfixes} from '../utils'; /** * This is a very cut-down implementation of the TypeScript module resolution strategy. diff --git a/packages/compiler-cli/ngcc/src/entry_point_finder/directory_walker_entry_point_finder.ts b/packages/compiler-cli/ngcc/src/entry_point_finder/directory_walker_entry_point_finder.ts index c4b7843231..8ac19b1495 100644 --- a/packages/compiler-cli/ngcc/src/entry_point_finder/directory_walker_entry_point_finder.ts +++ b/packages/compiler-cli/ngcc/src/entry_point_finder/directory_walker_entry_point_finder.ts @@ -9,10 +9,10 @@ import {AbsoluteFsPath, FileSystem, PathSegment} from '../../../src/ngtsc/file_s import {EntryPointWithDependencies} from '../dependencies/dependency_host'; import {DependencyResolver, SortedEntryPointsInfo} from '../dependencies/dependency_resolver'; import {Logger} from '../logging/logger'; +import {PathMappings} from '../ngcc_options'; import {NgccConfiguration} from '../packages/configuration'; import {getEntryPointInfo, INCOMPATIBLE_ENTRY_POINT, NO_ENTRY_POINT} from '../packages/entry_point'; import {EntryPointManifest} from '../packages/entry_point_manifest'; -import {PathMappings} from '../utils'; import {NGCC_DIRECTORY} from '../writing/new_entry_point_file_writer'; import {EntryPointFinder} from './interface'; diff --git a/packages/compiler-cli/ngcc/src/entry_point_finder/targeted_entry_point_finder.ts b/packages/compiler-cli/ngcc/src/entry_point_finder/targeted_entry_point_finder.ts index 0a5ef883eb..abd5c2f1a9 100644 --- a/packages/compiler-cli/ngcc/src/entry_point_finder/targeted_entry_point_finder.ts +++ b/packages/compiler-cli/ngcc/src/entry_point_finder/targeted_entry_point_finder.ts @@ -9,10 +9,10 @@ import {AbsoluteFsPath, FileSystem, join, PathSegment, relative, relativeFrom} f import {EntryPointWithDependencies} from '../dependencies/dependency_host'; import {DependencyResolver, SortedEntryPointsInfo} from '../dependencies/dependency_resolver'; import {Logger} from '../logging/logger'; +import {PathMappings} from '../ngcc_options'; import {hasBeenProcessed} from '../packages/build_marker'; import {NgccConfiguration} from '../packages/configuration'; import {EntryPoint, EntryPointJsonProperty, getEntryPointInfo, INCOMPATIBLE_ENTRY_POINT, NO_ENTRY_POINT} from '../packages/entry_point'; -import {PathMappings} from '../utils'; import {EntryPointFinder} from './interface'; import {getBasePaths} from './utils'; diff --git a/packages/compiler-cli/ngcc/src/entry_point_finder/utils.ts b/packages/compiler-cli/ngcc/src/entry_point_finder/utils.ts index ff0da04edd..9442958e66 100644 --- a/packages/compiler-cli/ngcc/src/entry_point_finder/utils.ts +++ b/packages/compiler-cli/ngcc/src/entry_point_finder/utils.ts @@ -7,7 +7,7 @@ */ import {AbsoluteFsPath, getFileSystem, relative, resolve} from '../../../src/ngtsc/file_system'; import {Logger} from '../logging/logger'; -import {PathMappings} from '../utils'; +import {PathMappings} from '../ngcc_options'; /** * Extract all the base-paths that we need to search for entry-points. diff --git a/packages/compiler-cli/ngcc/src/execution/cluster/worker.ts b/packages/compiler-cli/ngcc/src/execution/cluster/worker.ts index 610cfe5078..a570494345 100644 --- a/packages/compiler-cli/ngcc/src/execution/cluster/worker.ts +++ b/packages/compiler-cli/ngcc/src/execution/cluster/worker.ts @@ -9,12 +9,11 @@ import * as cluster from 'cluster'; -import {absoluteFrom, CachedFileSystem, getFileSystem, NodeJSFileSystem, setFileSystem} from '../../../../src/ngtsc/file_system'; -import {readConfiguration} from '../../../../src/perform_compile'; +import {CachedFileSystem, NodeJSFileSystem, setFileSystem} from '../../../../src/ngtsc/file_system'; import {parseCommandLineOptions} from '../../command_line_options'; import {ConsoleLogger} from '../../logging/console_logger'; import {Logger, LogLevel} from '../../logging/logger'; -import {getPathMappingsFromTsConfig} from '../../utils'; +import {getSharedSetup} from '../../ngcc_options'; import {CreateCompileFn} from '../api'; import {getCreateCompileFn} from '../create_compile_function'; import {stringifyTask} from '../tasks/utils'; @@ -25,34 +24,21 @@ import {sendMessageToMaster} from './utils'; // Cluster worker entry point if (require.main === module) { - process.title = 'ngcc (worker)'; - setFileSystem(new CachedFileSystem(new NodeJSFileSystem())); - let { - basePath, - targetEntryPointPath, - createNewEntryPointFormats = false, - logger = new ConsoleLogger(LogLevel.info), - pathMappings, - errorOnFailedEntryPoint = false, - enableI18nLegacyMessageIdFormat = true, - tsConfigPath - } = parseCommandLineOptions(process.argv.slice(2)); (async () => { + process.title = 'ngcc (worker)'; + try { - if (!!targetEntryPointPath) { - // targetEntryPointPath forces us to error if an entry-point fails. - errorOnFailedEntryPoint = true; - } + setFileSystem(new CachedFileSystem(new NodeJSFileSystem())); - const fileSystem = getFileSystem(); - const absBasePath = absoluteFrom(basePath); - const projectPath = fileSystem.dirname(absBasePath); - const tsConfig = - tsConfigPath !== null ? readConfiguration(tsConfigPath || projectPath) : null; - - if (pathMappings === undefined) { - pathMappings = getPathMappingsFromTsConfig(tsConfig, projectPath); - } + const { + createNewEntryPointFormats = false, + logger = new ConsoleLogger(LogLevel.info), + pathMappings, + errorOnFailedEntryPoint = false, + enableI18nLegacyMessageIdFormat = true, + fileSystem, + tsConfig + } = getSharedSetup(parseCommandLineOptions(process.argv.slice(2))); // NOTE: To avoid file corruption, `ngcc` invocation only creates _one_ instance of // `PackageJsonUpdater` that actually writes to disk (across all processes). @@ -68,7 +54,7 @@ if (require.main === module) { process.exitCode = 0; } catch (e) { console.error(e.stack || e.message); - process.exitCode = 1; + process.exit(1); } })(); } diff --git a/packages/compiler-cli/ngcc/src/execution/create_compile_function.ts b/packages/compiler-cli/ngcc/src/execution/create_compile_function.ts index 38bf31fdfa..3eab5c296f 100644 --- a/packages/compiler-cli/ngcc/src/execution/create_compile_function.ts +++ b/packages/compiler-cli/ngcc/src/execution/create_compile_function.ts @@ -12,9 +12,9 @@ import {replaceTsWithNgInErrors} from '../../../src/ngtsc/diagnostics'; import {FileSystem} from '../../../src/ngtsc/file_system'; import {ParsedConfiguration} from '../../../src/perform_compile'; import {Logger} from '../logging/logger'; +import {PathMappings} from '../ngcc_options'; import {getEntryPointFormat} from '../packages/entry_point'; import {makeEntryPointBundle} from '../packages/entry_point_bundle'; -import {PathMappings} from '../utils'; import {FileWriter} from '../writing/file_writer'; import {InPlaceFileWriter} from '../writing/in_place_file_writer'; import {NewEntryPointFileWriter} from '../writing/new_entry_point_file_writer'; diff --git a/packages/compiler-cli/ngcc/src/main.ts b/packages/compiler-cli/ngcc/src/main.ts index 7422a6b6b5..02ddbf7ab2 100644 --- a/packages/compiler-cli/ngcc/src/main.ts +++ b/packages/compiler-cli/ngcc/src/main.ts @@ -10,10 +10,8 @@ import * as os from 'os'; -import {readConfiguration} from '../..'; -import {absoluteFrom, AbsoluteFsPath, dirname, FileSystem, getFileSystem, resolve} from '../../src/ngtsc/file_system'; +import {AbsoluteFsPath, FileSystem, resolve} from '../../src/ngtsc/file_system'; -import {AsyncNgccOptions, NgccOptions, SyncNgccOptions} from './command_line_options'; import {CommonJsDependencyHost} from './dependencies/commonjs_dependency_host'; import {DependencyResolver} from './dependencies/dependency_resolver'; import {DtsDependencyHost} from './dependencies/dts_dependency_host'; @@ -33,12 +31,11 @@ import {composeTaskCompletedCallbacks, createLogErrorHandler, createMarkAsProces import {AsyncLocker} from './locking/async_locker'; import {LockFileWithChildProcess} from './locking/lock_file_with_child_process'; import {SyncLocker} from './locking/sync_locker'; -import {ConsoleLogger} from './logging/console_logger'; -import {Logger, LogLevel} from './logging/logger'; +import {Logger} from './logging/logger'; +import {AsyncNgccOptions, getSharedSetup, NgccOptions, PathMappings, SyncNgccOptions} from './ngcc_options'; import {NgccConfiguration} from './packages/configuration'; import {EntryPointJsonProperty, SUPPORTED_FORMAT_PROPERTIES} from './packages/entry_point'; import {EntryPointManifest, InvalidatingEntryPointManifest} from './packages/entry_point_manifest'; -import {getPathMappingsFromTsConfig, PathMappings} from './utils'; import {DirectPackageJsonUpdater, PackageJsonUpdater} from './writing/package_json_updater'; /** @@ -51,41 +48,26 @@ import {DirectPackageJsonUpdater, PackageJsonUpdater} from './writing/package_js */ export function mainNgcc(options: AsyncNgccOptions): Promise; export function mainNgcc(options: SyncNgccOptions): void; -export function mainNgcc({ - basePath, - targetEntryPointPath, - propertiesToConsider = SUPPORTED_FORMAT_PROPERTIES, - compileAllFormats = true, - createNewEntryPointFormats = false, - logger = new ConsoleLogger(LogLevel.info), - pathMappings, - async = false, - errorOnFailedEntryPoint = false, - enableI18nLegacyMessageIdFormat = true, - invalidateEntryPointManifest = false, - tsConfigPath -}: NgccOptions): void|Promise { - if (!!targetEntryPointPath) { - // targetEntryPointPath forces us to error if an entry-point fails. - errorOnFailedEntryPoint = true; - } +export function mainNgcc(options: NgccOptions): void|Promise { + const { + basePath, + targetEntryPointPath, + propertiesToConsider, + compileAllFormats, + createNewEntryPointFormats, + logger, + pathMappings, + async, + errorOnFailedEntryPoint, + enableI18nLegacyMessageIdFormat, + invalidateEntryPointManifest, + fileSystem, + absBasePath, + projectPath, + tsConfig + } = getSharedSetup(options); - // Execute in parallel, if async execution is acceptable and there are more than 1 CPU cores. - const inParallel = async && (os.cpus().length > 1); - - // Instantiate common utilities that are always used. - // NOTE: Avoid eagerly instantiating anything that might not be used when running sync/async or in - // master/worker process. - const fileSystem = getFileSystem(); - const absBasePath = absoluteFrom(basePath); - const projectPath = dirname(absBasePath); const config = new NgccConfiguration(fileSystem, projectPath); - const tsConfig = tsConfigPath !== null ? readConfiguration(tsConfigPath || projectPath) : null; - - if (pathMappings === undefined) { - pathMappings = getPathMappingsFromTsConfig(tsConfig, projectPath); - } - const dependencyResolver = getDependencyResolver(fileSystem, logger, config, pathMappings); const entryPointManifest = invalidateEntryPointManifest ? new InvalidatingEntryPointManifest(fileSystem, config, logger) : @@ -104,12 +86,16 @@ export function mainNgcc({ return; } - const pkgJsonUpdater = new DirectPackageJsonUpdater(fileSystem); + // Execute in parallel, if async execution is acceptable and there are more than 1 CPU cores. + const inParallel = async && (os.cpus().length > 1); const analyzeEntryPoints = getAnalyzeEntryPointsFn( logger, finder, fileSystem, supportedPropertiesToConsider, compileAllFormats, propertiesToConsider, inParallel); + // Create an updater that will actually write to disk. In + const pkgJsonUpdater = new DirectPackageJsonUpdater(fileSystem); + // The function for creating the `compile()` function. const createCompileFn = getCreateCompileFn( fileSystem, logger, pkgJsonUpdater, createNewEntryPointFormats, errorOnFailedEntryPoint, diff --git a/packages/compiler-cli/ngcc/src/ngcc_options.ts b/packages/compiler-cli/ngcc/src/ngcc_options.ts new file mode 100644 index 0000000000..36120276ca --- /dev/null +++ b/packages/compiler-cli/ngcc/src/ngcc_options.ts @@ -0,0 +1,214 @@ +/** + * @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 + */ +import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem, resolve} from '../../src/ngtsc/file_system'; +import {ParsedConfiguration, readConfiguration} from '../../src/perform_compile'; + +import {ConsoleLogger} from './logging/console_logger'; +import {Logger, LogLevel} from './logging/logger'; +import {SUPPORTED_FORMAT_PROPERTIES} from './packages/entry_point'; + +/** + * The options to configure the ngcc compiler for synchronous execution. + */ +export interface SyncNgccOptions { + /** The absolute path to the `node_modules` folder that contains the packages to process. */ + basePath: string; + + /** + * The path to the primary package to be processed. If not absolute then it must be relative to + * `basePath`. + * + * All its dependencies will need to be processed too. + * + * If this property is provided then `errorOnFailedEntryPoint` is forced to true. + */ + targetEntryPointPath?: string; + + /** + * Which entry-point properties in the package.json to consider when processing an entry-point. + * Each property should hold a path to the particular bundle format for the entry-point. + * Defaults to all the properties in the package.json. + */ + propertiesToConsider?: string[]; + + /** + * Whether to process all formats specified by (`propertiesToConsider`) or to stop processing + * this entry-point at the first matching format. Defaults to `true`. + */ + compileAllFormats?: boolean; + + /** + * Whether to create new entry-points bundles rather than overwriting the original files. + */ + createNewEntryPointFormats?: boolean; + + /** + * Provide a logger that will be called with log messages. + */ + logger?: Logger; + + /** + * Paths mapping configuration (`paths` and `baseUrl`), as found in `ts.CompilerOptions`. + * These are used to resolve paths to locally built Angular libraries. + * + * Note that `pathMappings` specified here take precedence over any `pathMappings` loaded from a + * TS config file. + */ + pathMappings?: PathMappings; + + /** + * Provide a file-system service that will be used by ngcc for all file interactions. + */ + fileSystem?: FileSystem; + + /** + * Whether the compilation should run and return asynchronously. Allowing asynchronous execution + * may speed up the compilation by utilizing multiple CPU cores (if available). + * + * Default: `false` (i.e. run synchronously) + */ + async?: false; + + /** + * Set to true in order to terminate immediately with an error code if an entry-point fails to be + * processed. + * + * If `targetEntryPointPath` is provided then this property is always true and cannot be + * changed. Otherwise the default is false. + * + * When set to false, ngcc will continue to process entry-points after a failure. In which case it + * will log an error and resume processing other entry-points. + */ + errorOnFailedEntryPoint?: boolean; + + /** + * Render `$localize` messages with legacy format ids. + * + * The default value is `true`. Only set this to `false` if you do not want legacy message ids to + * be rendered. For example, if you are not using legacy message ids in your translation files + * AND are not doing compile-time inlining of translations, in which case the extra message ids + * would add unwanted size to the final source bundle. + * + * It is safe to leave this set to true if you are doing compile-time inlining because the extra + * legacy message ids will all be stripped during translation. + */ + enableI18nLegacyMessageIdFormat?: boolean; + + /** + * Whether to invalidate any entry-point manifest file that is on disk. Instead, walk the + * directory tree looking for entry-points, and then write a new entry-point manifest, if + * possible. + * + * Default: `false` (i.e. the manifest will be used if available) + */ + invalidateEntryPointManifest?: boolean; + + /** + * An absolute path to a TS config file (e.g. `tsconfig.json`) or a directory containing one, that + * will be used to configure module resolution with things like path mappings, if not specified + * explicitly via the `pathMappings` property to `mainNgcc`. + * + * If `undefined`, ngcc will attempt to load a `tsconfig.json` file from the directory above the + * `basePath`. + * + * If `null`, ngcc will not attempt to load any TS config file at all. + */ + tsConfigPath?: string|null; +} + +/** + * The options to configure the ngcc compiler for asynchronous execution. + */ +export type AsyncNgccOptions = Omit&{async: true}; + +/** + * The options to configure the ngcc compiler. + */ +export type NgccOptions = AsyncNgccOptions|SyncNgccOptions; + +export type PathMappings = { + baseUrl: string, + paths: {[key: string]: string[]} +}; + +/** + * If `pathMappings` is not provided directly, then try getting it from `tsConfig`, if available. + */ +export function getPathMappingsFromTsConfig( + tsConfig: ParsedConfiguration|null, projectPath: AbsoluteFsPath): PathMappings|undefined { + if (tsConfig !== null && tsConfig.options.baseUrl !== undefined && + tsConfig.options.paths !== undefined) { + return { + baseUrl: resolve(projectPath, tsConfig.options.baseUrl), + paths: tsConfig.options.paths, + }; + } +} + +export type OptionalNgccOptionKeys = 'targetEntryPointPath'|'tsConfigPath'|'pathMappings'; +export type RequiredNgccOptions = Required>; +export type OptionalNgccOptions = Pick; +export type SharedSetup = { + fileSystem: FileSystem; absBasePath: AbsoluteFsPath; projectPath: AbsoluteFsPath; + tsConfig: ParsedConfiguration | null; +}; + +/** + * Instantiate common utilities that are always used and fix up options with defaults, as necessary. + * + * NOTE: Avoid eagerly instantiating anything that might not be used when running sync/async. + */ +export function getSharedSetup(options: NgccOptions): SharedSetup&RequiredNgccOptions& + OptionalNgccOptions { + const fileSystem = getFileSystem(); + const absBasePath = absoluteFrom(options.basePath); + const projectPath = fileSystem.dirname(absBasePath); + const tsConfig = + options.tsConfigPath !== null ? readConfiguration(options.tsConfigPath || projectPath) : null; + + let { + basePath, + targetEntryPointPath, + propertiesToConsider = SUPPORTED_FORMAT_PROPERTIES, + compileAllFormats = true, + createNewEntryPointFormats = false, + logger = new ConsoleLogger(LogLevel.info), + pathMappings, + async = false, + errorOnFailedEntryPoint = false, + enableI18nLegacyMessageIdFormat = true, + invalidateEntryPointManifest = false, + tsConfigPath, + } = options; + + pathMappings = options.pathMappings || getPathMappingsFromTsConfig(tsConfig, projectPath); + + if (!!options.targetEntryPointPath) { + // targetEntryPointPath forces us to error if an entry-point fails. + errorOnFailedEntryPoint = true; + } + + return { + basePath, + targetEntryPointPath, + propertiesToConsider, + compileAllFormats, + createNewEntryPointFormats, + logger, + pathMappings, + async, + errorOnFailedEntryPoint, + enableI18nLegacyMessageIdFormat, + invalidateEntryPointManifest, + tsConfigPath, + fileSystem, + absBasePath, + projectPath, + tsConfig, + }; +} diff --git a/packages/compiler-cli/ngcc/src/packages/entry_point_bundle.ts b/packages/compiler-cli/ngcc/src/packages/entry_point_bundle.ts index 74b4173006..62259c1b4c 100644 --- a/packages/compiler-cli/ngcc/src/packages/entry_point_bundle.ts +++ b/packages/compiler-cli/ngcc/src/packages/entry_point_bundle.ts @@ -7,7 +7,7 @@ */ import * as ts from 'typescript'; import {AbsoluteFsPath, FileSystem, NgtscCompilerHost} from '../../../src/ngtsc/file_system'; -import {PathMappings} from '../utils'; +import {PathMappings} from '../ngcc_options'; import {BundleProgram, makeBundleProgram} from './bundle_program'; import {EntryPoint, EntryPointFormat} from './entry_point'; import {NgccSourcesCompilerHost} from './ngcc_compiler_host'; diff --git a/packages/compiler-cli/ngcc/src/utils.ts b/packages/compiler-cli/ngcc/src/utils.ts index ed544e5dff..507a880ff2 100644 --- a/packages/compiler-cli/ngcc/src/utils.ts +++ b/packages/compiler-cli/ngcc/src/utils.ts @@ -5,10 +5,9 @@ * 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 */ -import {ParsedConfiguration} from '@angular/compiler-cli/src/perform_compile'; import * as ts from 'typescript'; -import {absoluteFrom, AbsoluteFsPath, FileSystem, isRooted, resolve} from '../../src/ngtsc/file_system'; +import {absoluteFrom, AbsoluteFsPath, FileSystem, isRooted} from '../../src/ngtsc/file_system'; import {KnownDeclaration} from '../../src/ngtsc/reflection'; /** @@ -78,11 +77,6 @@ export function hasNameIdentifier(declaration: ts.Declaration): declaration is t return namedDeclaration.name !== undefined && ts.isIdentifier(namedDeclaration.name); } -export type PathMappings = { - baseUrl: string, - paths: {[key: string]: string[]} -}; - /** * Test whether a path is "relative". * @@ -186,17 +180,3 @@ export function stripDollarSuffix(value: string): string { export function stripExtension(fileName: string): string { return fileName.replace(/\..+$/, ''); } - -/** - * If `pathMappings` is not provided directly, then try getting it from `tsConfig`, if available. - */ -export function getPathMappingsFromTsConfig( - tsConfig: ParsedConfiguration|null, projectPath: AbsoluteFsPath): PathMappings|undefined { - if (tsConfig !== null && tsConfig.options.baseUrl !== undefined && - tsConfig.options.paths !== undefined) { - return { - baseUrl: resolve(projectPath, tsConfig.options.baseUrl), - paths: tsConfig.options.paths, - }; - } -} \ No newline at end of file diff --git a/packages/compiler-cli/ngcc/test/entry_point_finder/directory_walker_entry_point_finder_spec.ts b/packages/compiler-cli/ngcc/test/entry_point_finder/directory_walker_entry_point_finder_spec.ts index a8990eb5d1..aa3bdd3dc1 100644 --- a/packages/compiler-cli/ngcc/test/entry_point_finder/directory_walker_entry_point_finder_spec.ts +++ b/packages/compiler-cli/ngcc/test/entry_point_finder/directory_walker_entry_point_finder_spec.ts @@ -13,10 +13,10 @@ import {DtsDependencyHost} from '../../src/dependencies/dts_dependency_host'; import {EsmDependencyHost} from '../../src/dependencies/esm_dependency_host'; import {ModuleResolver} from '../../src/dependencies/module_resolver'; import {DirectoryWalkerEntryPointFinder} from '../../src/entry_point_finder/directory_walker_entry_point_finder'; +import {PathMappings} from '../../src/ngcc_options'; import {NgccConfiguration} from '../../src/packages/configuration'; import {EntryPoint} from '../../src/packages/entry_point'; import {EntryPointManifest, EntryPointManifestFile} from '../../src/packages/entry_point_manifest'; -import {PathMappings} from '../../src/utils'; import {MockLogger} from '../helpers/mock_logger'; runInEachFileSystem(() => { diff --git a/packages/compiler-cli/ngcc/test/entry_point_finder/targeted_entry_point_finder_spec.ts b/packages/compiler-cli/ngcc/test/entry_point_finder/targeted_entry_point_finder_spec.ts index e8555324b8..dc9af67357 100644 --- a/packages/compiler-cli/ngcc/test/entry_point_finder/targeted_entry_point_finder_spec.ts +++ b/packages/compiler-cli/ngcc/test/entry_point_finder/targeted_entry_point_finder_spec.ts @@ -13,10 +13,10 @@ import {DtsDependencyHost} from '../../src/dependencies/dts_dependency_host'; import {EsmDependencyHost} from '../../src/dependencies/esm_dependency_host'; import {ModuleResolver} from '../../src/dependencies/module_resolver'; import {TargetedEntryPointFinder} from '../../src/entry_point_finder/targeted_entry_point_finder'; +import {PathMappings} from '../../src/ngcc_options'; import {NGCC_VERSION} from '../../src/packages/build_marker'; import {NgccConfiguration} from '../../src/packages/configuration'; import {EntryPoint} from '../../src/packages/entry_point'; -import {PathMappings} from '../../src/utils'; import {MockLogger} from '../helpers/mock_logger'; runInEachFileSystem(() => {