nodejs項目總結


前幾天花了3天時間,搭建、開發了一個包含客戶端、cms、server端的項目,也因着以前有php的開發經驗,以及sql的設計和應用能力,倒也沒遇到什么阻礙。至於項目結構搭建(架構),也是共通的,以模塊化、便於協作、擴展為前提。而構建工具的搭建,也只是nodejs的server端稍陌生,掌握了思路,也就簡單了。

一、技術棧

vue全家桶 + element-ui + axios + sass + webpack + ES6/ES7 + nodejs(express) + mongodb(mongoose) + sentry

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’;轉換方法有多種:

  • a、window.URLSearchParams:存在兼容性問題;
  • b、Qs.stringify():將對象轉換成url的形式。

tips:服務端如何獲取數據呢?如果服務端為nodejs,可使用body-parse中間件。可通過其extened屬性來設置,將post/update的數據轉換成對象;在取req數據時,需使用req.body.paramsName而非get方法中的req.query.paramsName。

ES6/7: 因babel的存在,可以更好的使用ES6/7的特性;如結構解析、rest、promise、模塊管理、async/await、symbol、set等。同時由於nodejs為事件循環機制,通過使用async/await,來獲取返回結果,其雖為同步語法,但並非真正的同步,不會影響並發(nodejs的優勢)。可通過try{}catch{}來捕獲await失敗的error(async/await的實質為promise的封裝,遇到reject的情況,可使用catch來捕獲),代碼如下:

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(); 執行下一個中間件},如:

// 當訪問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的實例,我將其視為為一個文檔,對應關系型數據庫中的表。

二、目錄結構

結構圖

2.1、build、cms-build

分別為client、cms在dev、production環境下的webpack配置。其中dev環境下的幾個重要的中間件介紹如下:

  • webpack-hot-middleware:模塊熱加載;
  • webpack-dev-middleware:將編譯后的內容存入內存中;
  • http-proxy-middleware:實現接口代理,可在本地環境下,跨域訪問其他接口:如Rap api之類;
  • connect-history-api-fallback:可控制刷新時,如果路由不存在,則訪問前端路由。

2.2、 client、cms

分別為客戶端、CMS 的源碼,其子目錄如圖所示,相應的文件夾內容為:

  • api:保存接口api和axios的封裝,在這里將處理統一的請求超時等錯誤,對接口名稱進行統一管理;
  • assets:保存樣式,reset.scss、common.scss、style.scss,其中的style.scss中保存着統一變量(如$mainBgColor、$mainFontColor、$mainBorderColor、$designWidth等)、minxin、function等;
  • components:公共組件庫;
  • libs:utils.js、preload.js等工具函數、插件等;
  • router:路由;(路由的按需加載等以前整理過,不贅述);
  • store:vuex;(vuex的模塊化也整理過了,不贅述);
  • views:vue業務組件。

2.3、config

各生產環境下的webpack區別化配置信息及本地開發路由代理配置信息。

2.4、public

cms:為CMS 在production環境下的編譯生成,當nodejs server端捕獲到/cms/*的路徑時(cms頁面刷新時產生),導向該文件夾;

main:為client 在production環境下的編譯生成,當nodejs server端捕獲到/pages/*的路徑時(client頁面刷新時產生),導向該文件夾;

2.5、server

通過nodejs的express框架搭建的服務端,對client\cms 的api及頁面訪問提供數據和文件等資源服務。

  • **controller: **處理業務,包括res的數據校驗、格式化處理等;
  • models:數據庫操作集合;包含scheme、model等的聲明、定義等;
  • libs:utils、msg(errorMsg、code等)等公共插件、工具函數的統一管理;
  • router:express的路由,分為api、cms 的頁面響應、client的頁面響應等
  • db.js:數據庫的管理(連接等)
  • app.js:服務器的靜態服務、cookie、session等配置和監聽;
  • index.js:注冊babel及babel解析的相應配置,包括忽略.babelrc文件、commonjs編譯、異步支持等;加載執行app;通過node ./server/index.js運行服務端。該方法為一種較為簡單的編譯方法,使得支持ES6/7,當然也可以通過webpack解析得到nodejs的執行腳本,但需注意在webpack中設置target: 'node'屬性,這樣編譯生成的腳本node才能運行。在實施ssr的時候,可使用webpack編譯解析的方式,視項目需要而定。如下:
// 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');

2.6、upload

為文件、圖片上傳后的存放位置,使用express的靜態服務器方法進行處理,可通過http進行訪問。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM