From 3e033043f3afe1fd7ef00e671920d5b23f34ab44 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 24 Aug 2014 17:46:22 -0400 Subject: [PATCH] on-demand reloading of client-side assets --- src/meta/js.js | 187 ++++++++++++++++++++++++--------------------- src/routes/meta.js | 4 +- 2 files changed, 102 insertions(+), 89 deletions(-) diff --git a/src/meta/js.js b/src/meta/js.js index 29c6f77880..0625738db9 100644 --- a/src/meta/js.js +++ b/src/meta/js.js @@ -19,35 +19,37 @@ module.exports = function(Meta) { hash: +new Date(), prepared: false, minFile: 'nodebb.min.js', - scripts: [ - 'vendor/jquery/js/jquery.js', - 'vendor/jquery/js/jquery-ui-1.10.4.custom.js', - 'vendor/jquery/timeago/jquery.timeago.min.js', - 'vendor/jquery/js/jquery.form.min.js', - 'vendor/jquery/serializeObject/jquery.ba-serializeobject.min.js', - 'vendor/jquery/deserialize/jquery.deserialize.min.js', - 'vendor/bootstrap/js/bootstrap.min.js', - 'vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js', - 'vendor/requirejs/require.js', - 'vendor/bootbox/bootbox.min.js', - 'vendor/tinycon/tinycon.js', - 'vendor/xregexp/xregexp.js', - 'vendor/xregexp/unicode/unicode-base.js', - 'vendor/buzz/buzz.min.js', - '../node_modules/templates.js/lib/templates.js', - 'src/utils.js', - 'src/app.js', - 'src/ajaxify.js', - 'src/variables.js', - 'src/widgets.js', - 'src/translator.js', - 'src/helpers.js', - 'src/overrides.js' - ] + scripts: { + base: [ + 'public/vendor/jquery/js/jquery.js', + 'public/vendor/jquery/js/jquery-ui-1.10.4.custom.js', + 'public/vendor/jquery/timeago/jquery.timeago.min.js', + 'public/vendor/jquery/js/jquery.form.min.js', + 'public/vendor/jquery/serializeObject/jquery.ba-serializeobject.min.js', + 'public/vendor/jquery/deserialize/jquery.deserialize.min.js', + 'public/vendor/bootstrap/js/bootstrap.min.js', + 'public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js', + 'public/vendor/requirejs/require.js', + 'public/vendor/bootbox/bootbox.min.js', + 'public/vendor/tinycon/tinycon.js', + 'public/vendor/xregexp/xregexp.js', + 'public/vendor/xregexp/unicode/unicode-base.js', + 'public/vendor/buzz/buzz.min.js', + './node_modules/templates.js/lib/templates.js', + 'public/src/utils.js', + 'public/src/app.js', + 'public/src/ajaxify.js', + 'public/src/variables.js', + 'public/src/widgets.js', + 'public/src/translator.js', + 'public/src/helpers.js', + 'public/src/overrides.js' + ] + } }; Meta.js.loadRJS = function(callback) { - var rjsPath = path.join(__dirname, '../..', '/public/src'); + var rjsPath = path.join(__dirname, '../../public/src'); async.parallel({ forum: function(next) { @@ -65,75 +67,53 @@ module.exports = function(Meta) { rjsFiles = rjsFiles.filter(function(file) { return file.match('admin') === null; }).map(function(file) { - return path.join('src', file.replace(rjsPath, '')); + return path.join('public/src', file.replace(rjsPath, '')); }); - Meta.js.scripts = Meta.js.scripts.concat(rjsFiles); + Meta.js.scripts.rjs = rjsFiles; callback(); }); }; Meta.js.prepare = function (callback) { - plugins.fireHook('filter:scripts.get', Meta.js.scripts, function(err, scripts) { - var jsPaths = scripts.map(function (jsPath) { - jsPath = path.normalize(jsPath); - - if (jsPath.substring(0, 7) === 'plugins') { - var matches = _.map(plugins.staticDirs, function(realPath, mappedPath) { - if (jsPath.match(mappedPath)) { - return mappedPath; - } else { - return null; - } - }).filter(function(a) { return a; }); - - if (matches.length) { - var relPath = jsPath.slice(('plugins/' + matches[0]).length), - pluginId = matches[0].split(path.sep)[0]; - - return plugins.staticDirs[matches[0]] + relPath; - } else { - winston.warn('[meta.scripts.get] Could not resolve mapped path: ' + jsPath + '. Are you sure it is defined by a plugin?'); - return null; - } + async.parallel([ + async.apply(Meta.js.loadRJS), // Require.js scripts + async.apply(getPluginScripts), // plugin scripts via filter:scripts.get + function(next) { // client scripts via "scripts" config in plugin.json + var pluginsScripts = [], + pluginDirectories = [], + clientScripts = []; + + pluginsScripts = plugins.clientScripts.filter(function(path) { + if (path.indexOf('.js') !== -1) { + return true; } else { - return path.join(__dirname, '../..', '/public', jsPath); + pluginDirectories.push(path); + return false; } }); - Meta.js.scripts = jsPaths.filter(function(path) { - return path !== null; - }); + // Add plugin scripts + Meta.js.scripts.client = pluginsScripts; - var pluginDirectories = []; - - plugins.clientScripts = plugins.clientScripts.filter(function(path) { - if (path.indexOf('.js') !== -1) { - return true; - } else { - pluginDirectories.push(path); - return false; - } - }); - - // Add plugin scripts - Meta.js.scripts = Meta.js.scripts.concat(plugins.clientScripts); - - async.each(pluginDirectories, function(directory, next) { - utils.walk(directory, function(err, scripts) { - Meta.js.scripts = Meta.js.scripts.concat(scripts); - next(err); - }); - }, function(err) { - // Translate into relative paths - Meta.js.scripts = Meta.js.scripts.map(function(script) { - return path.relative(path.resolve(__dirname, '../..'), script).replace(/\\/g, '/'); - }); + // Add plugin script directories + async.each(pluginDirectories, function(directory, next) { + utils.walk(directory, function(err, scripts) { + Meta.js.scripts.client = Meta.js.scripts.client.concat(scripts); + next(err); + }); + }, next); + } + ], function(err) { + if (err) return callback(err); - Meta.js.prepared = true; - callback(err); + // Convert all scripts to paths relative to the NodeBB base directory + var basePath = path.resolve(__dirname, '../..'); + Meta.js.scripts.all = Meta.js.scripts.base.concat(Meta.js.scripts.rjs, Meta.js.scripts.plugin, Meta.js.scripts.client).map(function(script) { + return path.relative(basePath, script).replace(/\\/g, '/'); }); + callback(); }); }; @@ -183,13 +163,11 @@ module.exports = function(Meta) { } }); - Meta.js.loadRJS(function() { - Meta.js.prepare(function() { - minifier.send({ - action: 'js', - minify: minify, - scripts: Meta.js.scripts - }); + Meta.js.prepare(function() { + minifier.send({ + action: 'js', + minify: minify, + scripts: Meta.js.scripts.all }); }); }; @@ -199,4 +177,39 @@ module.exports = function(Meta) { Meta.js.minifierProc.kill('SIGTERM'); } }; + + function getPluginScripts(callback) { + plugins.fireHook('filter:scripts.get', [], function(err, scripts) { + if (err) callback(err, []); + + var jsPaths = scripts.map(function (jsPath) { + jsPath = path.normalize(jsPath); + + // if (jsPath.substring(0, 7) === 'plugins') { + var matches = _.map(plugins.staticDirs, function(realPath, mappedPath) { + if (jsPath.match(mappedPath)) { + return mappedPath; + } else { + return null; + } + }).filter(function(a) { return a; }); + + if (matches.length) { + var relPath = jsPath.slice(('plugins/' + matches[0]).length), + pluginId = matches[0].split(path.sep)[0]; + + return plugins.staticDirs[matches[0]] + relPath; + } else { + winston.warn('[meta.scripts.get] Could not resolve mapped path: ' + jsPath + '. Are you sure it is defined by a plugin?'); + return null; + } + // } else { + // return path.join(__dirname, '../..', jsPath); + // } + }); + + Meta.js.scripts.plugin = jsPaths.filter(Boolean); + callback(); + }); + }; }; \ No newline at end of file diff --git a/src/routes/meta.js b/src/routes/meta.js index f0d9aa85b2..76cefadf0e 100644 --- a/src/routes/meta.js +++ b/src/routes/meta.js @@ -35,8 +35,8 @@ function setupPluginSourceMapping(app) { development mode (`./nodebb dev`) */ var routes = plugins.clientScripts, - mapping, - prefix = __dirname.split(path.sep).length - 1; + prefix = __dirname.split(path.sep).length - 1, + mapping; routes.forEach(function(route) { mapping = '/' + route.split(path.sep).slice(prefix).join('/');