简体   繁体   中英

How to write files into the app tree in ember-cli preprocessTree hook

I have a broccoli plugin which does the following:

  • Read json file from root folder
  • based on the JSON generate some route template HBS files

This works perfectly and can also be acceptance tested by triggering a broccoli build.

Example result of the broccoli build:

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

The next phase is integrating it into an ember-addon, and I created one with a preprocessTree hook.

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;
  }
};

The problem with above solution is that the trees cannot be merged if no destDir is passed. The ember-app tree is prefixed with the application name, eg:

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

When calling this addon immediately from a ember-app the app.options.trees.app will work, however when this addon is called as dependency from another addon, the parameter in the included hook gets an addon object which doesn't have the app tree name.

So the question is, how do I write files to an app tree the right way?

In most addons where this is needed there is a block of code like

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;
},

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

There is also a private method this._findHost() that does this, but it isn't available in all versions of ember-cli (and is private).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM