mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-19 12:34:32 +08:00
By using a pure schematic based implementation the overhead of running tslint can be removed. This also has the benefit of allowing direct control over the files loaded and to modify files only within the schematic tree context. For a hello world application, there was a ~20% performance improvement for the CLI migration from 7.0 to 8.0 as well as a ~10% reduction in memory usage.
77 lines
2.1 KiB
TypeScript
77 lines
2.1 KiB
TypeScript
/**
|
|
* @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 { DirEntry, Rule, UpdateRecorder } from '@angular-devkit/schematics';
|
|
import * as ts from '../../third_party/github.com/Microsoft/TypeScript/lib/typescript';
|
|
|
|
function* visit(directory: DirEntry): IterableIterator<ts.SourceFile> {
|
|
for (const path of directory.subfiles) {
|
|
if (path.endsWith('.ts') && !path.endsWith('.d.ts')) {
|
|
const entry = directory.file(path);
|
|
if (entry) {
|
|
const content = entry.content;
|
|
if (content.includes('loadChildren')) {
|
|
const source = ts.createSourceFile(
|
|
entry.path,
|
|
content.toString(),
|
|
ts.ScriptTarget.Latest,
|
|
true,
|
|
);
|
|
|
|
yield source;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (const path of directory.subdirs) {
|
|
if (path === 'node_modules') {
|
|
continue;
|
|
}
|
|
|
|
yield* visit(directory.dir(path));
|
|
}
|
|
}
|
|
|
|
export function updateLazyModulePaths(): Rule {
|
|
return tree => {
|
|
for (const sourceFile of visit(tree.root)) {
|
|
let recorder: UpdateRecorder | undefined;
|
|
|
|
ts.forEachChild(sourceFile, function analyze(node) {
|
|
if (ts.isPropertyAssignment(node) &&
|
|
(ts.isIdentifier(node.name) || ts.isStringLiteral(node.name)) &&
|
|
node.name.text === 'loadChildren' &&
|
|
ts.isStringLiteral(node.initializer)) {
|
|
const valueNode = node.initializer;
|
|
const parts = valueNode.text.split('#');
|
|
const path = parts[0];
|
|
const moduleName = parts[1] || 'default';
|
|
|
|
const fix = `() => import('${path}').then(m => m.${moduleName})`;
|
|
|
|
if (!recorder) {
|
|
recorder = tree.beginUpdate(sourceFile.fileName);
|
|
}
|
|
|
|
const index = valueNode.getStart();
|
|
const length = valueNode.getWidth();
|
|
recorder
|
|
.remove(index, length)
|
|
.insertLeft(index, fix);
|
|
}
|
|
|
|
ts.forEachChild(node, analyze);
|
|
});
|
|
|
|
if (recorder) {
|
|
tree.commitUpdate(recorder);
|
|
}
|
|
}
|
|
};
|
|
}
|