Pluginbnb
Lightweight, unopinionated plugin framework - create extremely extensible and scalable apps using a service-based architecture and dependency injection.
Overview
At a high level - pluginbnb is an app framework that consists of plugins which can provide/consume services. To define a plugin you define a function which provide services and a function that can consume services, consumption happens in the form of a redux-saga so your plugin can wait around for your desired service to be provided which elmiminates dependency chains entirely since your plugin will pause execution until the service it needs becomes available.
This architecture allows for a highly extensible application because a plugin that adds functionality would just provide services other plugins consume (or consume services other plugins provide) - for example a plugin could provide new routes to be consumed by a router plugin or a plugin could provide UI components such as navigation-menus which would be rendered by a navigation-menu consumer.
Configuration
In order for plugins to run, they have to be declared in a configuration
which will contain at a minimum the path of the plugin. Here you would define
environment specific data.
Configuration can either be json or a js file that exports an object/Promise that resolves to an object
The plugins array represents the enabled plugins in a pluginbnb instance.
module.exports = {
plugins: [
{"path": "express-app", "apiBaseUrl" : "/api", "port" : 3001},
{"path": "./route-provider", "port": 3001},
],
};
Plugin Interface
A plugin consists of a module which exports a generator function, each plugin takes the form of a redux-saga meaning
they can wait for specific events to happens or services to be provided by other plugins before running their own code.
let express = require("express");
const consume = require("pluginbnb/effects/consume");
module.exports = {
run : function*(config, provide, services){
const app = express();
const router = express.Router();
app.use(config.apiBaseUrl, router);
app.listen(config.port);
yield provide({
expressApp: app,
baseRouter: router
});
while(true){
let newRoute = yield consume(services.expressRouter);
router.use(newRoute);
}
}
}
Now if I wanted to create a plugin which adds a new route to my app all I need to do is provide an expressRoute service
module.exports = {
run : function*(config, provide, services){
const router = require("express").Router();
router.get("/hello-world", (req, res) => {
res.json({hello : "world"});
});
yield provide({
expressRouter: router
});
}
}
package.json
In order for a pluginbnb plugin to be considered valid it requires a pluginbnb
section to be defined in the package.json. For a basic definition you just need
to define where the entry point to your plugin is and the services the plugin consumes (if any)
{
"name": "express-app",
"version": "0.0.1",
"private": true,
"pluginbnb": {
"main" : "express-app.js",
"consumes": ["expressRoute"]
}
}
Starting Pluginbnb
To start pluginbnb on the server, just call createPluginbnb and initialize it
const CONFIG_PATH = "./config.js"
let path = require("path");
let Pluginbnb = require("pluginbnb");
Pluginbnb.createPluginbnb(path.resolve(__dirname, CONFIG_PATH))
.then(pluginbnb => pluginbnb.initialize())
.catch(e => {
console.error(e);
});
Advanced (in progress...)
Hooks
On Plugin Install
On Plugin Uninstall
On Plugin Enable
On Plugin Disable
Consume services with React components
see pluginbnb-react
###Credit