【问题标题】:Yeoman generator add a new file generated exsiting projectYeoman 生成器添加新文件生成现有项目
【发布时间】:2020-10-02 11:45:47
【问题描述】:

我有 yeoman 生成器,它成功生成了一个简单的 sproject。

我希望项目生成之后,以后用户可以在app文件夹下生成一个新文件deployment.yaml,但是它需要读取一些数据从主发电机 例如appName 作为子生成器需要生成一个新文件 在生成的应用程序中。

例如yo tdk

此命令生成一个新项目

当我运行yo tdk:event(或类似的东西)时,它会在项目app文件夹中生成一个新文件

为了说明,我创建了这个非常简单的生成器

const Generator = require("yeoman-generator");

module.exports = class extends Generator {
  prompting() {
    this.props = {
      appName: "my-app",
      srvName: "my-service"
    };

    const prompts = [
      {
        name: "appName",
        message: "Project name: ",
        type: "input",
        default: this.props.appName
      },
      {
        name: "srvName",
        message: "Service name: ",
        type: "input",
        default: this.props.srvName
      }
    ];

    return this.prompt(prompts).then(props => {
      this.props = props;
    });
  }

  writing() {
    this.fs.copyTpl(
      this.templatePath("app"),
      this.destinationPath(this.props.appName),
      this.props
    );
  }
};

这个生成器有两个简单的问题

  1. 应用名称
  2. 服务名称

它会生成一个类似的项目

myapp   /root
 -app   /folder
  - service.yaml   /single file at the project generation

生成的service.yaml 如下所示:

apiVersion: v1
kind: Service
metadata:
  name: <%= appName %>
spec:
  selector:
    app: <%= srvName %>
  ports:
    - protocol: TCP
      port: 80

现在使用此service.yaml 文件生成项目后 我想在后期(项目生成后)在app文件夹下添加新文件deployment.yaml

deployment.yaml

apiVersion: v1
kind: Deployment
metadata:
  name: <%= appName %>  //this is the appname from the project generation

spec:
  replicas: <%= replica %>
  selector:
    app: <%= srvName %>

