2017-09-13 07:52:34 +02:00

130 lines
2.9 KiB
JavaScript
Vendored

let md5 = require('md5');
let chokidar = require('chokidar');
let concatenate = require('concatenate');
let babel;
class Concat {
/**
* Create a new Concat instance.
*/
constructor() {
this.combinations = [];
global.events.listen('build', this.run.bind(this))
.listen('init', () => this.watch());
}
/**
* Add a set of files to be combined.
*
* @param {object} files
*/
add(files) {
this.combinations.push({
src: files.src,
output: files.output,
outputOriginal: files.output,
babel: !! files.babel
});
return this;
}
/**
* Watch all relevant files for changes.
*
* @param {object|null} watcher
*/
watch(watcher) {
watcher = watcher || chokidar;
if (! this.shouldWatch() || ! this.any()) return;
this.combinations.forEach(combination => {
watcher.watch(combination.src, { persistent: true })
.on('change', this.combine.bind(this, combination));
});
}
/**
* Determine if file watching should be enabled.
*
* @return {boolean}
*/
shouldWatch() {
return this.any() && process.argv.includes('--watch');
}
/**
* Process combination.
*
* @param {object} files
*/
combine(files) {
let output = File.find(files.output).makeDirectories();
let mergedFileContents = concatenate.sync(files.src, files.output);
if (files.babel && output.fileType === '.js') {
output.write(this.babelify(mergedFileContents));
}
// If file versioning is enabled, then we'll
// rename the output file to apply a hash.
if (global.options.versioning) {
let versionedPath = File.find(files.outputOriginal)
.versionedPath(md5(mergedFileContents));
files.output = output.rename(versionedPath).file;
}
if (process.env.NODE_ENV === 'production' || process.argv.includes('-p')) {
new File(files.output).minify();
}
// We'll now fire an event, so that the Manifest class
// can be refreshed to reflect these new files.
global.events.fire('combined', files);
}
/**
* Apply Babel to the given contents.
*
* @param {string} contents
*/
babelify(contents) {
if (! babel) babel = require('babel-core');
return babel.transform(
contents, { presets: ['env'] }
).code;
}
/**
* Perform all relevant combinations.
*/
run() {
this.combinations.forEach(files => this.combine(files));
return this;
}
/**
* Determine if there are any files to concatenate.
*
* @return {boolean}
*/
any() {
return this.combinations.length > 0;
}
}
module.exports = Concat;