lactate

Simple and featureful assets server

npm install lactate
24 downloads in the last day
79 downloads in the last week
469 downloads in the last month

Lactate

npm install -g lactate

An exceedingly fast static file handler, with a few electives.

Features

  • In-memory caching
  • Redis caching
  • Robust cache-control setting
  • Automatic gzipping
  • Automatic minification
  • Custom 404 pages
  • Custom response headers
  • Custom / automatic charset headers
  • Custom gzip patterns
  • Asset bundling and minification
  • Middleware export
  • Default error pages
  • on(status) listeners
  • Colored log output
  • Global executable
  • Directory indexing
  • Express.static API compatibility
  • node-static API compatibility

Using Lactate

Global executable

If installed globally with npm install -g lactate, you will have the lactate command at your disposal. This will run lactate static file server in the current working directory, utilizing the cluster module for multiple CPU cores. All options are available.

$ lactate --help
Usage: lactate [options]

Options:
--root, -r          Local path                          [default: ""]
--from, -f          Public path                         [default: ""]
--subdirs, -s       Serve subdirectories                [default: true]
--hidden, -h        Serve hidden files                  [default: false]
--error-pages       Serve error pages                   [default: true]
--autoindex, -a     Automatically index directories     [default: true]
--cache, -c         Store assets in-memory              [default: true]
--watch-files       Watch files for cache update        [default: true]
--client-cache      Client-side caching max-age         [default: 172800]
--gzip, -g          Gzip text assets                    [default: true]
--minify, -m        Minify text assets                  [default: false]
--bundle, -b        Bundle text assets                  [default: false]
--rebundle, --rb    Rebundle assets if modified         [default: true]
--headers, -H       Custom response headers             [default: ""]
--debug, -d         Log HTTP info                       [default: true]
--quiet, -q         Prevent all log output              [default: false]

Programmatic lactating

Lactate can be used with either plain node, or with Express. With Express, Lactate is a drop-in replacement for static middleware, but with far more ability. The examples below use Express 2.x API for simplicity. See the examples for various examples.

var lactate = require('lactate');
var express = require('express');

var app = express();
app.use(lactate.static(__dirname + '/files'));

Testing Lactate

If installed locally (without -g flag to npm install):

  1. cd into ~/node_modules/lactate
  2. npm install ./ to install devDependencies
  3. make test to run mocha test

The varieties of Lactate experience

Creating a Lactate server

var lactate = require('lactate'); 
var options = {root:'files'}; 
var server = lactate.createServer(options); 

server.listen(8080);

Creating a directory handler

var lactate = require('lactate');
var options = {from:'public/path/to/files'};
var files = lactate.dir('files', options);

var http = require('http');
var server = new http.Server;

server.addListener('request', function(req, res) {
  files.serve(req, res);
});

server.listen(8080);

Using directory middleware

var lactate = require('lactate');
var files = lactate.dir('files', options);

var http = require('http');
var server = new http.Server;

server.addListener('request', files.toMiddleware());
server.listen(8080);

Integrating with Express

var lactate = require('lactate');
var files = lactate.dir('files', options);

var express = require('express');
var app = express();

app.use(files.toMiddleware());
app.listen(8080);

Using Express.static API

var lactate = require('lactate');
var express = require('express');
var app = express();

app.use(lactate.static(__dirname + '/files'));
app.listen(8000);

Using node-static API

var lactate = require('lactate');
var files = new(lactate.Server)('./files');

var http = require('http');
var server = new http.Server;

// You could also pass a .toMiddleware()'d function

server.addListener('request', function(req, res) {
  files.serve(req, res);
});

server.listen(8000);

Serving individual files

var lactate = require('lactate');

var fileOptions = {from:'public/directory'};
var files = lactate.dir('files', fileOptions);

var pageOptions = {};
var pages = lactate.dir('pages');

var http = require('http');
var server = new http.Server;

server.addListener('request', function(req, res) {
  if (req.url === '/') {
    pages.serve('index.html', req, res);
  } else {
    files.serve(req, res);
  };
});
server.listen(8000);

Setting options

var lactate = require('lactate');

var fileOptions = {
  from:'public'
};

var files = lactate.dir('files', fileOptions);

files.set('cache', false);
files.disable('gzip');
files.maxAge('ten days');

var express = require('express');
var app = express():

app.get('/public/*', files.toMiddleware());
app.listen(8080);

Bundling assets

var lactate = require('lactate');
var options = {
  from:'files'
};

var files = lactate.dir('files', options);

// Combine and minify all scripts to 'common.js'
files.bundle('js', 'common.js', function(err, data) {
// Handle errors
});

// Combine and minify all CSS to 'common.css'
files.bundleCSS('common.css');

var express = require('express');
var app = express();

app.use(files.toMiddleware());
app.listen(8000);

Using custom 404 pages

var lactate = require('lactate');
var files = lactate.dir('files');

files.notFound('path/to/404/page.html');

files.notFound(function(req, res) {
  res.writeHead(404);
  res.end('Woops, 404');
});