appName & srvName 来自主生成器, (我看到有在子生成器之间共享数据的选项 https://yeoman.io/authoring/storage.html,不知道如何在生成器之间共享) replica 应该来自新的/子生成器

这是生成后的项目结构

myapp   /root
 -app   /folder
  - service.yaml      /single file at the project generation
  - deployment.yaml   / new file added to the project under app folder

就像用户开始另一个 generator/sub 并有一个新问题,例如how much replicas do you want? 然后生成文件。

我该怎么做?

更新 这是我的项目结构

myapp
 - node_modules
 - package.json //here I declare the main-generator command -> tdk
 - generators
 -- app
 ---index.ts
 --deployment
 ---index.ts
 ---package.json    //here I declare the sub-generator command -> deploy
 - node_modules
 - package.json
 -.yo-rc.json       //here I see the data that I keep via config.set api

更新

当我通过像

这样的程序调用子生成器时

const yeoman = require('yeoman-environment'); const env = yeoman.createEnv();

env.lookup(function () {
    env.run("tdk:deploy", {
        replicas: 100
    }, (err) => {
        console.log("done", err);
    });
});

我收到错误:

out from config undefined : undefined //未定义来自子生成器中的控制台

done TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined
    at validateString (internal/validators.js:125:11)
    at Object.join (path.js:1037:7)

我在子生成器代码中放了一个console.log

  initializing() {
    this.srvName = this.config.get("srvName");
    this.appName = this.config.get("appName");
    console.log("out from config", this.srvName, ":", this.appName);
  }

当我运行子生成器时,我得到了空配置(来自.yo-rc.json) 在检查 .yo-rc.json 时。我能够看到来自主生成器的条目,数据已存储,但是当我从程序运行它时,它没有找到它......任何想法?

这是两个项目的链接(演示这一点的非常基本的 yeoman 生成器)只需要为两个项目运行 npm install 对于生成器,还要运行npm link

最后:应该用两个文件

生成一个项目
1. service.yaml   // generated from the main generator
2. deployment.yaml - // generated from sub generator with the properties from the main & sub generator

目前没有生成deployment.yaml文件

https://drive.google.com/drive/folders/1kBnZxpVcRR9qhGZagVtod7W4wFmt73C6

1 . generator-tdk -  Generator and sub-generator 
2.  yeomanEnv - The code which is running the sub-generator to create the file inside the generated project

我做错了什么? :(

如果子生成器有办法读取.yo-rc.json,它可以提供帮助

【问题讨论】:

    标签: javascript node.js typescript yeoman yeoman-generator


    【解决方案1】:

    您可以像这样在主生成器的configuring 中设置配置值:

    configuring() {
      this.config.set('appName', this.props.appName);
      this.config.set('srvName', this.props.srvName);
    }
    

    并读取子生成器中的值:

    initializing() {
      this.srvName = this.config.get("srvName");
      this.appName = this.config.get("appName");
    }
    

    因此,您可以在编写时通过this.srvNamethis.appName 访问这些值。

    示例代码:

    app/index.js:

    const Generator = require("yeoman-generator");
    
    module.exports = class extends Generator {
      prompting() {
        this.props = {
          appName: "my-app",
          srvName: "my-service",
        };
    
        const prompts = [
          {
            name: "appName",
            message: "Project name: ",
            type: "input",
            default: this.props.appName,
          },
          {
            name: "srvName",
            message: "Service name: ",
            type: "input",
            default: this.props.srvName,
          },
        ];
    
        return this.prompt(prompts).then((props) => {
          this.props = props;
        });
      }
    
      configuring() {
        this.config.set('appName', this.props.appName);
        this.config.set('srvName', this.props.srvName);
      }
    
      writing() {
        this.fs.copyTpl(
          this.templatePath("app"),
          this.destinationPath(this.props.appName),
          this.props
        );
      }
    };
    

    部署/index.js:

    const Generator = require("yeoman-generator");
    
    module.exports = class extends Generator {
      initializing() {
        this.srvName = this.config.get("srvName");
        this.appName = this.config.get("appName");
      }
    
      prompting() {
        this.props = {
          replicas: 0,
        };
    
        const prompts = [
          {
            name: "replica",
            message: "how much replicas do you want?",
            type: "input",
            default: this.props.replicas,
          },
        ];
    
        return this.prompt(prompts).then((props) => {
          this.props = props;
        });
      }
    
      writing() {
        this.fs.copyTpl(
          this.templatePath("deploy"),
          this.destinationPath(this.appName),
          {
            srvName: this.srvName,
            appName: this.appName,
            ...this.props,
          }
        );
      }
    };
    
    

    和命令:

    yo &lt;name 用于主项目生成

    yo &lt;name&gt;:deploy 请求副本并创建deployment.yaml


    不使用yo执行子生成器:

    var yeoman = require("yeoman-environment");
    var env = yeoman.createEnv();
    
    env.lookup(function () {
      env.run("<name>:deploy", {
          replicas: 100
      }, (err) => {
        console.log("done", err);
      });
    });
    

    还有一个示例子生成器,如果值是通过选项传递的,则跳过问题 (deploy/index.js):

    const Generator = require("yeoman-generator");
    
    module.exports = class extends Generator {
      initializing() {
        this.srvName = this.config.get("srvName");
        this.appName = this.config.get("appName");
      }
    
      prompting() {
        this.props = {
          replicas: 0,
        };
    
        const prompts = [
          {
            name: "replicas",
            message: "which app to generate?",
            type: "input",
            default: this.props.replicas,
            when: !this.options.replicas, // disable the question if it's found in options
          },
        ];
    
        return this.prompt(prompts).then((props) => {
          this.props = props;
    
          // set values from options (if found)
          this.props.replicas = this.options.replicas || this.props.replicas;
        });
      }
    
    
      writing() {
        this.fs.copyTpl(
          this.templatePath("deploy"),
          this.destinationPath(this.appName),
          {
            srvName: this.srvName,
            appName: this.appName,
            ...this.props,
          }
        );
      }
    };
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多