2

在 Angular 中使用 Schematics 生成组件时,它会尝试将新生成的组件导入到 NgModule 中,这是强制性的,以便组件工作并节省时间。

但是,在创建自己的原理图时,我找不到正确的方法来做同样的事情并将我的库导入 app.component.ts 的 NgModule。使用 ng-add 原理图时,如何让原理图自动将自己的条目添加到 NgModule 中?

原理图需要做两件事:

  1. 导入库
  2. 将其添加到 NgModule 导入

前:

@NgModule({
  declarations: [],
  imports: [],
  exports: []
})
export class appModule { }

后:

import {library} from 'library';

@NgModule({
  declarations: [],
  imports: [library],
  exports: []
})
export class appModule { }

我知道 angular devkit 中存在执行此操作的功能,因为组件的“官方”原理图等使用它。我该怎么做?

4

2 回答 2

5

对于第一种情况,类似下面的代码将帮助您:

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 原理图存储库,以了解它是如何为诸如模块之类的东西完成的。

干杯!

于 2020-01-07T14:46:50.447 回答
2

这是一个使用来自 `@schematics/angular/utility/ast-utils' 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;
}

在我的其他返回规则的函数之一的末尾,在我对链([])的调用中,我这样调用了这个函数(我需要将 HttpClientModule 添加到导入中,如果用户安装了在选项 x-prompts 期间进行 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;

这成功地将两个模块添加到我的导入中:app.module 中的 [] 以及顶部的导入语句。还有一个来自“@schemics/angular/utility/find-module”的实用函数“buildRelativePath”,如果您需要从您正在使用的模块所在的任何位置构建相对路径,它可以提供帮助。

于 2021-10-07T23:27:34.123 回答