node.js - yeoman 生成器中的 ComposeWith 不发出结束事件,因此不驱动 'on' 方法

原文 标签 node.js yeoman yeoman-generator yeoman-generator-angular

背景
我正在为 Angular SPA(单页应用程序)创建一个脚手架生成器。它将依赖于标准角度生成器('yo angular')设置的环境,并且还依赖于标准角度子生成器来生成应用程序所需的一些额外服务和 Controller 。换句话说,我正在“装饰”一个基本的 Angular 应用程序。
如果用户之前安装了 Angular 应用程序(我查找标记文件并在我的代码中设置 bool 值“angularAppFound”),生成器将正常工作。但是,我希望它也是“一站式”的,因为如果他们还没有设置角度应用程序,我的生成器将为他们调用角度生成器,然后再将我的其他角度工件安装在单个跑。
显然,如果没有角度应用程序,我的依赖任务将无法工作。
数据
我的代码如下所示:

  // need this to complete before running other task
  subgeneratorsApp: function () {    
      if (!this.angularAppFound) {
        var done = this.async();

        this.log('now creating base Angular app...');
        // doesn't work (does not drive .on)
        //this.composeWith('angular',  {args: [ this.appName ]} )
        // works (drives .on)
        this.invoke('angular',  {args: [ this.appName ]} )
         .on('end',function(){
                        this.log('>>>in end handler of angular base install');
                        done();
                    }.bind(this));
        
      }    
  },

  // additional steps to only run after full angular install
  subgeneratorServices: function () {
    Object.keys(this.artifacts.services).forEach( function (key, index, array) {
      this.composeWith('angular:service',  {args: [ this.artifacts.services[key] ]} );
    }.bind(this));
  },

  subgeneratorControllers: function () {
    Object.keys(this.artifacts.controllers).forEach( function (key, index, array) {
      this.composeWith('angular:controller',  {args: [ this.artifacts.controllers[key] ]} );
    }.bind(this));
  },
通过查看日志和结果,我凭经验确定 'composeWith' 不会驱动 .on 方法,而 'invoke' 会。
如果 .on 方法没有被驱动,done() 也不会被驱动,并且生成器在 angular base install 之后停止并且不会驱动后续步骤(因为生成器认为该步骤永远不会完成)。
我很好用调用,除了它已被弃用:
(!) generator#invoke() is deprecated. Use generator#composeWith() - see http://yeoman.io/authoring/composability.html
问题
我已阅读 herehere生成器不应相互依赖:

When composing generators, the core idea is to keep both decoupled. They shouldn't care about the ordering, they should run in any order and output the same result.


那么我应该如何处理我的情况,因为排序很重要(除了使用'invoke')?在不牺牲“一站式”处理的情况下,我想不出任何其他方式来重新组织我的生成器。
我应该简单地说用户必须在单独的步骤中安装 Angular 并且不允许“一站式”处理吗?
'composeWith' 不会发出 'end' 事件是设计使然吗?
如果没有,您是否建议我打开错误报告,或者是否有其他方法(不推荐使用)?
非常感谢。

最佳答案

使用 priority base run loop 订购生成器可组合性.因此,在运行您的生成器之前等待另一个生成器完成是可能的。

尽管这里的棘手部分是,一旦触发结束事件,生成器就完成运行。它不会安排任何 future 的任务 - end事件意味着一切都已经完成,是时候结束了。公平地说,你不应该需要结束事件。它仍然在 Yeoman 中,只是为了向后兼容。

在您的情况下,您需要两个发电机。 app生成器(根)和您的自定义功能生成器。然后将它们组合在一起:

所以里面generator/app/index.js ,您将按如下方式组织您的代码:

writing: {
  this.composeWith('angular:app');
},

end: function () {
  this.composeWith('my:subgen');
}

生成器角度巨大且相当复杂。它仍然基于旧版本的 Yeoman,这意味着将其用作基础生成器可能会更困难。我相信这些项目的所有者会很高兴得到一些帮助来升级和改进构图故事。 - 如果您想知道 Yeoman 组合的更好的开发人员 UX 是什么样的,请查看 generator-node谁被设计为合成的基础生成器。

关于node.js - yeoman 生成器中的 ComposeWith 不发出结束事件,因此不驱动 'on' 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33010498/

相关文章:

javascript - 错误 : EACCES, 命令 #yo angular 中的权限被拒绝

node.js - Yeoman 生成器在发布到 npm 后不包含子生成器

node.js - 在nodejs中包含对象

javascript - 当错误可能未包含在 promise 中时,我如何使用 promise 来捕获错误?

javascript - 将范围绑定(bind)到 forEach 循环中的项目

javascript - Yeoman + Grunticon : Gruntfile. js 问题

node.js - nodejs中stdin的结束进程

javascript - 安装Yeeoman Gulp-Angular项目后,单元测试中出现错误

angularjs - 使用grunt进行构建时,dist中没有 View

node.js - 与Yeoman/Grunt建立Jade进行模板制作的正确方法