前幾天花了3天時間,搭建、開發了一個包含客戶端、cms、server端的項目,也因着之前有php的開發經驗,以及sql的設計和應用能力,倒也沒遇到什麼阻礙。至於項目結構搭建(架構),也是共通的,以模塊化、便於協做、擴展爲前提。而構建工具的搭建,也只是nodejs的server端稍陌生,掌握了思路,也就簡單了。php
vue全家桶 + element-ui + axios + sass + webpack + ES6/ES7 + nodejs(express) + mongodb(mongoose) + sentrycss
element-ui:用來搭建CMS UI。前端
axios:服務端數據請求使用axios,而非vue-resource(已中止維護)。根據restful api的定義,使用其get/post/put/delete/(patch未使用)方法。在進行post和update(put、patch即update)時,須要將 content-type 由 ‘application/json’ 轉換成 ‘application/x-www-form-urlencoded’;轉換方法有多種:vue
tips:服務端如何獲取數據呢?若是服務端爲nodejs,可以使用body-parse中間件。可經過其extened屬性來設置,將post/update的數據轉換成對象;在取req數據時,需使用req.body.paramsName而非get方法中的req.query.paramsName。node
ES6/7: 因babel的存在,能夠更好的使用ES6/7的特性;如結構解析、rest、promise、模塊管理、async/await、symbol、set等。同時因爲nodejs爲事件循環機制,經過使用async/await,來獲取返回結果,其雖爲同步語法,但並不是真正的同步,不會影響併發(nodejs的優點)。可經過try{}catch{}來捕獲await失敗的error(async/await的實質爲promise的封裝,遇到reject的狀況,可以使用catch來捕獲),代碼以下:webpack
try { let admin = await adminModel.findOne({username}) // 依次驗證是否存在管理員和密碼,而後將admin_id存入session中(登陸機制) if (!admin) { rst.error = error.adminNotExist } else if (encryption(password).toString() != admin.password.toString()) { rst.error = error.passwordError } else { req.session.admin_id = admin['_id']; rst.success = true } } catch(err) { rst.error = error.default Raven.captureException(err); }
Express:是由路由和中間件構成一個的 web 開發框架,從本質上來講,一個 Express 應用就是在調用各類中間件。其中間件爲函數:function (req, res, next) {... // next(); 執行下一個中間件},如:ios
// 當訪問cms的api,獲取列表信息時,須要先驗證是否已登錄,如此才能獲取信息,不然訪問失敗 router.get('/api/cms/album', adminCtrl.checkLoginState, albumCtrl.findAlbum) checkLoginState: async (req, res, next) => { ... // 若是驗證成功則跳入下一個中間件,不然返回 if (rst.success) { next() } else { resCallback(res, rst) } }
mongodb:一種文檔型數據庫,相對穩定的關係型數據庫來講,在一致性等可能保證不足,不適合金融業務。mongoose的兩個關鍵方法:Schema:定義屬性的類型和默認值等;model:至關於schema的實例,我將其視爲爲一個文檔,對應關係型數據庫中的表。web
結構圖sql
分別爲client、cms在dev、production環境下的webpack配置。其中dev環境下的幾個重要的中間件介紹以下:mongodb
分別爲客戶端、CMS 的源碼,其子目錄如圖所示,相應的文件夾內容爲:
各生產環境下的webpack區別化配置信息及本地開發路由代理配置信息。
cms:爲CMS 在production環境下的編譯生成,當nodejs server端捕獲到/cms/*的路徑時(cms頁面刷新時產生),導向該文件夾;
main:爲client 在production環境下的編譯生成,當nodejs server端捕獲到/pages/*的路徑時(client頁面刷新時產生),導向該文件夾;
經過nodejs的express框架搭建的服務端,對client\cms 的api及頁面訪問提供數據和文件等資源服務。
// index.js require('babel-core/register')({ babelrc: 'false', presets: ['stage-3', 'env'], plugins: [ 'transform-runtime', "transform-async-to-generator", "transform-es2015-modules-commonjs" ] }); require('./app.js');
爲文件、圖片上傳後的存放位置,使用express的靜態服務器方法進行處理,可經過http進行訪問。