yeoman生成器中的ComposeWith不发出结束事件,因此不驱动“打开"方法 [英] ComposeWith in yeoman generator not emitting an end event and thus not driving 'on' method

查看:294
本文介绍了yeoman生成器中的ComposeWith不发出结束事件,因此不驱动“打开"方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Angular SPA(单页应用程序)创建一个脚手架生成器.它将依赖于标准角度生成器("yo angle")设置的环境,还依赖于标准角度子生成器来生成该应用程序所需的一些额外服务和控制器.换句话说,我在装饰"自己的东西.基本的角度应用程序.

I am creating a scaffolding generator for an Angular SPA (single page application). It will rely on the environment set up by the standard angular generator ('yo angular'), and also rely on the standard angular subgenerators to generate a few extra services and controllers necessary to the app. In other words, I'm "decorating" a basic angular app.

如果用户先前已经安装了角度应用程序(我会寻找标记文件并在我的代码中设置booleon'angularAppFound'),则生成器将正常工作.但是,我希望它也是一站式"的,因为如果尚未安装角度应用程序,则在我安装其他角度工件之前,我的生成器将为他们调用角度生成器在一次运行中.

The generator will work fine if the user has previously installed an angular app (I look for marker files and set a booleon 'angularAppFound' in my code). However, I would like it to also be 'one-stop', in that if they don't have an angular app already set up, my generator will call the angular generator for them, before I install my additional angular artifacts within a single run.

很显然,如果没有适当的角度应用程序,我的从属任务将无法正常工作.

Obviously, my dependent tasks will not work if an angular app is not in place.

我的代码如下:

  // 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'会驱动.

I have empirically determined, by looking at the log and by outcome, that 'composeWith' does not drive the .on method, and 'invoke' does.

如果未驱动.on方法,则不会驱动done(),并且生成器在安装角度基座后停止,并且不驱动后续步骤(因为生成器认为该步骤永不结束).

If the .on method is not driven, done() is not driven, and the generator stops after the angular base install and does not drive the subsequent steps (because the generator thinks the step never finishes).

除了已弃用,我可以使用invoke很好

I'm fine using invoke, except it's deprecated:

(!) generator#invoke() is deprecated. Use generator#composeWith() - see http://yeoman.io/authoring/composability.html

问题

我已在此处此处,生成器不应相互依赖:

Questions

I have read here and here that generators shouldn't be dependent on each other:

组成发电机时,核心思想是使两者保持解耦状态.他们不应该在乎顺序,它们应该以任何顺序运行并输出相同的结果.

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.

既然订购 很重要(而不是使用调用"),那么我应该如何处理自己的情况?在不牺牲一站式"处理的情况下,我想不出其他任何方法来重新组织生成器.

How should I then deal with my situation, since ordering is important (other than using 'invoke')? I can't think of any other way to re-organize my generator without sacrificing 'one-stop' processing.

我应该简单地说,用户必须在单独的步骤中安装角度组件,并且不允许一站式"处理吗?

Should I simply say that user has to install angular in a separate step and not allow for 'one stop' processing?

设计上不是'composeWith'不发出'end'事件吗?

Is it by design that 'composeWith' does not emit an 'end' event?

如果没有,您是否建议我打开错误报告,或者是否有其他方法可以做到这一点(不推荐使用)?

If not, do you recommend I open a bug report, or is there some other way to do it (that is not deprecated)?

非常感谢.

推荐答案

使用优先级基本运行循环.因此,在运行您的发电机之前,可以等待另一台发电机完成.

Generator composability is ordered using a priority base run loop. As so, it is kind of possible to wait for another generator to be done before running yours.

尽管这里最棘手的部分是,一旦触发了结束事件,生成器就完成了运行.它不会安排任何将来的任务-end事件意味着一切都已完成,是时候结束了.公平地说,您不需要结束事件.它仍在Yeoman中,仅用于向后兼容.

Although the tricky part here is that, once the end event is triggered, the generator is done running. It won't schedule any future task - the end events means everything is done and it's time to wrap up. To be fair, you shouldn't need the end event. It's still in Yeoman for backward compatibility only.

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

In your case, you want two generator. The app generator (the root one) and your custom functionality generator. Then you compose them together:

因此,在generator/app/index.js内部,您将按以下方式组织代码:

So inside of generator/app/index.js, you'll organize your code as follow:

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

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

生成器角度很大且相当复杂.它仍然基于Yeoman的旧版本,这意味着将其用作基本生成器可能会更加困难.我敢肯定,项目的所有者很乐意为您提供一些帮助,以升级和改善作品故事. -如果您想了解更适合开发者UX的用户界面,请查看 generator-node 被设计为合成的基础生成器.

The generator-angular is huge and fairly complex. It is still based on an old version of Yeoman, which means it can be harder to use it as a base generator. I'm sure the owners of the projects would be happy to have some help to upgrade and improve the composition story. - If you wonder what a better developper UX can looks like for Yeoman composition, take a look at generator-node who've been designed as a base generator for composition.

这篇关于yeoman生成器中的ComposeWith不发出结束事件,因此不驱动“打开"方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