134 lines
2.9 KiB
JavaScript
134 lines
2.9 KiB
JavaScript
|
var createWatchify = require('watchify')
|
||
|
var EventEmitter = require('events').EventEmitter
|
||
|
var debounce = require('debounce')
|
||
|
var concat = require('concat-stream')
|
||
|
var assign = require('object-assign')
|
||
|
var stripAnsi = require('strip-ansi')
|
||
|
var parseError = require('./parse-error')
|
||
|
|
||
|
module.exports = bundler
|
||
|
function bundler (browserify, opt) {
|
||
|
opt = opt || {}
|
||
|
var emitter = new EventEmitter()
|
||
|
var delay = opt.delay || 0
|
||
|
var closed = false
|
||
|
var pending = false
|
||
|
var time = Date.now()
|
||
|
var updates = []
|
||
|
var errorHandler = opt.errorHandler
|
||
|
if (errorHandler === true) {
|
||
|
errorHandler = defaultErrorHandler
|
||
|
}
|
||
|
|
||
|
var watchify = createWatchify(browserify, assign({}, opt, {
|
||
|
// we use our own debounce, so make sure watchify
|
||
|
// ignores theirs
|
||
|
delay: 0
|
||
|
}))
|
||
|
var contents = null
|
||
|
|
||
|
emitter.close = function () {
|
||
|
if (closed) return
|
||
|
closed = true
|
||
|
if (watchify) {
|
||
|
// needed for watchify@3.0.0
|
||
|
// this needs to be revisited upstream
|
||
|
setTimeout(function () {
|
||
|
watchify.close()
|
||
|
}, 200)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var bundleDebounced = debounce(bundle, delay)
|
||
|
watchify.on('update', function (rows) {
|
||
|
if (closed) return
|
||
|
updates = rows
|
||
|
pending = true
|
||
|
time = Date.now()
|
||
|
emitter.emit('pending', updates)
|
||
|
bundleDebounced()
|
||
|
})
|
||
|
|
||
|
emitter.bundle = function () {
|
||
|
if (closed) return
|
||
|
time = Date.now()
|
||
|
if (!pending) {
|
||
|
pending = true
|
||
|
process.nextTick(function () {
|
||
|
emitter.emit('pending', updates)
|
||
|
})
|
||
|
}
|
||
|
bundle()
|
||
|
}
|
||
|
|
||
|
// initial bundle
|
||
|
if (opt.initialBundle !== false) {
|
||
|
emitter.bundle()
|
||
|
}
|
||
|
|
||
|
return emitter
|
||
|
|
||
|
function bundle () {
|
||
|
if (closed) {
|
||
|
update()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
var didError = false
|
||
|
var outStream = concat(function (body) {
|
||
|
if (!didError) {
|
||
|
contents = body
|
||
|
|
||
|
var delay = Date.now() - time
|
||
|
emitter.emit('log', {
|
||
|
contentLength: contents.length,
|
||
|
elapsed: Math.round(delay),
|
||
|
level: 'info',
|
||
|
type: 'bundle'
|
||
|
})
|
||
|
|
||
|
bundleEnd()
|
||
|
}
|
||
|
})
|
||
|
|
||
|
var wb = watchify.bundle()
|
||
|
// it can be nice to handle errors gracefully
|
||
|
if (typeof errorHandler === 'function') {
|
||
|
wb.once('error', function (err) {
|
||
|
err.message = parseError(err)
|
||
|
contents = errorHandler(err) || ''
|
||
|
|
||
|
didError = true
|
||
|
emitter.emit('bundle-error', err)
|
||
|
bundleEnd()
|
||
|
})
|
||
|
} else {
|
||
|
wb.once('error', function (err) {
|
||
|
err.message = parseError(err)
|
||
|
emitter.emit('error', err)
|
||
|
emitter.emit('bundle-error', err)
|
||
|
})
|
||
|
}
|
||
|
wb.pipe(outStream)
|
||
|
|
||
|
function bundleEnd () {
|
||
|
update()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function update () {
|
||
|
if (closed) return
|
||
|
if (pending) {
|
||
|
pending = false
|
||
|
emitter.emit('update', contents, updates)
|
||
|
updates = []
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function defaultErrorHandler (err) {
|
||
|
console.error('%s', err)
|
||
|
var msg = stripAnsi(err.message)
|
||
|
return ';console.error(' + JSON.stringify(msg) + ');'
|
||
|
}
|