var express = require('express');
var app = express();

app.use(files.toMiddleware());
app.listen(8000);

Using custom response headers

var lactate = require('lactate');
var files = lactate.dir('files');

files.setHeader('x-powered-by', 'Lactate');
files.header('x-timestamp', function(req, res) {
  return new Date().toUTCString();
});

var headers = {};
files.headers(headers);

Status listeners

Lactate extends EventEmitter for emitting status code events.

var files = lactate.dir('files');
files.on('404', function(req) {
  console.log('404', req.url);
});

Options

Setting options

Boolean options may be set using enable and disable methods. Other options may be set using set method with either key/value or an options object.

Passing to initialization function

var lactate = require('lactate').Lactate({
  max_age:'two days'
})

Using set method

lactate.set('hidden', true)

Using enable/disable:

lactate.disable('gzip');
lactate.enable('minify');

Special options methods

Lactate has some special methods to reduce visual clutter. For setting client-side expiration use maxAge

lactate.maxAge('two days');

is equivalent to:

lactate.set('max age', 'two days');

For setting custom headers you may use setHeader

lactate.setHeader('x-powered-by', 'Rodent exercise');

You can also use a function with setHeader for added variance:

lactate.setHeader('x-id', function(req, res) {
  return Math.random().toString(36).substring(2);
}):

For defining charsets, you may use Lactate.define

lactate.define('js', 'application/javascript');

or with an object

lactate.define({
  'html': 'text/html; charset=utf-8',
  'js': 'application/javascript'
});

Underscores or spaces

Use spaces instead of underscores if you prefer:

lactate.disable('max age');
lactate.enable('watch files');

Options available

  • root string

Local directory from which to serve files. By default, the current working directory.

  • from string

Public directory exposed to clients. If set, only requests from /directory will complete. Contrast this with the root option which is the location of files on the serving machine, not necessarily the requested path.

  • subdirs boolean

By default subdirectories are served. To disable this, set subdirs to false.

  • hidden boolean

Whether or not to serve hidden files. Default is false.

  • error pages boolean

Enabled by default. When disabled, Lactate will not serve error pages for 404 resposes, etc..

  • autoindex boolean

Automatically display directory indexes. Disabled by default.

  • cache boolean or object

Keep files in-memory. Enabled by default. For caching options and more information about caching strategy, see Caching Options.

  • gzip boolean

If false, disables automatic gzipping for text files (HTML, JS, CSS). Enabled by default.

  • minify boolean

If true, will automatically minify JavaScript and CSS using Abridge. Disabled by default.

  • watch files boolean

Determines whether Lactate will watch files to update its cache. If this is disabled, then your file cache will not update automatically as files are modified on the server.

  • headers object or function

Sets custom response headers. If the option value is a function, it is a callback which is give (req, res) arguments. This function should return the header value; it is a mapping function.

  • max age number or string

Pass this function a number (of seconds) or a string and appropriate headers will be set for client-side caching. Lactate comes with expiration defaults, such as 'two days' or '5 years and sixteen days' See Expire for details.

lactate.set('max_age', 87500)
//87500 seconds
lactate.set('max_age', 'two days')
//172800 seconds
lactate.set'max_age', 'five weeks and one minute and ten seconds')
//3024070 seconds
lactate.set('max_age', 'one year and 2 months and seven weeks and 16 seconds')
//41050028 seconds
  • not found string or function

For custom 404 handling. Functions are supplied the response for 100% custom response handling. Otherwise, if set to a string, this option will be treated as an ordinary file path and abide rules for gzipping / in-memory cache.

  • gzip patterns array

Set custom gzip RegExp patterns. The patterns are matched with mime types. E.g. /(\+|\/)xml$/ may be used for matching XML documents for gzipping. You may either use:

lactate.set('gzip patterns', []);

Or perhaps more conveniently:

//Accepts RegExp or String
lactate.gzip(/pattern/, ...);
  • charset boolean or string

Set custom response charset, or automatically detect charset using node-mime.

lactate.enable('charset');
// Content-Type: text/html; charset=UTF-8
lactate.set('charset', 'utf-8');
// Content-Type: text/html; charset=UTF-8
  • debug boolean

Colored status / msg / path logging, for debugging purposes.

Caching options

Pass an object to the cache option setting. The following fields are accepted and optional:

  • expire Seconds expiration for cache keys. Keys expire after they are untouched for x-seconds. Default is 15min.
  • max keys Maximum number of keys to keep in memory. Default is Infinity.
  • max size Maximum size in MB to keep in cache. Default is 100mb.
  • segment Determines the threshold after which to segment a file for streaming instead of traditional writing. Default is 200kb.
  var options = {};

  options.cache = {
    expire:5,
    max_keys:200,
    max_size:2,
    segment:100
  };

  var files = lactate.static('files', options);

  // Or use a string representation. Same as setting for max-age.
  options.cache.expire = 'fifteen minutes';
  files.set('cache', options.cache);

License

MIT

npm loves you