mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
refactor(schematics): avoid typescript version conflicts (#12989)
The Angular Material schematics parse TypeScript sources files and pass the AST to the `@schematics/angular` package which defined an explicit dependency on `typescript`. Since we currently just always require the flattened `typescript` dependency (`node_modules/typescript`), there could be either no TypeScript version or a different TypeScript version that causes the AST operations of the `@schematics/angular` utility functions to not work properly (e.g. different `SyntaxKind` ids) We should primarily try to load the same TypeScript version that has been shipped with the `@schematics/angular`. If that one couldn't be found, fall back to the top level `typescript` version. Includes workaround for Bazel ts module resolution
This commit is contained in:
committed by
Jeremy Elbourn
parent
c54c89769c
commit
9886b1b198
@@ -47,7 +47,11 @@ jobs:
|
||||
<<: *post_checkout
|
||||
- restore_cache:
|
||||
key: *cache_key
|
||||
- run: echo "Temporarily disabled until Bazel setup can be fixed"
|
||||
|
||||
- run: bazel run @nodejs//:npm install
|
||||
# TODO(jelbourn): Update this command to run all tests if the Bazel issues have been fixed.
|
||||
- run: bazel test src/lib/schematics:unit_tests
|
||||
|
||||
- save_cache:
|
||||
key: *cache_key
|
||||
paths:
|
||||
|
||||
@@ -13,12 +13,11 @@ import {InsertChange} from '@schematics/angular/utility/change';
|
||||
import {getWorkspace, WorkspaceProject} from '@schematics/angular/utility/config';
|
||||
import {findModuleFromOptions as internalFindModule} from '@schematics/angular/utility/find-module';
|
||||
import {getAppModulePath} from '@schematics/angular/utility/ng-ast-utils';
|
||||
import * as ts from 'typescript';
|
||||
import {getProjectMainFile} from './project-main-file';
|
||||
|
||||
import {ts} from './version-agnostic-typescript';
|
||||
|
||||
/** Reads file given path and returns TypeScript source file. */
|
||||
export function getSourceFile(host: Tree, path: string): ts.SourceFile {
|
||||
export function getSourceFile(host: Tree, path: string) {
|
||||
const buffer = host.read(path);
|
||||
if (!buffer) {
|
||||
throw new SchematicsException(`Could not find file for path: ${path}`);
|
||||
@@ -50,8 +49,9 @@ export function addModuleImportToModule(host: Tree, modulePath: string, moduleNa
|
||||
throw new SchematicsException(`Module not found: ${modulePath}`);
|
||||
}
|
||||
|
||||
// TODO: cast to any, because the types for ts.SourceFile
|
||||
// aren't compatible with `strictFunctionTypes`.
|
||||
// TODO(devversion): Cast to any because the Bazel typescript rules seem to incorrectly resolve
|
||||
// the the required TypeScript version for the @schematics/angular utility functions. Meaning
|
||||
// that is a type signature mismatch at compilation which is not valid.
|
||||
const changes = addImportToModule(moduleSource as any, modulePath, moduleName, src);
|
||||
const recorder = host.beginUpdate(modulePath);
|
||||
|
||||
|
||||
@@ -38,18 +38,17 @@ import {buildDefaultPath} from '@schematics/angular/utility/project';
|
||||
import {validateHtmlSelector, validateName} from '@schematics/angular/utility/validation';
|
||||
import {readFileSync} from 'fs';
|
||||
import {dirname, join, resolve} from 'path';
|
||||
import * as ts from 'typescript';
|
||||
import {getProjectFromWorkspace} from './get-project';
|
||||
import {getDefaultComponentOptions} from './schematic-options';
|
||||
import {ts} from './version-agnostic-typescript';
|
||||
|
||||
function readIntoSourceFile(host: Tree, modulePath: string): ts.SourceFile {
|
||||
function readIntoSourceFile(host: Tree, modulePath: string) {
|
||||
const text = host.read(modulePath);
|
||||
if (text === null) {
|
||||
throw new SchematicsException(`File ${modulePath} does not exist.`);
|
||||
}
|
||||
const sourceText = text.toString('utf-8');
|
||||
|
||||
return ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true);
|
||||
return ts.createSourceFile(modulePath, text.toString('utf-8'), ts.ScriptTarget.Latest, true);
|
||||
}
|
||||
|
||||
function addDeclarationToNgModule(options: ComponentOptions): Rule {
|
||||
@@ -68,9 +67,11 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
|
||||
const relativePath = buildRelativePath(modulePath, componentPath);
|
||||
const classifiedName = strings.classify(`${options.name}Component`);
|
||||
|
||||
// TODO: cast to any, because the types for ts.SourceFile
|
||||
// aren't compatible with `strictFunctionTypes`.
|
||||
const declarationChanges = addDeclarationToModule(source as any,
|
||||
// TODO(devversion): Cast to any because the Bazel typescript rules seem to incorrectly resolve
|
||||
// the the required TypeScript version for the @schematics/angular utility functions. Meaning
|
||||
// that is a type signature mismatch at compilation which is not valid.
|
||||
const declarationChanges = addDeclarationToModule(
|
||||
source as any,
|
||||
modulePath,
|
||||
classifiedName,
|
||||
relativePath);
|
||||
@@ -88,9 +89,12 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
|
||||
const source = readIntoSourceFile(host, modulePath);
|
||||
const exportRecorder = host.beginUpdate(modulePath);
|
||||
|
||||
// TODO: cast to any, because the types for ts.SourceFile
|
||||
// aren't compatible with `strictFunctionTypes`.
|
||||
const exportChanges = addExportToModule(source as any, modulePath,
|
||||
// TODO(devversion): Cast to any because the Bazel typescript rules seem to incorrectly resolve
|
||||
// the the required TypeScript version for the @schematics/angular utility functions. Meaning
|
||||
// that is a type signature mismatch at compilation which is not valid.
|
||||
const exportChanges = addExportToModule(
|
||||
source as any,
|
||||
modulePath,
|
||||
strings.classify(`${options.name}Component`),
|
||||
relativePath);
|
||||
|
||||
@@ -107,10 +111,12 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
|
||||
const source = readIntoSourceFile(host, modulePath);
|
||||
const entryComponentRecorder = host.beginUpdate(modulePath);
|
||||
|
||||
// TODO: cast to any, because the types for ts.SourceFile
|
||||
// aren't compatible with `strictFunctionTypes`.
|
||||
// TODO(devversion): Cast to any because the Bazel typescript rules seem to incorrectly resolve
|
||||
// the the required TypeScript version for the @schematics/angular utility functions. Meaning
|
||||
// that is a type signature mismatch at compilation which is not valid.
|
||||
const entryComponentChanges = addEntryComponentToModule(
|
||||
source as any, modulePath,
|
||||
source as any,
|
||||
modulePath,
|
||||
strings.classify(`${options.name}Component`),
|
||||
relativePath);
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC 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
|
||||
*/
|
||||
|
||||
/** This is just a type import and won't be generated in the release output. */
|
||||
import typescript = require('@schematics/angular/node_modules/typescript');
|
||||
|
||||
/**
|
||||
* This is an agnostic re-export of TypeScript. Depending on the context, this module file will
|
||||
* return the TypeScript version that is being shipped within the `@schematics/angular` package,
|
||||
* or fall back to the TypeScript version that has been flattened in the node modules.
|
||||
*
|
||||
* This is necessary because we parse TypeScript files and pass the resolved AST to the
|
||||
* `@schematics/angular` package which might have a different TypeScript version installed.
|
||||
*/
|
||||
let ts: typeof typescript;
|
||||
|
||||
try {
|
||||
ts = require('@schematics/angular/node_modules/typescript');
|
||||
} catch {
|
||||
try {
|
||||
ts = require('typescript');
|
||||
} catch {
|
||||
throw new Error('Error: Could not find TypeScript for the Angular Material schematics. ' +
|
||||
'Please report an issue on the Angular Material repository.');
|
||||
}
|
||||
}
|
||||
|
||||
export {ts};
|
||||
Reference in New Issue
Block a user