bpmn-js/tasks/bundle.js

163 lines
3.6 KiB
JavaScript

'use strict';
var browserify = require('browserify'),
derequire = require('browserify-derequire'),
UglifyJS = require('uglify-js'),
collapse = require('bundle-collapser/plugin'),
concat = require('source-map-concat'),
fs = require('fs'),
path = require('path');
var BANNER = fs.readFileSync(__dirname + '/banner.txt', 'utf8'),
BANNER_MIN = fs.readFileSync(__dirname + '/banner-min.txt', 'utf8');
function extractSourceMap(content) {
var SOURCE_MAP_HEADER = '//# sourceMappingURL=data:application/json;base64,';
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 uglify(bundle, preamble) {
return UglifyJS.minify(bundle.code, {
fromString: true,
output: {
preamble: preamble
}
});
}
function Timer() {
this.reset();
}
Timer.prototype.done = function(message) {
console.log(message, '[' + (this.now() - this.start) + 'ms]');
this.reset();
};
Timer.prototype.reset = function() {
this.start = this.now();
};
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',
debug: true,
builtins: false,
insertGlobalVars: {
process: function () {
return 'undefined';
},
Buffer: function () {
return 'undefined';
}
}
};
var timer = new Timer();
var targetFileBase = path.join(dest, variant);
var banner = grunt.template.process(BANNER, grunt.config.get()),
bannerMin = grunt.template.process(BANNER_MIN, grunt.config.get());
browserify(browserifyOptions)
.plugin(derequire)
.plugin(collapse)
.add(src)
.bundle(function(err, result) {
timer.done('bundled');
if (err) {
return done(err);
}
var bundled, minified;
bundled = extractSourceMap(result.toString('utf8'));
timer.done('extracted source map');
try {
minified = uglify(bundled, bannerMin);
} catch (e) {
return done(e);
}
timer.done('minified');
var bannerBundled;
try {
bannerBundled = concat([ bundled ])
.prepend(banner + '\n')
.add('//# sourceMappingURL=' + variant + '.js.map')
.toStringWithSourceMap();
} catch (e) {
console.error(e.stack);
throw e;
}
timer.done('added banner');
grunt.file.write(targetFileBase + '.js', bannerBundled.code, 'utf8');
grunt.file.write(targetFileBase + '.js.map', bannerBundled.map, 'utf8');
grunt.file.write(targetFileBase + '.min.js', minified.code, 'utf8');
timer.done('all saved');
done();
});
});
};