diff --git a/Gruntfile.js b/Gruntfile.js
index 36c054445f..0621f8c1a8 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -57,7 +57,7 @@ module.exports = function(grunt) {
files: ['public/**/*.less', 'node_modules/nodebb-*/*.less', 'node_modules/nodebb-*/*/*.less', 'node_modules/nodebb-*/*/*/*.less', 'node_modules/nodebb-*/*/*/*/*.less']
},
clientUpdated: {
- files: ['public/src/**/*.js', 'node_modules/nodebb-*/*.js', 'node_modules/nodebb-*/*/*.js', 'node_modules/nodebb-*/*/*/*.js', 'node_modules/nodebb-*/*/*/*/*.js', 'node_modules/templates.js/lib/templates.js']
+ files: ['public/src/**/*.js', '!public/src/modules/*.js', 'node_modules/nodebb-*/*.js', 'node_modules/nodebb-*/*/*.js', 'node_modules/nodebb-*/*/*/*.js', 'node_modules/nodebb-*/*/*/*/*.js', 'node_modules/templates.js/lib/templates.js']
},
serverUpdated: {
files: ['*.js', 'install/*.js', 'src/**/*.js']
diff --git a/package.json b/package.json
index 5dcb5e8cf8..5ff036175a 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"autoprefixer": "^6.2.3",
"bcryptjs": "~2.3.0",
"body-parser": "^1.9.0",
+ "chart.js": "^1.0.2",
"colors": "^1.1.0",
"compression": "^1.1.0",
"connect-ensure-login": "^0.1.1",
diff --git a/public/src/admin/general/dashboard.js b/public/src/admin/general/dashboard.js
index 930e996cdc..b23f57e3c8 100644
--- a/public/src/admin/general/dashboard.js
+++ b/public/src/admin/general/dashboard.js
@@ -1,7 +1,7 @@
"use strict";
-/*global define, ajaxify, app, socket, utils, bootbox, Chart, RELATIVE_PATH*/
+/*global define, ajaxify, app, socket, utils, bootbox, RELATIVE_PATH*/
-define('admin/general/dashboard', ['semver'], function(semver) {
+define('admin/general/dashboard', ['semver', 'Chart'], function(semver, Chart) {
var Admin = {},
intervals = {
rooms: false,
diff --git a/public/src/admin/manage/category.js b/public/src/admin/manage/category.js
index a845b59790..32a4c99e9b 100644
--- a/public/src/admin/manage/category.js
+++ b/public/src/admin/manage/category.js
@@ -1,12 +1,13 @@
"use strict";
-/*global define, app, socket, ajaxify, RELATIVE_PATH, bootbox, templates, Chart */
+/*global define, app, socket, ajaxify, RELATIVE_PATH, bootbox, templates */
define('admin/manage/category', [
'uploader',
'iconSelect',
'admin/modules/colorpicker',
- 'autocomplete'
-], function(uploader, iconSelect, colorpicker, autocomplete) {
+ 'autocomplete',
+ 'Chart'
+], function(uploader, iconSelect, colorpicker, autocomplete, Chart) {
var Category = {};
Category.init = function() {
diff --git a/src/meta.js b/src/meta.js
index 7a054b1836..8fec4c3444 100644
--- a/src/meta.js
+++ b/src/meta.js
@@ -62,6 +62,7 @@ var async = require('async'),
async.apply(plugins.reloadRoutes),
function(next) {
async.parallel([
+ async.apply(Meta.js.symlinkModules),
async.apply(Meta.js.minify, 'nodebb.min.js'),
async.apply(Meta.js.minify, 'acp.min.js'),
async.apply(Meta.css.minify),
diff --git a/src/meta/js.js b/src/meta/js.js
index 314e10a400..506d872f87 100644
--- a/src/meta/js.js
+++ b/src/meta/js.js
@@ -7,6 +7,7 @@ var winston = require('winston'),
_ = require('underscore'),
nconf = require('nconf'),
fs = require('fs'),
+ rimraf = require('rimraf'),
file = require('../file'),
plugins = require('../plugins'),
emitter = require('../emitter'),
@@ -43,6 +44,8 @@ module.exports = function(Meta) {
'public/src/variables.js',
'public/src/widgets.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',
@@ -77,10 +80,51 @@ module.exports = function(Meta) {
'public/src/modules/helpers.js',
'public/src/modules/sounds.js',
'public/src/modules/string.js'
+ ],
+
+ // modules listed below are symlinked to public/src/modules so they can be defined anonymously
+ modules: [
+ './node_modules/chart.js/Chart.js'
]
}
};
+ Meta.js.symlinkModules = function(callback) {
+ // Symlink all defined modules to /public/src/modules
+ var modulesLoaded = 0,
+ targetPath;
+
+ async.series([
+ function(next) {
+ async.each(Meta.js.scripts.modules, function(localPath, next) {
+ targetPath = path.join(__dirname, '../../public/src/modules', path.basename(localPath));
+
+ async.waterfall([
+ async.apply(fs.access, localPath, fs.R_OK),
+ async.apply(rimraf, targetPath),
+ async.apply(fs.link, localPath, targetPath)
+ ], function(err) {
+ if (err) {
+ winston.error('[meta/js] Could not symlink `' + localPath + '` to modules folder');
+ } else {
+ winston.verbose('[meta/js] Symlinked `' + localPath + '` to modules folder');
+ ++modulesLoaded;
+ }
+
+ next(err);
+ });
+ }, next);
+ }
+ ], function(err) {
+ if (err) {
+ winston.error('[meta/js] Encountered error while symlinking modules:' + err.message);
+ }
+
+ winston.verbose('[meta/js] ' + modulesLoaded + ' of ' + Meta.js.scripts.modules.length + ' modules symlinked');
+ callback(err);
+ });
+ };
+
Meta.js.minify = function(target, callback) {
if (nconf.get('isPrimary') !== 'true') {
if (typeof callback === 'function') {
diff --git a/src/views/admin/header.tpl b/src/views/admin/header.tpl
index 19b3b065cb..e445a66403 100644
--- a/src/views/admin/header.tpl
+++ b/src/views/admin/header.tpl
@@ -27,7 +27,6 @@
-
diff --git a/src/webserver.js b/src/webserver.js
index 4a46b54520..cf814feda9 100644
--- a/src/webserver.js
+++ b/src/webserver.js
@@ -92,6 +92,7 @@ function initializeNodeBB(callback) {
function(next) {
async.parallel([
async.apply(meta.templates.compile),
+ async.apply(meta.js.symlinkModules),
async.apply(!skipJS ? meta.js.minify : meta.js.getFromFile, 'nodebb.min.js'),
async.apply(!skipJS ? meta.js.minify : meta.js.getFromFile, 'acp.min.js'),
async.apply(!skipLess ? meta.css.minify : meta.css.getFromFile),