Add ability to load plugins from app
This commit is contained in:
parent
b0df4207c4
commit
fb03aff43a
|
@ -1,6 +1,8 @@
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
var utils = require('./utils');
|
var utils = require('./utils');
|
||||||
|
var path = require('path');
|
||||||
|
var pluginLoader = require('./plugin-loader');
|
||||||
var debug = require('debug')('loopback:boot:bootstrapper');
|
var debug = require('debug')('loopback:boot:bootstrapper');
|
||||||
var Promise = global.Promise || require('bluebird');
|
var Promise = global.Promise || require('bluebird');
|
||||||
|
|
||||||
|
@ -31,6 +33,17 @@ var builtinPhases = [
|
||||||
'load', 'compile', 'starting', 'start', 'started',
|
'load', 'compile', 'starting', 'start', 'started',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
function loadAndRegisterPlugins(bootstrapper, options) {
|
||||||
|
var loader = pluginLoader(options);
|
||||||
|
var loaderContext = {};
|
||||||
|
loader.load(loaderContext);
|
||||||
|
loader.compile(loaderContext);
|
||||||
|
|
||||||
|
for (var i in loaderContext.instructions.pluginScripts) {
|
||||||
|
bootstrapper.use('/boot/' + i, loaderContext.instructions.pluginScripts[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Bootstrapper with options
|
* Create a new Bootstrapper with options
|
||||||
* @param options
|
* @param options
|
||||||
|
@ -64,6 +77,12 @@ function Bootstrapper(options) {
|
||||||
var factory = require('./plugins/' + p);
|
var factory = require('./plugins/' + p);
|
||||||
self.use('/boot/' + p, factory(options));
|
self.use('/boot/' + p, factory(options));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
loadAndRegisterPlugins(self, options);
|
||||||
|
} catch (err) {
|
||||||
|
debug(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,6 +15,7 @@ var g = require('strong-globalize')();
|
||||||
* @param {Object} bundler A browserify object created by `browserify()`.
|
* @param {Object} bundler A browserify object created by `browserify()`.
|
||||||
*/
|
*/
|
||||||
module.exports = function addInstructionsToBrowserify(context, bundler) {
|
module.exports = function addInstructionsToBrowserify(context, bundler) {
|
||||||
|
// bundlePluginScripts(context, bundler);
|
||||||
bundleModelScripts(context, bundler);
|
bundleModelScripts(context, bundler);
|
||||||
bundleMixinScripts(context, bundler);
|
bundleMixinScripts(context, bundler);
|
||||||
bundleComponentScripts(context, bundler);
|
bundleComponentScripts(context, bundler);
|
||||||
|
@ -27,6 +28,11 @@ function bundleOtherScripts(context, bundler) {
|
||||||
addScriptsToBundle('boot', list, bundler);
|
addScriptsToBundle('boot', list, bundler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bundlePluginScripts(context, bundler) {
|
||||||
|
var list = context.instructions.pluginScripts;
|
||||||
|
addScriptsToBundle('plugins', list, bundler);
|
||||||
|
}
|
||||||
|
|
||||||
function bundleModelScripts(context, bundler) {
|
function bundleModelScripts(context, bundler) {
|
||||||
bundleSourceFiles(context, 'models', bundler);
|
bundleSourceFiles(context, 'models', bundler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
var util = require('util');
|
||||||
|
var utils = require('./utils');
|
||||||
|
var path = require('path');
|
||||||
|
var async = require('async');
|
||||||
|
var debug = require('debug')('loopback:boot:plugin-loader');
|
||||||
|
var PluginBase = require('./plugin-base');
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
module.exports = function(options) {
|
||||||
|
return new PluginScript(options);
|
||||||
|
};
|
||||||
|
|
||||||
|
function PluginScript(options) {
|
||||||
|
PluginBase.call(this, options, 'pluginScripts', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
util.inherits(PluginScript, PluginBase);
|
||||||
|
|
||||||
|
PluginScript.prototype.load = function(context) {
|
||||||
|
var options = this.options;
|
||||||
|
var appRootDir = options.rootDir;
|
||||||
|
// require directories
|
||||||
|
var pluginDirs = options.pluginDirs || []; // precedence
|
||||||
|
pluginDirs = pluginDirs.concat(path.join(appRootDir, 'plugins'));
|
||||||
|
utils.resolveRelativePaths(pluginDirs, appRootDir);
|
||||||
|
|
||||||
|
var pluginScripts = options.pluginScripts || [];
|
||||||
|
utils.resolveRelativePaths(pluginScripts, appRootDir);
|
||||||
|
|
||||||
|
pluginDirs.forEach(function(dir) {
|
||||||
|
pluginScripts = pluginScripts.concat(utils.findScripts(dir));
|
||||||
|
var envdir = dir + '/' + options.env;
|
||||||
|
pluginScripts = pluginScripts.concat(utils.findScripts(envdir));
|
||||||
|
});
|
||||||
|
|
||||||
|
// de-dedup boot scripts -ERS
|
||||||
|
// https://github.com/strongloop/loopback-boot/issues/64
|
||||||
|
pluginScripts = _.uniq(pluginScripts);
|
||||||
|
debug('Plugin scripts: %j', pluginScripts);
|
||||||
|
this.configure(context, pluginScripts);
|
||||||
|
return pluginScripts;
|
||||||
|
};
|
||||||
|
|
||||||
|
PluginScript.prototype.compile = function(context) {
|
||||||
|
var pluginScripts = context.configurations.pluginScripts;
|
||||||
|
context.instructions = context.instructions || {};
|
||||||
|
var plugins = context.instructions.pluginScripts = {};
|
||||||
|
var self = this;
|
||||||
|
pluginScripts.forEach(function(ps) {
|
||||||
|
debug('Loading %s', ps);
|
||||||
|
var factory = require(ps);
|
||||||
|
var handler = factory(self.options);
|
||||||
|
var name = handler.name || path.basename(ps, '.js');
|
||||||
|
debug('Loaded plugin name: %s', name);
|
||||||
|
plugins[name] = handler;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ describe('Bootstrapper', function() {
|
||||||
expect(context.configurations.bootScripts).to.be.object;
|
expect(context.configurations.bootScripts).to.be.object;
|
||||||
expect(context.configurations.middleware).to.be.object;
|
expect(context.configurations.middleware).to.be.object;
|
||||||
expect(context.configurations.models).to.be.object;
|
expect(context.configurations.models).to.be.object;
|
||||||
|
expect(context.configurations.tracker).to.eql('load');
|
||||||
expect(context.instructions).to.be.undefined;
|
expect(context.instructions).to.be.undefined;
|
||||||
expect(process.bootFlags.length).to.eql(0);
|
expect(process.bootFlags.length).to.eql(0);
|
||||||
done();
|
done();
|
||||||
|
@ -55,6 +56,8 @@ describe('Bootstrapper', function() {
|
||||||
expect(context.configurations.models).to.be.undefined;
|
expect(context.configurations.models).to.be.undefined;
|
||||||
expect(context.configurations.bootScripts).to.be.object;
|
expect(context.configurations.bootScripts).to.be.object;
|
||||||
expect(context.instructions.application).to.be.object;
|
expect(context.instructions.application).to.be.object;
|
||||||
|
expect(context.instructions.tracker).to.eql('compile');
|
||||||
|
expect(context.executions.tracker).to.eql('start');
|
||||||
expect(process.bootFlags).to.eql(['barLoaded',
|
expect(process.bootFlags).to.eql(['barLoaded',
|
||||||
'barSyncLoaded',
|
'barSyncLoaded',
|
||||||
'fooLoaded',
|
'fooLoaded',
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
module.exports = function(opitions) {
|
||||||
|
return new Tracker(opitions);
|
||||||
|
};
|
||||||
|
|
||||||
|
function Tracker(options) {
|
||||||
|
this.name = 'tracker';
|
||||||
|
this.options = options || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Tracker.prototype.load = function(context) {
|
||||||
|
context.configurations.tracker = 'load';
|
||||||
|
};
|
||||||
|
|
||||||
|
Tracker.prototype.compile = function(context, done) {
|
||||||
|
context.instructions.tracker = 'compile';
|
||||||
|
process.nextTick(done);
|
||||||
|
};
|
||||||
|
|
||||||
|
Tracker.prototype.start = function(context, done) {
|
||||||
|
context.executions = context.executions || {};
|
||||||
|
context.executions.tracker = 'start';
|
||||||
|
process.nextTick(done);
|
||||||
|
};
|
Loading…
Reference in New Issue