玩nodebb有些日子了。以前用的是v0.4.1版本,一直用着還不錯。但有朋友反應發帖時不能使用快捷鍵很麻煩,因此想加一個插件nodebb-plugin-shortcuts。可是使用插件後,論壇不能啓動,看了看最新提交是在7天前。猜測多是nodebb新版本修改了一些文件,插件作了適應性修改,因此想把nodebb升級到最新的v0.4.3版本。升級過程很順暢。以前也升過一次,可是由於有些問題,就回退了。今天順便解決一下問題,學習學習。javascript
如今的問題是右上角的登陸狀態有問題。css
正常的狀態:html
用chrome開發者工具查看右上角的元素屬性,獲得一個比較有特色的元素id名logged-in-menu
,而後做爲關鍵字在文件中搜索前端
在public目錄下的文件通常都是在客戶端引用的。以tpl結尾的是模板文件。多了一個.app.js.swp是由於我正在用vim編輯它。java
打開app.js後發現了這個函數:node
function updateOnlineStatus(uid) { socket.emit('user.isOnline', uid, function(err, data) { $('#logged-in-menu #user_label #user-profile-link>i').attr('class', 'fa fa-circle status ' + data.status); }); }
猜測這個函數使用socket.io與後臺通訊更新了用戶的登陸狀態。 因而在瀏覽器模擬了一下動做,發現data確實能獲取用戶的登陸狀態。可是這個函數只是改變了一下用戶在線或不在線的提示顏色。jquery
綠色就是在線,黑色就是離線。看來問題不是這裏,再找。git
nodebb的核心客戶端js文件叫作nodebb.min.js。但是在項目裏find,沒有這個文件。因而猜測多是動態生成的,做爲關鍵詞搜索了下github
最下面的兩個是服務端js文件,看名字應該是元變量的設置和路由。查看src/routes/meta.jsajax
<!-- lang: js --> "use strict"; ... meta = require('../meta'), ... function sendMinifiedJS(req, res, next) { return res.type('text/javascript').send(meta.js.cache); } function sendStylesheet(req, res, next) { res.type('text/css').send(200, meta.css.cache); } module.exports = function(app, middleware, controllers) { app.get('/stylesheet.css', sendStylesheet); app.get('/nodebb.min.js', sendMinifiedJS); ... };
確實是在src/meta.js中對靜態js、css文件作了壓縮並緩存到了各屬性的cache變量中。
<!-- lang: js --> ... Meta.js = { cache: undefined, prepared: false, scripts: [ 'vendor/jquery/js/jquery.js', ... 'src/app.js', ... ], minFile: 'nodebb.min.js', ... minify: function(minify) { // Prepare js for minification/concatenation var minifier = this.minifierProc = fork('minifier.js'); minifier.on('message', function(payload) { if (payload.action !== 'error') { winston.info('[meta/js] Compilation complete'); Meta.js.cache = payload.data; minifier.kill(); } else { winston.error('[meta/js] Could not compile client-side scripts!'); winston.error('[meta/js] ' + payload.error.message); minifier.kill(); process.exit(); } }); this.prepare(function() { minifier.send({ action: minify ? 'js.minify' : 'js.concatenate', scripts: Meta.js.scripts }); }); }, ... };
能夠看到public/src/app.js也在壓縮之列。
再去看看public/src/app.js吧。發現前幾行就定義了一個全局變量,裏邊記錄了用戶的基本信息,能夠試試。
如下是個人app變量:
username,uid居然都爲空!確定是有問題的。
再去nodebb官方社區登陸了下試試,果真有值!
繼續查看app.js。nodebb爲了作到實時通訊,大量使用了socket.io。
app變量的值在前端是在socket.on('event:connect')時被賦予的。
剛纔個人論壇裏app變量有空值多是由於升級過程當中沒有停機,session管理有異常致使的。
因而跟代碼到了src/socket.io/indexjs的io.sockets.on('connection')。
開始我覺得db.sessionStore.get(sessionID,function...)中的sessionID不對,由於我觀察redis中的sessino都是以sess:做爲前綴的。可是打印此處的sessionID並無帶sess:,還自覺得是地加了sess:,但是仍是不行。看了connect-redis(一個專門用redis作sessionStore的項目)的源碼才發現,在對redis進行get操做前,默認加了前綴sess:。
查了這麼久都沒什麼收穫,看來得換個方向了。
除了右上角的登陸狀態顯示有異常外,論壇右側的狀態統計功能也失效了。因而乎跟了一下代碼,發現如下語句報undefined。代碼位於node_modules/nodebb-widget-essentials/public/templates/forumstats.tpl。
// public/templates/forumstats.tpl ajaxify.register_events([ 'user.count', 'meta.getUsageStats', 'user.getActiveUsers' ]);
這個代碼屬於nodebb-widget-essentials。因而去github上看了一下是否有更新。發現上面代碼用如下代碼替換了。
$(window).on('action:ajaxify.start', function(ev) { socket.removeListener('user.count', updateUserCount); socket.removeListener('meta.getUsageStats', updateUsageStats); socket.removeListener('user.getActiveUsers', updateActiveUsers); });
忽然想到,本次升級的這些異常是否由於只對nodebb自己進行了升級,而忽略了各類依賴包和插件的升級呢?因而乎...npm update
。
重啓應用...問題消失...
呵呵...居然是由於這麼簡單的緣由...雖然是個低級錯誤,但仍是有必要注意一下的。順便贊一下nodebb的鬆耦合設計,自己只保留了不多的骨架而把比較獨立的功能都作成了各類widget、plugin,從而在具體功能的實現和個性化上及其地方便。
在升級成功以後,npm install nodebb-plugin-shortcuts
便可安裝快捷鍵,支持了包括髮帖等大量的快捷鍵。