Angular 原理图 - 将库添加到 NgModule 导入
Angular Schematics - add library to NgModule imports
在 Angular 中使用 Schematics 生成组件时,它会尝试将新生成的组件导入到 NgModule 中,这是强制性的,以便组件工作并节省时间。
但是,在创建我自己的原理图时,我无法找到正确的方法来执行相同的操作并将我的库导入 app.component.ts 的 NgModule。使用 ng-add schematics 时,如何让 schematic 自动添加自己的条目到 NgModule?
原理图需要做两件事:
- 导入库
- 将其添加到 NgModule 导入中
之前:
@NgModule({
declarations: [],
imports: [],
exports: []
})
export class appModule { }
之后:
import {library} from 'library';
@NgModule({
declarations: [],
imports: [library],
exports: []
})
export class appModule { }
我知道 angular devkit 中存在执行此操作的功能,因为组件的 "official" 原理图等使用它。我该怎么做?
对于第一种情况,类似下面的代码可以帮助您:
export function addImportStatement(tree: Tree, filePath: string, type: string, file: string): void {
let source = getTsSourceFile(tree, filePath);
const importChange = insertImport(source, filePath, type, file) as InsertChange;
if (!(importChange instanceof NoopChange)) {
const recorder = tree.beginUpdate(filePath);
recorder.insertLeft(importChange.pos, importChange.toAdd);
tree.commitUpdate(recorder);
}
}
对于第二个,我现在不记得了,但你可以查看 angular-cli schematics 存储库,以了解它是如何为模块之类的东西完成的。
干杯!
这是一个使用来自“@schematics/angular/utility/ast-utils”实用程序的'addImportToModule'函数的函数..
function _addImport(
importPath: string,
importName: string,
_options: Partial<Schema>,
tree: Tree
): Tree {
const appModulePath = `/${_options.projectName}/src/app/app.module.ts`;
const appModuleFile = tree.read(normalize(appModulePath)).toString('utf-8');
if (!appModuleFile) {
throw new SchematicsException('app.module.ts not found');
}
const result = new AddToModuleContext();
result.source = ts.createSourceFile(
appModulePath,
appModuleFile,
ts.ScriptTarget.Latest,
true
);
result.relativePath = importPath;
result.classifiedName = importName;
const importsChanges = addImportToModule(
result.source,
appModulePath,
result.classifiedName,
result.relativePath
);
const importRecorder = tree.beginUpdate(appModulePath);
for (const change of importsChanges) {
if (change instanceof InsertChange) {
importRecorder.insertLeft(change.pos, change.toAdd);
}
}
tree.commitUpdate(importRecorder);
return tree;
}
在 return 规则的其他函数之一的末尾,在我对 chain([]) 的调用中......,我这样调用了这个函数(我需要添加HttpClientModule 导入,如果用户在选项 x 提示期间安装了 flex 布局,我也需要将 FlexLayoutModule 添加到导入中。
还有多个其他实用函数,例如 addDependencyToModule、addExportToModule 等,可用于调整您的任何 module.ts 文件
来电:
tree = _addImport(
'@angular/common/http',
'HttpClientModule',
_options,
tree
);
if (_options.dependencies.includes('flexLayout')) {
tree = _addImport(
'@angular/flex-layout',
'FlexLayoutModule',
_options,
tree
);
}
return tree;
这成功地将两个模块添加到我的导入中:[] in app.module,以及顶部的导入语句。还有一个实用函数 'buildRelativePath' 来自 '@schematics/angular/utility/find-module,如果您需要从您正在使用的模块所在的位置构建相对路径,它会有所帮助。
在 Angular 中使用 Schematics 生成组件时,它会尝试将新生成的组件导入到 NgModule 中,这是强制性的,以便组件工作并节省时间。
但是,在创建我自己的原理图时,我无法找到正确的方法来执行相同的操作并将我的库导入 app.component.ts 的 NgModule。使用 ng-add schematics 时,如何让 schematic 自动添加自己的条目到 NgModule?
原理图需要做两件事:
- 导入库
- 将其添加到 NgModule 导入中
之前:
@NgModule({
declarations: [],
imports: [],
exports: []
})
export class appModule { }
之后:
import {library} from 'library';
@NgModule({
declarations: [],
imports: [library],
exports: []
})
export class appModule { }
我知道 angular devkit 中存在执行此操作的功能,因为组件的 "official" 原理图等使用它。我该怎么做?
对于第一种情况,类似下面的代码可以帮助您:
export function addImportStatement(tree: Tree, filePath: string, type: string, file: string): void {
let source = getTsSourceFile(tree, filePath);
const importChange = insertImport(source, filePath, type, file) as InsertChange;
if (!(importChange instanceof NoopChange)) {
const recorder = tree.beginUpdate(filePath);
recorder.insertLeft(importChange.pos, importChange.toAdd);
tree.commitUpdate(recorder);
}
}
对于第二个,我现在不记得了,但你可以查看 angular-cli schematics 存储库,以了解它是如何为模块之类的东西完成的。
干杯!
这是一个使用来自“@schematics/angular/utility/ast-utils”实用程序的'addImportToModule'函数的函数..
function _addImport(
importPath: string,
importName: string,
_options: Partial<Schema>,
tree: Tree
): Tree {
const appModulePath = `/${_options.projectName}/src/app/app.module.ts`;
const appModuleFile = tree.read(normalize(appModulePath)).toString('utf-8');
if (!appModuleFile) {
throw new SchematicsException('app.module.ts not found');
}
const result = new AddToModuleContext();
result.source = ts.createSourceFile(
appModulePath,
appModuleFile,
ts.ScriptTarget.Latest,
true
);
result.relativePath = importPath;
result.classifiedName = importName;
const importsChanges = addImportToModule(
result.source,
appModulePath,
result.classifiedName,
result.relativePath
);
const importRecorder = tree.beginUpdate(appModulePath);
for (const change of importsChanges) {
if (change instanceof InsertChange) {
importRecorder.insertLeft(change.pos, change.toAdd);
}
}
tree.commitUpdate(importRecorder);
return tree;
}
在 return 规则的其他函数之一的末尾,在我对 chain([]) 的调用中......,我这样调用了这个函数(我需要添加HttpClientModule 导入,如果用户在选项 x 提示期间安装了 flex 布局,我也需要将 FlexLayoutModule 添加到导入中。 还有多个其他实用函数,例如 addDependencyToModule、addExportToModule 等,可用于调整您的任何 module.ts 文件
来电:
tree = _addImport(
'@angular/common/http',
'HttpClientModule',
_options,
tree
);
if (_options.dependencies.includes('flexLayout')) {
tree = _addImport(
'@angular/flex-layout',
'FlexLayoutModule',
_options,
tree
);
}
return tree;
这成功地将两个模块添加到我的导入中:[] in app.module,以及顶部的导入语句。还有一个实用函数 'buildRelativePath' 来自 '@schematics/angular/utility/find-module,如果您需要从您正在使用的模块所在的位置构建相对路径,它会有所帮助。