refactor(bazel): use `readConfiguration` to read config file (#40694)

With this change we clean up the parsing of tsconfig files.

PR Close #40694
This commit is contained in:
Alan Agius 2021-02-04 15:39:53 +01:00 committed by Joey Perrott
parent b7c4d07e81
commit 719f9ef7ac
1 changed files with 37 additions and 64 deletions

View File

@ -44,81 +44,54 @@ export function runOneBuild(args: string[], inputs?: {[path: string]: string}):
const project = args[0].replace(/^@+/, ''); const project = args[0].replace(/^@+/, '');
const [parsedOptions, errors] = parseTsconfig(project); const [parsedOptions, errors] = parseTsconfig(project);
if (errors && errors.length) { if (errors?.length) {
console.error(ng.formatDiagnostics(errors)); console.error(ng.formatDiagnostics(errors));
return false; return false;
} }
const {options: tsOptions, bazelOpts, files, config} = parsedOptions;
const angularCompilerOptions: {[k: string]: unknown} = config['angularCompilerOptions'] || {};
// Allow Bazel users to control some of the bazel options. const {bazelOpts, options: tsOptions, files, config} = parsedOptions;
// Since TypeScript's "extends" mechanism applies only to "compilerOptions" const {errors: userErrors, options: userOptions} = ng.readConfiguration(project);
// we have to repeat some of their logic to get the user's "angularCompilerOptions".
if (config['extends']) {
// Load the user's config file
// Note: this doesn't handle recursive extends so only a user's top level
// `angularCompilerOptions` will be considered. As this code is going to be
// removed with Ivy, the added complication of handling recursive extends
// is likely not needed.
let userConfigFile = resolveNormalizedPath(path.dirname(project), config['extends']);
if (!userConfigFile.endsWith('.json')) userConfigFile += '.json';
const {config: userConfig, error} = ts.readConfigFile(userConfigFile, ts.sys.readFile);
if (error) {
console.error(ng.formatDiagnostics([error]));
return false;
}
// All user angularCompilerOptions values that a user has control if (userErrors?.length) {
// over should be collected here console.error(ng.formatDiagnostics(userErrors));
if (userConfig.angularCompilerOptions) { return false;
angularCompilerOptions['diagnostics'] =
angularCompilerOptions['diagnostics'] || userConfig.angularCompilerOptions.diagnostics;
angularCompilerOptions['trace'] =
angularCompilerOptions['trace'] || userConfig.angularCompilerOptions.trace;
angularCompilerOptions['disableExpressionLowering'] =
angularCompilerOptions['disableExpressionLowering'] ||
userConfig.angularCompilerOptions.disableExpressionLowering;
angularCompilerOptions['disableTypeScriptVersionCheck'] =
angularCompilerOptions['disableTypeScriptVersionCheck'] ||
userConfig.angularCompilerOptions.disableTypeScriptVersionCheck;
angularCompilerOptions['i18nOutLocale'] = angularCompilerOptions['i18nOutLocale'] ||
userConfig.angularCompilerOptions.i18nOutLocale;
angularCompilerOptions['i18nOutFormat'] = angularCompilerOptions['i18nOutFormat'] ||
userConfig.angularCompilerOptions.i18nOutFormat;
angularCompilerOptions['i18nOutFile'] =
angularCompilerOptions['i18nOutFile'] || userConfig.angularCompilerOptions.i18nOutFile;
angularCompilerOptions['i18nInFormat'] =
angularCompilerOptions['i18nInFormat'] || userConfig.angularCompilerOptions.i18nInFormat;
angularCompilerOptions['i18nInLocale'] =
angularCompilerOptions['i18nInLocale'] || userConfig.angularCompilerOptions.i18nInLocale;
angularCompilerOptions['i18nInFile'] =
angularCompilerOptions['i18nInFile'] || userConfig.angularCompilerOptions.i18nInFile;
angularCompilerOptions['i18nInMissingTranslations'] =
angularCompilerOptions['i18nInMissingTranslations'] ||
userConfig.angularCompilerOptions.i18nInMissingTranslations;
angularCompilerOptions['i18nUseExternalIds'] = angularCompilerOptions['i18nUseExternalIds'] ||
userConfig.angularCompilerOptions.i18nUseExternalIds;
angularCompilerOptions['preserveWhitespaces'] =
angularCompilerOptions['preserveWhitespaces'] ||
userConfig.angularCompilerOptions.preserveWhitespaces;
angularCompilerOptions.createExternalSymbolFactoryReexports =
angularCompilerOptions.createExternalSymbolFactoryReexports ||
userConfig.angularCompilerOptions.createExternalSymbolFactoryReexports;
}
} }
const allowedNgCompilerOptionsOverrides = new Set<string>([
'diagnostics',
'trace',
'disableExpressionLowering',
'disableTypeScriptVersionCheck',
'i18nOutLocale',
'i18nOutFormat',
'i18nOutFile',
'i18nInLocale',
'i18nInFile',
'i18nInFormat',
'i18nUseExternalIds',
'i18nInMissingTranslations',
'preserveWhitespaces',
'createExternalSymbolFactoryReexports',
]);
const userOverrides = Object.entries(userOptions)
.filter(([key]) => allowedNgCompilerOptionsOverrides.has(key))
.reduce((obj, [key, value]) => {
obj[key] = value;
return obj;
}, {});
const compilerOpts: ng.AngularCompilerOptions = {
...userOverrides,
...config['angularCompilerOptions'],
...tsOptions,
};
// These are options passed through from the `ng_module` rule which aren't supported // These are options passed through from the `ng_module` rule which aren't supported
// by the `@angular/compiler-cli` and are only intended for `ngc-wrapped`. // by the `@angular/compiler-cli` and are only intended for `ngc-wrapped`.
const {expectedOut, _useManifestPathsAsModuleName} = config['angularCompilerOptions']; const {expectedOut, _useManifestPathsAsModuleName} = config['angularCompilerOptions'];
const {basePath} = ng.calcProjectFileAndBasePath(project);
const compilerOpts = ng.createNgCompilerOptions(basePath, config, tsOptions);
const tsHost = ts.createCompilerHost(compilerOpts, true); const tsHost = ts.createCompilerHost(compilerOpts, true);
const {diagnostics} = compile({ const {diagnostics} = compile({
allDepsCompiledWithBazel: ALL_DEPS_COMPILED_WITH_BAZEL, allDepsCompiledWithBazel: ALL_DEPS_COMPILED_WITH_BAZEL,