BrowserSync SSI Recipe
BrowserSync is my Node.js web browser app development server of choice. This gulpfile is a work in progress to address support for server side includes when using a BrowserSync static server.
gulpfile.js
var gulp = require('gulp');
var browserSync = require('browser-sync').create();
var minimist = require('minimist');
var serverConfig = {
site: './src',
directory: false,
host: 'localhost',
ssi: '.inc',
index: 'index.html'
}
// from https://github.com/gulpjs/gulp/blob/master/docs/recipes/pass-arguments-from-cli.md
// seems to make sense since gulp itself uses minimist.
var optionsConfig = {
string: 'host',
default: { host: process.env.NODE_ENV || serverConfig.host }
};
var options = minimist(process.argv.slice(2), optionsConfig);
// Static server
gulp.task('server', function() {
browserSync.init({
server: {
baseDir: serverConfig.site,
directory: serverConfig.directory,
index: serverConfig.index
}
});
});
// BrowserSync static server with ssi support
// https://www.npmjs.com/package/ssi#supported-instructions
// ------------------------------------------------
// Known issues:
// virtual include directives to an absolute URL path
// do not work as expected. For example, given this file context,
// http://localhost:3000/subdir/index.html
// works:
// <!--#include virtual="../incl/head.inc" -->
// does NOT work correctly, include directives in this include may not be found:
// <!--#include virtual="/incl/head.inc" -->
//
// workaround: use gulp server-proxy task
// ------------------------------------------------
function ssiMiddleware (req, res, next) {
var fs = require('fs');
var path = require('path');
var ssi = require("ssi");
var url = require('url');
var pathname = url.parse(req.originalUrl || req.url).pathname;
var filename = path.join(serverConfig.site, pathname.substr(-1) === '/' ? pathname + serverConfig.index : pathname);
if (fs.existsSync(filename)) {
var matcher = '/**/*' + serverConfig.ssi;
var parser = new ssi(serverConfig.site, serverConfig.site, matcher);
var contents = parser.parse(filename, fs.readFileSync(filename, {
encoding: 'utf8'
})).contents;
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.end(contents);
browserSync.emitter.on('service:running', function(data) {
if (!snippet) {
snippet = data.options.get('snippet');
}
inject();
});
}
else {
next();
}
}
gulp.task('server-ssi', function() {
browserSync.init({
server: {
baseDir: serverConfig.site,
directory: serverConfig.directory,
index: serverConfig.index
},
middleware: ssiMiddleware
});
});
// Proxy
// http://www.browsersync.io/docs/options/#option-proxy
// useful if apache needed for .htaccess, ssi, rewrite, etc.
// usage: $ gulp server-proxy --host [host]
// e.g., $ gulp server-proxy --host local.dev
gulp.task('server-proxy', function() {
browserSync.init({
proxy: options.host
});
});
Required Modules
$ gulp server-ssi