Files
NodeBB/src/meta/js.js

308 lines
8.6 KiB
JavaScript
Raw Normal View History

2014-07-04 18:20:40 -04:00
'use strict';
var winston = require('winston'),
fork = require('child_process').fork,
path = require('path'),
async = require('async'),
2014-08-27 14:42:10 -04:00
nconf = require('nconf'),
fs = require('fs'),
2015-09-29 18:22:41 -04:00
file = require('../file'),
2014-07-04 18:20:40 -04:00
plugins = require('../plugins'),
emitter = require('../emitter'),
utils = require('../../public/src/utils');
module.exports = function(Meta) {
Meta.js = {
2016-01-18 15:17:21 -05:00
target: {},
scripts: {
base: [
'./node_modules/jquery/dist/jquery.js',
2014-11-20 19:02:29 -05:00
'./node_modules/socket.io-client/socket.io.js',
2015-08-17 12:38:28 -04:00
'public/vendor/jquery/timeago/jquery.timeago.js',
'public/vendor/jquery/js/jquery.form.min.js',
'public/vendor/visibility/visibility.min.js',
'public/vendor/bootstrap/js/bootstrap.js',
'public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js',
2016-03-25 19:54:22 -04:00
'public/vendor/jquery/textcomplete/jquery.textcomplete.js',
'public/vendor/requirejs/require.js',
2016-08-26 12:53:00 +03:00
'public/src/require-config.js',
'public/vendor/bootbox/bootbox.min.js',
'public/vendor/tinycon/tinycon.js',
'public/vendor/xregexp/xregexp.js',
'public/vendor/xregexp/unicode/unicode-base.js',
'./node_modules/templates.js/lib/templates.js',
'public/src/utils.js',
2015-09-18 10:58:32 -04:00
'public/src/sockets.js',
'public/src/app.js',
'public/src/ajaxify.js',
2015-03-17 12:47:40 -04:00
'public/src/overrides.js',
'public/src/widgets.js',
"./node_modules/promise-polyfill/promise.js"
],
// files listed below are only available client-side, or are bundled in to reduce # of network requests on cold load
rjs: [
'public/src/client/footer.js',
'public/src/client/chats.js',
'public/src/client/infinitescroll.js',
'public/src/client/pagination.js',
2015-10-20 22:54:32 -04:00
'public/src/client/recent.js',
'public/src/client/unread.js',
'public/src/client/topic.js',
'public/src/client/topic/events.js',
'public/src/client/topic/flag.js',
'public/src/client/topic/fork.js',
'public/src/client/topic/move.js',
'public/src/client/topic/posts.js',
'public/src/client/topic/postTools.js',
'public/src/client/topic/threadTools.js',
'public/src/client/categories.js',
'public/src/client/category.js',
'public/src/client/categoryTools.js',
'public/src/modules/translator.js',
'public/src/modules/notifications.js',
'public/src/modules/chat.js',
'public/src/modules/components.js',
2015-10-20 22:54:32 -04:00
'public/src/modules/sort.js',
'public/src/modules/navigator.js',
'public/src/modules/topicSelect.js',
'public/src/modules/share.js',
'public/src/modules/search.js',
'public/src/modules/alerts.js',
'public/src/modules/taskbar.js',
'public/src/modules/helpers.js',
'public/src/modules/sounds.js',
'public/src/modules/string.js'
],
// modules listed below are routed through express (/src/modules) so they can be defined anonymously
2016-04-27 14:14:22 -04:00
modules: {
2016-07-29 19:31:48 +00:00
"Chart.js": './node_modules/chart.js/dist/Chart.min.js',
"mousetrap.js": './node_modules/mousetrap/mousetrap.min.js',
2016-08-29 21:53:12 +00:00
"jqueryui.js": 'public/vendor/jquery/js/jquery-ui.js',
2016-04-27 14:14:22 -04:00
"buzz.js": 'public/vendor/buzz/buzz.js'
}
}
2014-07-04 18:20:40 -04:00
};
Meta.js.bridgeModules = function(app, callback) {
// Add routes for AMD-type modules to serve those files
2016-04-27 14:14:22 -04:00
var numBridged = 0,
addRoute = function(relPath) {
var relativePath = nconf.get('relative_path');
2016-07-14 21:44:33 +03:00
app.get(relativePath + '/src/modules/' + relPath, function(req, res) {
2016-04-27 14:14:22 -04:00
return res.sendFile(path.join(__dirname, '../../', Meta.js.scripts.modules[relPath]), {
maxAge: app.enabled('cache') ? 5184000000 : 0
});
});
};
async.series([
function(next) {
2016-04-27 14:14:22 -04:00
for(var relPath in Meta.js.scripts.modules) {
if (Meta.js.scripts.modules.hasOwnProperty(relPath)) {
addRoute(relPath);
++numBridged;
}
}
next();
}
], function(err) {
if (err) {
winston.error('[meta/js] Encountered error while bridging modules:' + err.message);
}
winston.verbose('[meta/js] ' + numBridged + ' of ' + Object.keys(Meta.js.scripts.modules).length + ' modules bridged');
callback(err);
});
};
2016-01-18 15:17:21 -05:00
Meta.js.minify = function(target, callback) {
2016-01-18 14:18:17 -05:00
if (nconf.get('isPrimary') !== 'true') {
if (typeof callback === 'function') {
callback();
}
return;
}
winston.verbose('[meta/js] Minifying ' + target);
2016-01-18 14:18:17 -05:00
var forkProcessParams = setupDebugging();
var minifier = Meta.js.minifierProc = fork('minifier.js', [], forkProcessParams);
2016-01-18 15:17:21 -05:00
Meta.js.target[target] = {};
Meta.js.prepare(target, function() {
2016-01-18 14:18:17 -05:00
minifier.send({
action: 'js',
minify: global.env !== 'development',
2016-01-18 15:17:21 -05:00
scripts: Meta.js.target[target].scripts
2016-01-18 14:18:17 -05:00
});
});
minifier.on('message', function(message) {
switch(message.type) {
case 'end':
2016-01-18 15:17:21 -05:00
Meta.js.target[target].cache = message.minified;
Meta.js.target[target].map = message.sourceMap;
winston.verbose('[meta/js] ' + target + ' minification complete');
2016-01-18 14:18:17 -05:00
minifier.kill();
2016-03-30 16:05:11 -04:00
if (process.send && Meta.js.target['nodebb.min.js'] && Meta.js.target['acp.min.js']) {
2016-01-18 14:18:17 -05:00
process.send({
action: 'js-propagate',
data: Meta.js.target
2016-01-18 14:18:17 -05:00
});
}
2016-07-08 10:43:28 -04:00
if (nconf.get('local-assets') === undefined || nconf.get('local-assets') !== false) {
return Meta.js.commitToFile(target, function() {
if (typeof callback === 'function') {
callback();
}
});
2016-07-08 10:43:28 -04:00
} else {
emitter.emit('meta:js.compiled');
if (typeof callback === 'function') {
return callback();
}
2016-07-08 10:43:28 -04:00
}
2016-01-18 14:18:17 -05:00
break;
case 'error':
2016-02-01 20:58:16 +02:00
winston.error('[meta/js] Could not compile ' + target + ': ' + message.message);
2016-01-18 14:18:17 -05:00
minifier.kill();
2016-01-18 14:18:17 -05:00
if (typeof callback === 'function') {
2016-02-01 20:58:16 +02:00
callback(new Error(message.message));
2016-01-18 14:18:17 -05:00
} else {
process.exit(0);
}
break;
}
});
};
2016-01-18 15:17:21 -05:00
Meta.js.prepare = function(target, callback) {
var pluginsScripts = [];
var pluginDirectories = [];
2014-07-04 18:20:40 -04:00
pluginsScripts = plugins[target === 'nodebb.min.js' ? 'clientScripts' : 'acpScripts'].filter(function(path) {
if (path.endsWith('.js')) {
return true;
}
pluginDirectories.push(path);
return false;
});
async.each(pluginDirectories, function(directory, next) {
utils.walk(directory, function(err, scripts) {
pluginsScripts = pluginsScripts.concat(scripts);
next(err);
});
}, function(err) {
2014-10-04 18:56:33 -04:00
if (err) {
return callback(err);
}
2014-07-22 13:53:09 -04:00
var basePath = path.resolve(__dirname, '../..');
2016-01-18 15:17:21 -05:00
2016-01-18 15:41:30 -05:00
Meta.js.target[target].scripts = Meta.js.scripts.base.concat(pluginsScripts);
if (target === 'nodebb.min.js') {
Meta.js.target[target].scripts = Meta.js.target[target].scripts.concat(Meta.js.scripts.rjs);
2016-01-18 15:17:21 -05:00
}
Meta.js.target[target].scripts = Meta.js.target[target].scripts.map(function(script) {
return path.relative(basePath, script).replace(/\\/g, '/');
2014-07-04 18:20:40 -04:00
});
2016-01-18 15:17:21 -05:00
callback();
2014-07-04 18:20:40 -04:00
});
};
2016-01-18 14:05:53 -05:00
Meta.js.killMinifier = function() {
2014-07-04 18:20:40 -04:00
if (Meta.js.minifierProc) {
Meta.js.minifierProc.kill('SIGTERM');
}
};
Meta.js.commitToFile = function(target, callback) {
2016-01-18 15:17:21 -05:00
fs.writeFile(path.join(__dirname, '../../public/' + target), Meta.js.target[target].cache, function (err) {
2015-06-15 14:54:28 -04:00
if (err) {
winston.error('[meta/js] ' + err.message);
process.exit(0);
}
2015-06-15 14:54:28 -04:00
emitter.emit('meta:js.compiled');
callback();
});
};
2016-01-18 15:17:21 -05:00
Meta.js.getFromFile = function(target, callback) {
var scriptPath = path.join(__dirname, '../../public/' + target),
mapPath = path.join(__dirname, '../../public/' + target + '.map'),
paths = [scriptPath];
2016-01-18 15:17:21 -05:00
2015-09-29 18:22:41 -04:00
file.exists(scriptPath, function(exists) {
if (!exists) {
winston.warn('[meta/js] ' + target + ' not found on disk, re-minifying');
2016-01-18 15:17:21 -05:00
Meta.js.minify(target, callback);
2015-09-29 18:22:41 -04:00
return;
}
2015-09-29 18:22:41 -04:00
if (nconf.get('isPrimary') !== 'true') {
return callback();
}
2015-09-29 18:22:41 -04:00
file.exists(mapPath, function(exists) {
if (exists) {
paths.push(mapPath);
}
2015-09-29 18:22:41 -04:00
async.map(paths, fs.readFile, function(err, files) {
2016-08-16 19:46:59 +02:00
if (err) {
return callback(err);
}
2016-01-18 15:17:21 -05:00
Meta.js.target[target] = {
cache: files[0],
map: files[1] || ''
};
2015-09-29 18:22:41 -04:00
emitter.emit('meta:js.compiled');
callback();
});
});
});
};
2016-01-18 14:05:53 -05:00
function setupDebugging() {
/**
* Check if the parent process is running with the debug option --debug (or --debug-brk)
*/
var forkProcessParams = {};
if(global.v8debug || parseInt(process.execArgv.indexOf('--debug'), 10) !== -1) {
/**
* use the line below if you want to debug minifier.js script too (or even --debug-brk option, but
* you'll have to setup your debugger and connect to the forked process)
*/
//forkProcessParams = {execArgv: ['--debug=' + (global.process.debugPort + 1), '--nolazy']};
/**
* otherwise, just clean up --debug/--debug-brk options which are set up by default from the parent one
*/
forkProcessParams = {execArgv: []};
}
return forkProcessParams;
}
2015-10-20 22:54:32 -04:00
};