Files
NodeBB/src/meta/build.js

227 lines
5.5 KiB
JavaScript
Raw Normal View History

'use strict';
2019-09-13 18:24:21 -04:00
const async = require('async');
const winston = require('winston');
const nconf = require('nconf');
const _ = require('lodash');
2019-09-13 18:24:21 -04:00
const cacheBuster = require('./cacheBuster');
let meta;
2016-11-19 14:24:37 -05:00
function step(target, callback) {
var startTime = Date.now();
winston.info('[build] ' + target + ' build started');
2016-12-13 15:43:20 +03:00
return function (err) {
if (err) {
winston.error('[build] ' + target + ' build failed');
return callback(err);
}
2016-12-13 15:43:20 +03:00
var time = (Date.now() - startTime) / 1000;
2016-11-19 14:24:37 -05:00
winston.info('[build] ' + target + ' build completed in ' + time + 'sec');
callback();
};
}
var targetHandlers = {
'plugin static dirs': function (parallel, callback) {
meta.js.linkStatics(callback);
},
'requirejs modules': function (parallel, callback) {
meta.js.buildModules(parallel, callback);
},
'client js bundle': function (parallel, callback) {
meta.js.buildBundle('client', parallel, callback);
},
'admin js bundle': function (parallel, callback) {
meta.js.buildBundle('admin', parallel, callback);
},
javascript: [
'plugin static dirs',
'requirejs modules',
'client js bundle',
'admin js bundle',
],
'client side styles': function (parallel, callback) {
meta.css.buildBundle('client', parallel, callback);
},
'admin control panel styles': function (parallel, callback) {
meta.css.buildBundle('admin', parallel, callback);
},
styles: [
'client side styles',
'admin control panel styles',
],
templates: function (parallel, callback) {
meta.templates.compile(callback);
},
languages: function (parallel, callback) {
meta.languages.build(callback);
},
sounds: function (parallel, callback) {
meta.sounds.build(callback);
},
};
2016-12-13 15:43:20 +03:00
var aliases = {
'plugin static dirs': ['staticdirs'],
'requirejs modules': ['rjs', 'modules'],
'client js bundle': ['clientjs', 'clientscript', 'clientscripts'],
'admin js bundle': ['adminjs', 'adminscript', 'adminscripts'],
javascript: ['js'],
'client side styles': [
'clientcss', 'clientless', 'clientstyles', 'clientstyle',
],
'admin control panel styles': [
'admincss', 'adminless', 'adminstyles', 'adminstyle', 'acpcss', 'acpless', 'acpstyles', 'acpstyle',
],
styles: ['css', 'less', 'style'],
templates: ['tpl'],
languages: ['lang', 'i18n'],
sounds: ['sound'],
};
exports.aliases = aliases;
aliases = Object.keys(aliases).reduce(function (prev, key) {
var arr = aliases[key];
arr.forEach(function (alias) {
prev[alias] = key;
});
prev[key] = key;
return prev;
}, {});
function beforeBuild(targets, callback) {
var db = require('../database');
2018-05-16 15:53:49 -04:00
require('colors');
process.stdout.write(' started'.green + '\n'.reset);
async.series([
2019-10-04 00:38:59 -04:00
function (next) {
db.init(next);
},
2018-05-16 15:53:49 -04:00
function (next) {
meta = require('../meta');
meta.themes.setupPaths(next);
},
function (next) {
var plugins = require('../plugins');
plugins.prepareForBuild(targets, next);
},
], function (err) {
if (err) {
winston.error('[build] Encountered error preparing for build', err);
return callback(err);
}
callback();
});
}
var allTargets = Object.keys(targetHandlers).filter(function (name) {
return typeof targetHandlers[name] === 'function';
});
function buildTargets(targets, parallel, callback) {
var all = parallel ? async.each : async.eachSeries;
var length = Math.max.apply(Math, targets.map(function (name) {
return name.length;
}));
2016-12-01 13:51:14 +03:00
all(targets, function (target, next) {
targetHandlers[target](parallel, step(_.padStart(target, length) + ' ', next));
}, callback);
}
2016-12-01 13:51:14 +03:00
2019-09-13 18:24:21 -04:00
exports.build = function (targets, options, callback) {
2018-07-01 22:11:38 -06:00
if (!callback && typeof options === 'function') {
callback = options;
options = {};
} else if (!options) {
options = {};
}
if (targets === true) {
targets = allTargets;
} else if (!Array.isArray(targets)) {
targets = targets.split(',');
}
2018-07-01 22:11:38 -06:00
var parallel = !nconf.get('series') && !options.series;
targets = targets
// get full target name
.map(function (target) {
target = target.toLowerCase().replace(/-/g, '');
if (!aliases[target]) {
winston.warn('[build] Unknown target: ' + target);
if (target.includes(',')) {
winston.warn('[build] Are you specifying multiple targets? Separate them with spaces:');
winston.warn('[build] e.g. `./nodebb build adminjs tpl`');
}
return false;
}
return aliases[target];
})
// filter nonexistent targets
.filter(Boolean);
// map multitargets to their sets
targets = _.uniq(_.flatMap(targets, target => (
Array.isArray(targetHandlers[target]) ?
targetHandlers[target] :
target
)));
winston.verbose('[build] building the following targets: ' + targets.join(', '));
if (!targets) {
winston.info('[build] No valid targets supplied. Aborting.');
callback();
}
var startTime;
var totalTime;
async.series([
2017-05-24 16:55:23 -06:00
async.apply(beforeBuild, targets),
function (next) {
var threads = parseInt(nconf.get('threads'), 10);
if (threads) {
require('./minifier').maxThreads = threads - 1;
}
if (parallel) {
winston.info('[build] Building in parallel mode');
2016-12-01 13:51:14 +03:00
} else {
winston.info('[build] Building in series mode');
2016-12-01 13:51:14 +03:00
}
startTime = Date.now();
buildTargets(targets, parallel, next);
2016-12-01 13:51:14 +03:00
},
function (next) {
totalTime = (Date.now() - startTime) / 1000;
cacheBuster.write(next);
2017-02-17 19:31:21 -07:00
},
2016-12-01 13:51:14 +03:00
], function (err) {
if (err) {
winston.error('[build] Encountered error during build step', err);
return callback(err);
}
winston.info('[build] Asset compilation successful. Completed in ' + totalTime + 'sec.');
callback();
});
2019-09-13 18:24:21 -04:00
};
2017-01-23 21:06:34 -07:00
exports.buildAll = function (callback) {
2019-09-13 18:24:21 -04:00
exports.build(allTargets, callback);
2017-02-18 02:30:48 -07:00
};
2019-09-13 18:24:21 -04:00
require('../promisify')(exports);