Skip to content

Instantly share code, notes, and snippets.

@matthewmueller
Last active August 29, 2015 14:06
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save matthewmueller/a7727082581a4ade7fe1 to your computer and use it in GitHub Desktop.
Save matthewmueller/a7727082581a4ade7fe1 to your computer and use it in GitHub Desktop.
Duo gulp integration
/**
* Module Dependencies
*/
var debug = require('debug')('lapwing:build');
var relative = require('path').relative;
var resolve = require('path').resolve;
var extname = require('path').extname;
var uglify = require('gulp-uglify');
var Batch = require('better-batch');
var root = require('../root-path');
var yieldly = require('yieldly');
var Glob = require('glob').sync;
var map = require('map-stream');
var join = require('path').join;
var csso = require('gulp-csso');
var gulp = require('gulp');
var Duo = require('duo');
/**
* Expose `build`
*/
module.exports = yieldly(build);
/**
* Gulp plugins
*/
var myth = require('gulp-myth');
/**
* Environment
*/
var dev = 'development' == process.env.NODE_ENV;
/**
* File extension maps
*/
var extmap = {
'styl': 'css'
};
/**
* Build
*
* @param {String} glob
* @param {Function} fn
* @api public
*/
function build(glob, fn) {
var files = Glob(glob);
var segments = segment(files);
Batch()
.push(wrap(styles, segments.css))
.push(wrap(scripts, segments.js))
.end(fn);
// wrap batch
function wrap(fn, files) {
return function (done) {
fn(files, done);
}
}
}
/**
* Compile styles
*
* @param {Function} fn
* @return {Gulp} stream
* @api private
*/
function styles(styles, fn) {
var s = gulp.src(styles)
.pipe(logger('building'))
.pipe(duo())
.on('error', fn)
.pipe(myth())
.on('error', fn)
if (!dev) {
s.pipe(csso())
.on('error', fn);
}
s.pipe(gulp.dest('build'))
.on('error', fn)
.on('end', fn);
return s;
}
/**
* Compile javascript
*
* @param {Array} scripts
* @return {Function} fn
*/
function scripts(scripts, fn) {
var s = gulp.src(scripts)
.pipe(logger('building'))
.pipe(duo())
.on('error', fn);
if (!dev) {
s.pipe(uglify())
.on('error', fn);
}
s.pipe(gulp.dest('build'))
.on('error', fn)
.on('end', fn);
return s;
}
/**
* Build with Duo
*
* @return {Function}
*/
function duo() {
return map(function(file, fn) {
// change the base to root
file.base = root;
Duo(root)
.entry(file.path)
.run(function(err, src) {
if (err) return fn(err);
file.contents = new Buffer(src);
fn(null, file);
});
});
}
/**
* Segment files by extension
*
* @param {Array} files
* @return {Object}
* @api private
*/
function segment(files) {
var out = {};
files.map(function(file) {
var ext = extname(file).slice(1);
ext = extmap[ext] ? extmap[ext] : ext;
if(!out[ext]) out[ext] = [];
out[ext].push(file);
});
return out;
}
/**
* Logging
*
* @param {Stream} stream
* @api private
*/
function logger(event) {
return map(function(file, fn) {
debug('%s: %s', relative(root, file.path), event);
fn(null, file);
});
}
/**
* Module Dependencies
*/
var build = require('../build')
/**
* Expose `middleware`
*/
module.exports = middleware;
/**
* Initialize `middleware`
*
* @param {String} glob
* @return {Generator}
*/
function middleware(glob) {
return function *(next) {
yield build(glob);
yield next;
}
}
@matthewmueller
Copy link
Author

Usage:

build(join(__dirname, 'home.{js,styl,css}'), function(err) {
  // built
});

This allows you to easily integrate with middleware & only build the files you need for that page.

@johntron
Copy link

johntron commented Jan 7, 2015

Here's a simpler, less-robust version just to demonstrate the idea: https://gist.github.com/johntron/1c057bbad6d477362ab6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment