Búsqueda de sitios web

typescript - Angular Schematics - agregar biblioteca a las importaciones de NgModule


Al usar Schematics para generar componentes en Angular, intentará importar el componente recién generado en el NgModule, esto es obligatorio para que el componente funcione y ahorra tiempo.

Sin embargo, al crear mis propios esquemas, no puedo encontrar una manera correcta de hacer lo mismo e importar mi biblioteca en el NgModule de app.component.ts. Al usar los esquemas ng-add, ¿cómo se puede hacer que el esquema agregue automáticamente su propia entrada en el NgModule?

El esquema necesita hacer dos cosas:

  1. Importa la biblioteca
  2. Agrégalo a las importaciones de NgModule

Antes :

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

Después de :

import {library} from 'library';

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

Sé que existe una función para hacer esto en el angular devkit porque los esquemas "oficiales" para componentes y demás la usan. ¿Cómo haría lo mismo?

Respuesta #1

Para el primer caso, algo como el código a continuación te ayudará:

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);
    }
}

Para el segundo, no recuerdo en este momento, pero puedes consultar el repositorio de esquemas de angular-cli para ver cómo se hace para cosas como los módulos.

¡Salud!

Respuesta #2

Aquí hay una función que utiliza la función 'addImportToModule' de los utilitarios de `@schematics/angular/utility/ast-utils`.

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;
}

Al final de una de mis otras funciones que devuelven una Regla, dentro de mi llamada a chain([])....., llamé a esta función así (necesitaba agregar HttpClientModule a los imports, y si el usuario había instalado flex layout durante las opciones x-prompts, también necesitaba agregar FlexLayoutModule a los imports. Hay múltiples otras funciones utilitarias como addDependencyToModule, addExportToModule, etc., que se pueden usar para modificar cualquiera de tus archivos module.ts)

la llamada:

tree = _addImport(
      '@angular/common/http',
      'HttpClientModule',
      _options,
      tree
    );
    if (_options.dependencies.includes('flexLayout')) {
      tree = _addImport(
        '@angular/flex-layout',
        'FlexLayoutModule',
        _options,
        tree
      );
    }
    return tree;

Esto agregó con éxito ambos módulos a mis importaciones: [] en app.module, así como las declaraciones de importación en la parte superior. También hay una función de utilidad 'buildRelativePath' de '@schematics/angular/utility/find-module', que puede ayudar si necesitas construir rutas relativas desde donde se encuentre el módulo con el que estás trabajando.