Jack-Stack
A Jack-of-Express-stack; master of nothing else.
Purpose
Jack-Stack handles all of the standard Express.js app configuration you don't really care about.
What it provides
(In the following order)
- express.static
- morgan
- cookie-parser
- express-session
- feature-client
- xpr-express
- xpr-toggle
- body-parser
- json and urlencoded
- method-override
- compression
Installation
$ npm install --save jack-stack
Usage
This library was written using ES6 (ES 2015), but it is compiled to ES5.1, and uses that by default.
ES6
// Import jack's parts; // Configure your appapp; // Start your app;
ES5
// Require Jack's ES5 libraryvar jack = ; // Set the partsvar app = jackapp;var init = jackinit;var start = jackstart; // Configure your appapp; // Start your app;
Configuration
Jack lets you know when it's ready for you to pass in configuration. You can either overwrite specific keys, or you can pass a full object to merge with config
;
; // You can use either// app.on('config')// jack.useAfter('config') app; ;
Configuration options
experiments: name: 'expName' // Experiment name default: false // Default value cookie: secret: '' // Your Express cookie secret session: name: '' // The name of your express session secret: '' // The express session secret { // Function for using your own Session storage. // By default uses Express MemoryStore, which is not production-ready } bodyParser: urlencoded: // any configuration to pass into bodyParser.urlencoded extended: false json: {} // any configuration to pass into bodyParser.json methodOverride: {} // any configuration to pass into methodOverride morgan: {} // any configuration to pass into morgan staticDir: '' // Path to your webroot. Defaults to './public' port: 5000 // Port to run your application. Defaults to 5000
Middleware Ordering
The easiest way to add your own middleware during any stage in the initialization is to use jack.useBefore
and jack.useAfter
.
These methods have the following signature:
jack;jack;
method
- This is the event you want to neighbor your new handler.name
- A name for your handler. Make sure you check for uniqueness. I don't.handler
- Function to call when your turn for intialization comes.handler
is called as:handler({ app, config, registerDelay })
app
- This is the Express appconfig
- This is the full Jack configuration object (see config);registerDelay
- This allows you to register asynchronous actions that require delay of startup (see Async Middleware)
- jack.useAfter('config') is special. It only calls handler with the config object
; jack; jack;
The manual equivalent of this is listening on the events and wrapping your own methods in their events:
If you forget to wrap and name your events, you cannot stick things before or after your own things later.
; app; app;
Async Middleware
The big problem with adding middleware asynchronously is that you need to register a middleware during your event or it'll get out of order. To solve this, we'll add our middleware, delay startup until after our middleware is configured, and then configure it.
We'll use the parameter that gets passed up with the event: registerDelay
, which accepts Promises;
ES6
; jack; ;
ES5
var Promise = ;var jack = ;var app = jackapp start = jackstart; jack; ;
Currently Built-in events you may wrap around:
static
- express.staticlogging
- morgancookie
- cookie-parsersession
- express-sessionxprmntl
- feature-clientjson
- body-parser.jsonurlencoded
- body-parser.urlencodedoverride
- method-overridecompress
- compressionrouting
- Express router
Custom Events
You can also use these events for your own middleware if you'd like. Simply use the exported wrap
method for wrapping your own middleware:
ES6
First place:
; ;
Elsewhere:
jack;
ES5
First place:
var jack = ; var app = jackapp wrap = jackwrap; ;
Elsewhere:
jack;
Plugins
Known Plugins
- jack-stack-redis - Connect-Redis RedisStore session storage to replace the built-in MemoryStore one, which is "no bueno" for production.
- [Your Plugin Here] - Please feel free to create your own. If you do and you'd like to have it listed here, please create me a Pull Request adding it. I appreciate your contributions!
Plugin Authoring
Plugin authoring is handled in the same way events are. Any initialized plugin should return the following structure (or an array of them):
event: 'name.of.event' { // handler stuff }
You can then use jack.use
to implement these plugins:
var jack = ;var start = jackstart;var redisConfig = host: 'localhost' port: 6379; var redisPlugin = redisConfig;// This returns// {// event: 'config',// handler: function(config) {// config.session.getStore = () => {// return new RedisStore(redisConfig);// };// }// }jack;
Contribution
We'd love you to contribute. To work on it locally, simply clone the repo and use babel to generate the es5 stuff:
$ npm install -g babel$ git clone https://github.com/dncrews/jack-stack.git .$ cd jack-stack$ babel es6.js --watch --out-file index.js