【问题标题】:Efficient and simplest way to insert template based content into generated files with Yeoman generator使用 Yeoman 生成器将基于模板的内容插入到生成的文件中的有效且最简单的方法
【发布时间】:2017-01-31 12:39:47
【问题描述】:

假设我已经有一些由生成器生成的文件,并且想要创建一些子生成器,它们根据某些内容的模板将内容插入到这些文件中。

目标是创建一个由 3 层组成的多层架构的生成器(对于用 typescript 编写的 Angular2 应用程序):

  • 应用层
  • metier 层和
  • 业务代理层

对于每一层,主生成器必须生成构成它的所有文件:模块文件,接口文件,......在这个过程中生成的主要3个文件如下所示:

hero.applicif.ts

import { Injectable } from '@angular/core';
import { IHeroApplicatif } from './hero.applicatif.interface';
import { HeroMetier } from '../metier/hero.metier';
@Injectable()
export class HeroApplicatif implements IHeroApplicatif {
    constructor(private heroMetier: HeroMetier) {}
}

hero.metier.ts

import { Injectable } from '@angular/core';
import { IHeroMetier } from './hero.metier.interface';
import { HeroBusinessDelegate } from '../business-delegate/hero.business-delegate';
@Injectable()
export class HeroMetier implements IHeroMetier {
    constructor(private heroBusinessDelegate: HeroBusinessDelegate) {}
}

hero.business-delegate.ts

import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import { IHeroBusinessDelegate } from './hero.business-delegate.interface';
@Injectable()
export class HeroBusinessDelegate implements IHeroBusinessDelegate {
    constructor(private http: Http) {}
}

基于模板生成这些文件不会造成问题。但我想要提示用户输入方法名称的子生成器,它是返回类型和参数,因此子生成器必须修改每个先前生成的文件以插入代码,默认情况下,对于每一层,将调用传递给下一层。

假设子生成器提示用户输入一个名为getHero的方法,这3个文件的内容要这样修改:

hero.applicif.ts

import { Injectable } from '@angular/core';
import { IHeroApplicatif } from './hero.applicatif.interface';
import { HeroMetier } from '../metier/hero.metier';
@Injectable()
export class HeroApplicatif implements IHeroApplicatif {
    constructor(private heroMetier: HeroMetier) {}
    getHero(id:number): Promise<any> {
        return this.heroMetier.getHero(id);
    }
}

hero.metier.ts

import { Injectable } from '@angular/core';
import { IHeroMetier } from './hero.metier.interface';
import { HeroBusinessDelegate } from '../business-delegate/hero.business-delegate';
@Injectable()
export class HeroMetier implements IHeroMetier {
    constructor(private heroBusinessDelegate: HeroBusinessDelegate) {}
    getHero(id:number): Promise<any> {
        return this.heroBusinessDelegate.getHero(id);        
    }
}

hero.business-delegate.ts

import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import { IHeroBusinessDelegate } from './hero.business-delegate.interface';
@Injectable()
export class HeroBusinessDelegate implements IHeroBusinessDelegate {
    constructor(private http: Http) {}
    getHero(id:number): Promise<any> {
        return this.http.get(...).toPromise();
    }
}

最简单、安全、最新的方法是什么?

【问题讨论】:

  • 您想在什么文件中插入内容?请提供一个示例:您要插入新内容的文件内容+您要插入的内容
  • @SimonBoudrias 好的,我将编辑帖子以提供示例
  • @SimonBoudrias 现在在帖子中提供了一些文件示例

标签: yeoman yeoman-generator multi-layer


【解决方案1】:

要以一种不会干扰最终用户未预料到的更改的安全方式编辑代码文件内容,最安全的方法是修改文件Abstract Syntax Tree

Node 有多个 AST 解析器可用。最受欢迎的两个是EsprimaAcorn。还有一些基于这些解析器的工具可以更轻松地修改 AST。

如果您想检查一下https://github.com/SBoudrias/AST-query,我不久前就编写了这样一个工具 - 它可能适用于您的用例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    相关资源
    最近更新 更多