1

我有一个花椰菜插件,它执行以下操作:

  • 从根文件夹读取 json 文件
  • 基于 JSON 生成一些路由模板 HBS 文件

这非常有效,也可以通过触发 broccoli 构建来进行验收测试。

broccoli 构建的示例结果:

templates/generated-route.hbs
templates/my-sub/generated.hbs

下一阶段是将它集成到一个 ember-addon 中,我用preprocessTree钩子创建了一个。

module.exports = {
  name: 'route-template-generator',

  included(app) {
    this._super.included.apply(this, arguments);

    this.options = Object.assign({}, app.options);
    this.appName = app.name;

    if (!this.options.trees) {
        throw new Error('No trees found in app to add the new files to');
    }
    if (!this.appName) {
        throw new Error('no valid application name, unable to add files to the tree');
    }
  },

  preprocessTree(type, tree) {
    if (type === 'template') {
      const extraTemplates = new RouteTemplateGenerator(
        [new Funnel(this.options.trees.app, { include: ['router.json'] })], 
        { destDir: this.appName }
      );

      return mergeTrees([tree, extraTemplates], { overwrite: true });
    }
    return tree;
  }
};

destDir上述解决方案的问题是,如果没有传递,则无法合并树。ember-app 树以应用程序名称为前缀,例如:

my-ember-app-name/templates/application.hbs
my-ember-app-name/router.js
...

当立即从 ember-app 调用此插件app.options.trees.app时,该插件将起作用,但是当此插件作为来自另一个插件的依赖项调用时,included钩子中的参数会获取一个没有应用程序树名称的插件对象。

所以问题是,我如何以正确的方式将文件写入应用程序树?

4

1 回答 1

0

在大多数需要这样做的插件中,都有一段代码,例如

included(app) {
  this._super.included.apply(this, arguments)
  let current = this;
  // Keep iterating upward until we don't have a grandparent.
  // Has to do this grandparent check because at some point we hit the project.
  do {
    app = current.app || app;
  } while (current.parent.parent && (current = current.parent));

  this.app = app;
},

来源:https ://github.com/FortAwesome/ember-fontawesome/blob/master/index.js#L158-L163

还有一个私有方法this._findHost()可以做到这一点,但它并非在所有版本的 ember-cli 中都可用(并且是私有的)。

于 2019-02-07T14:07:40.433 回答