bpmn-js/tasks/bundle.js

214 lines
4.6 KiB
JavaScript

'use strict';
var browserify = require('browserify'),
derequire = require('browserify-derequire'),
collapse = require('bundle-collapser/plugin'),
concat = require('source-map-concat'),
fs = require('fs'),
path = require('path'),
flattenBundle = require('browser-pack-flat/plugin'),
commonShake = require('common-shakeify'),
unassertify = require('unassertify'),
uglify = require('uglify-es');
var assign = Object.assign;
var BANNER = fs.readFileSync(__dirname + '/banner.txt', 'utf8'),
BANNER_MIN = fs.readFileSync(__dirname + '/banner-min.txt', 'utf8');
var SOURCE_MAP_HEADER = '//# sourceMappingURL=data:application/json;charset=utf-8;base64,';
function extractSourceMap(content) {
var idx = content.indexOf(SOURCE_MAP_HEADER),
map, code;
if (idx !== -1) {
code = content.substring(0, idx);
map = content.substring(idx + SOURCE_MAP_HEADER.length);
map = new Buffer(map, 'base64').toString();
map = map.replace(/\\\\/g, '/'); // convert \\ -> /
var dir = __dirname;
var dirPattern = dir.replace(/\\/g, '/').replace(/\./g, '\\.') + '/';
var pattern = new RegExp(dirPattern, 'g');
map = map.replace(pattern, '');
return {
code: code,
map: JSON.parse(map)
};
} else {
throw new Error('no attached source map');
}
}
function Timer() {
this.reset();
}
Timer.prototype.done = function(message) {
console.log(message, '[' + (this.now() - this.s) + 'ms]');
this.reset();
};
Timer.prototype.reset = function() {
this.s = this.now();
};
Timer.prototype.start = function(msg) {
console.log('start: ' + msg);
this.reset();
};
Timer.prototype.now = function() {
return new Date().getTime();
};
module.exports = function(grunt) {
grunt.registerMultiTask('bundle', function(target) {
var data = this.data,
variant = data.name,
dest = data.dest,
src = path.resolve(data.src);
grunt.config.set('config.variant', variant);
var done = this.async();
var browserifyOptions = {
standalone: 'BpmnJS',
builtins: false,
insertGlobalVars: {
process: function() {
return 'undefined';
},
Buffer: function() {
return 'undefined';
}
}
};
var targetFileBase = path.join(dest, variant);
var banner = grunt.template.process(BANNER, grunt.config.get()),
bannerMin = grunt.template.process(BANNER_MIN, grunt.config.get());
var timer = new Timer();
var fns = [
// production
function(done) {
timer.start('build prod');
browserify(browserifyOptions)
.transform(unassertify)
.plugin(commonShake)
.plugin(flattenBundle)
.plugin(collapse)
.plugin(derequire)
.add(src)
.bundle(function(err, result) {
timer.done('bundled');
if (err) {
return done(err);
}
var str = result.toString('utf-8');
var minified = uglify.minify(str, {
compress: true,
mangle: true,
output: {
preamble: bannerMin
}
});
timer.done('minified');
grunt.file.write(targetFileBase + '.min.js', minified.code, 'utf8');
timer.done('saved');
done();
});
},
// development
function(done) {
timer.start('build dev');
browserify(assign({ debug: true }, browserifyOptions))
.plugin(collapse)
.plugin(derequire)
.add(src)
.bundle(function(err, result) {
timer.done('bundled');
if (err) {
return done(err);
}
try {
var bundled = extractSourceMap(result.toString('utf8'));
timer.done('extracted source map');
var bannerBundled =
concat([ bundled ])
.prepend(banner + '\n')
.add('//# sourceMappingURL=./' + variant + '.js.map')
.toStringWithSourceMap();
timer.done('added banner');
grunt.file.write(targetFileBase + '.js', bannerBundled.code, 'utf8');
grunt.file.write(targetFileBase + '.js.map', bannerBundled.map, 'utf8');
timer.done('all saved');
} catch (e) {
return done(e);
}
done();
});
}
];
function next(err) {
if (err) {
return done(err);
}
var fn = fns.shift();
if (!fn) {
return done();
} else {
fn(next);
}
}
next();
});
};