Application Components

In asimov.js, an “application component” is just a plugin scoped to one piece of functionality — a feature folder you could publish to npm tomorrow. The framework doesn’t impose a directory layout for components, but a common one looks like this:

my-app/
index.js plugin hook + bootstrap
package.json
lib/
commands/ every file becomes an `asimov <name>` command
loc.js
init/ initializers
logMessage.js
helpers/ registered onto asimov.*
year.js
middleware/ for asimov-server
requestId.js
content/ page content
home.txt
site/
templates/ .tmpl files
styles/ .styl files
scripts/ client JS
data/ globals
images/

The plugin hook

Every component exports the same shape: a plugin function (mounted with asimov.use()) and a start function (the bootstrap when run standalone).

index.js
var asimov = require('asimov');
var logMessage = require('./lib/init/logMessage');
module.exports = function plugin () {
asimov.init(logMessage);
};
module.exports.start = function bootstrap () {
asimov.use(module.exports).start();
};
module.parent || module.exports.start();

module.parent || module.exports.start(); is the keystone — it means “if I’m being required as a plugin, do nothing; if I’m being run directly, boot myself.”

Composing components

A larger app is just a plugin that mounts other plugins:

var server = require('asimov-server');
var pages = require('asimov-pages');
var blog = require('./lib/components/blog');
var auth = require('./lib/components/auth');
module.exports = function plugin () {
asimov.use(server);
asimov.use(pages);
asimov.use(blog);
asimov.use(auth);
};

Order matters: a plugin can only register something after the plugins it depends on have done their own registration. The conventional order is “platform-level first” (server, pages) → “feature-level” (blog, auth) → “decorators” (analytics, logging).