Plugin without a source file


#1

Hello,

I have a source javascript file that should be generated when I build the ember application (using “ember server” for now). There is no source file of any type, the javascript file is generated by an external tool (based on an HTTP request, which doesn’t matter for this issue).

I wrote a plugin based on broccoli-writer that can successfully generate this file in the directory given on the function call. However, how can I integrate this into the app tree?

This is the relevant part of the plugin:

var Writer = require('broccoli-writer');
var rsvp = require('rsvp');
var exec = require('child_process').exec;

module.exports = MyGreatPlugin;
MyGreatPlugin.prototype = Object.create(Writer.prototype);
MyGreatPlugin.prototype.constructor = MyGreatPlugin;

function MyGreatPlugin(options) {
	if (!(this instanceof MyGreatPlugin)) {
		return new MyGreatPlugin(options);
	}
	this.options = options || {};
};
MyGreatPlugin.prototype.description = "my-great-plugin";
MyGreatPlugin.prototype.write = function(readTree, destDir) {
	var options = this.options;
	return new rsvp.Promise(function(resolvePromise, rejectPromise) {
		exec('…', function(error, stdout, stderr) {
			if(error) {
				rejectPromise(error);
			} else {
				resolvePromise(destDir + '/' + options.namespace + '.js');
			}
		});
	});
};

I tried supplying the tree as a parameter to app.toTree(), but then it’s part of the allTrees tree, not the one where the javascript files are compiled (and so, the require-call to that file fails). I tried supplying it to a separate outer call to mergeTrees, but it results in the same problem. btw, the write function isn’t even called, but I suspect that’s because the missing file error caused by require happens earlier in the tree already and it stops.

I looked through the code (since documentation is non-existing), and there’s a registry for getting trees into an earlier stage of the build. However, that registry requires a file extension to be supplied, and I have none to give.

Also, I’m not quite clear on what parameter I should supply to resolvePromise() above. I’m lead to believe that it doesn’t really matter, though.

Can anybody help me there?


#2

Make an addon (ember addon my-source-generator), have that addon return your broccoli-writer based tree from the treeForApp method. That tree is merged with the app and is available for import as if the files returned were actually inside app/ itself.


#3

Thank you, that gets me a step closer to the solution! Now my tree is actually compiled and included.

However, how can I pass options this way? For example, the options.namespace in my snippet above needs to be defined in Brocfile.js, but since the addon is run automatically, I can’t pass anything anywhere.

Also, the generated JavaScript code uses amd, but define.amd isn’t defined, so it fails. What’s the problem there? Some kind of amd version difference?

if (typeof define === 'function' && define.amd) {
  define([], MyGreatPlugin_Module_Factory);
}

(that wasn’t written by me, that’s how the code is generated by this external tool)