nitayneeman / schematics-utilities

🛠️ Useful exported utilities for working with Schematics
https://nitayneeman.github.io/schematics-utilities
MIT License
87 stars 9 forks source link

addDeclarationToModule says "UPDATE" but the update does not occur #26

Open raul1991 opened 4 years ago

raul1991 commented 4 years ago

I have written the following code by peeking into the angular/schematics/component/index.js code

const declarationChanges = addDeclarationToModule(sourceFile, newLocal, `List${strings.classify(_options.name)}Component`, `./components/general-configuration/${dasherize(_options.name)}/list/list-${dasherize(_options.name)}.component`);
    const declarationRecorder = tree.beginUpdate(newLocal);
    for (const change of declarationChanges) {
        if (change instanceof InsertChange) {
            _context.logger.info(change.toAdd);
            declarationRecorder.insertLeft(change.pos, change.toAdd);
        }
    }
    tree.commitUpdate(declarationRecorder);

I get the following output UPDATE src/app/app.module.ts (1959 bytes) but the file still has no changes in it. Any idea what's going wrong here ?

dipaktelangre commented 4 years ago

I have imported same function from @schematics/angular instead of schematics-utilities and now its working.

import {
  addProviderToModule,
  addImportToModule,
} from "@schematics/angular/utility/ast-utils";
raul1991 commented 4 years ago

@dipaktelangre That is a better way to do it.

Although, I found a work around which is to explicitly cast change into InsertChange and then the changes occur,

dipaktelangre commented 4 years ago

@raul1991 It would have been better if shared working code here.

arawinters commented 4 years ago

must be on the edge of things. I can't find a single working/modern example of using @schematics/angular/utility/ast-utils#addImportToModule

raul1991 commented 4 years ago

@arawinters https://ithelp.ithome.com.tw/m/articles/10222385

Will share how I did it in a while till then read the above article.

raul1991 commented 3 years ago

@dipaktelangre I don't know if this still helps or not but I totally forgot about this issue.

Here is how I did it.


function addProviders(tree: Tree, _options: Schema): Tree {
  const routerModule = PATH_TO_ROUTE_CONFIG_FILE;
  const source = parser.readAsSourceFile(routerModule);
  const providerLiteral = `,\n\t\t${classify(_options.name)}Service`;
  // find the providers array todo: correct this
  const providers = findNodes(source, ts.SyntaxKind.Identifier).filter(n => n.getText() === 'providers');
  const changes = insertAfterLastOccurrence(providers.pop()?.parent?.getChildren()!, providerLiteral, routerModule, 0, ts.SyntaxKind.Identifier);
  // const changes = addProviderToModule(source, routerModule, provider.name, provider.path);
  const declarationRecorder = tree.beginUpdate(routerModule);
  declarationRecorder.insertLeft((<InsertChange>changes).pos, (<InsertChange>changes).toAdd);
  tree.commitUpdate(declarationRecorder);
  // add imports 
  const imports = `\nimport { ${_options.name}Service } from '../services/entities/${dasherize(_options.name)}.service';\n`
  const importChange = <InsertChange>insertAfterLastOccurrence(source.getChildren(), imports, PATH_TO_ROUTE_CONFIG_FILE, 0, ts.SyntaxKind.ImportDeclaration);
  const importRecorder = tree.beginUpdate(PATH_TO_ROUTE_CONFIG_FILE);
  importRecorder.insertLeft(importChange.pos, importChange.toAdd);
  tree.commitUpdate(importRecorder);
  return tree;
}

The important part is that I am casting the change in Insert change because that is how it was coming to be ALWAYS! Its still fragile but worked for me.