next + koa + mongodb 從搭建到部署(一)

前言

看了不少寫服務端渲染(next.js)的文章,但發現搜索的服務端渲染的案例都是一些比較簡單,或者不太系統的例子,若是作一個演示或者demo仍是能夠的,可是在實際應用上不利於分工協做,部署上線。明明能夠作大型項目殊不知怎麼去應用,因此帶着這些痛點和疑惑,決定本身作一套next + koa + mongodb 能夠應用到應用級項目的項目框架(此項目還在更新中),項目還在不斷優化中,但願你們能夠多多指點。css

話很少說,上圖先開始介紹下項目的規劃和想法node

項目介紹

這個是項目的首頁,應該你們都能看出來了,是一個模仿掘金的的我的博客項目。包含了基本的登陸,註冊,寫文章,展現文章。。。後續還會繼續添加新的功能。目標是發佈上線,不斷迭代,最終作一個成熟且完整的項目。git

項目結構

跟傳統的ssr項目同樣,分爲View層,和sever層,不熟悉的next.js,和koa.js的能夠先去腦補一下 next文檔&& koa文檔,view層後面會簡單說下,我們重點說一下server層的構建,sever層主要分爲apps.js(入口文件 app.js已廢棄),controller(接口定義,渲染的頁面配置),middleware(中間件),router(路由),token(登陸註冊時token定義)

  • 入口文件apps.js
const Koa = require('koa')
const next = require('next')
const koaRoute = require('./router')
const bodyParser = require('koa-bodyparser');
const middleware = require('./middleware')
const cors = require('koa2-cors');

const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()


app.prepare()
  .then(() => {
    const server = new Koa()
     //注入中間件
     middleware(server)
     server.use(bodyParser())
    //注入路由
    koaRoute(server,app,handle)
    server.listen(port, () => {
      console.log(`> Ready on http://localhost:${port}`)
    })
  })
複製代碼

1.middleware

apps.js入口文件比較簡單,由於主要邏輯封裝到組件中,先從middleware提及github

const bodyParser = require('koa-bodyparser');
const logger = () =>  {
    return async (ctx, next) => {
      const start = Date.now()
      bodyParser()
  
      await next()
  
      const responseTime = (Date.now() - start)
      console.log(`響應時間爲: ${responseTime / 1000}s`)
    }
  }
  
  module.exports = (app) => {
    app.use(logger())
  }
複製代碼

若是看過koa文檔會發現,無論使用路由和插件,都須要new Koa()之後再用use去調用,這裏只用到一個響應時間方法,之後可能會用到更多中間間,若是引入一個就要在入口引入一次會比較繁瑣,因此封裝通用方法,能夠繼續添加,只需在入口引入一次就能夠了。mongodb

2. controller

controller裏面主要是koa裏的路由管理,分爲接口管理(api)和視圖路由管理(view)以及數據庫管理(db.js),以及入口文件(index.js)。

api裏的getListInfor.js:數據庫

const DB = require('../db')
const loginInfor = (app) =>{
    return async (ctx, next) => {
       await DB.insert(ctx.request.body).then(res =>{
            ctx.response.body = {
               infor:'ok'
            }
       })
       
    }
}
module.exports =  loginInfor
複製代碼

view裏的home.jsapi

const home = (app) =>{
    return async (ctx, next) => {
        await app.render(ctx.req, ctx.res, '/home', ctx.query)
        ctx.respond = false
    }
}
module.exports = home
複製代碼

api.jsbash

const Monk = require('monk')
const url = 'mongodb://localhost:27017/home'; // Connection URL
const db  =  Monk(url)
const dbName = 'col'
const collection = db.get(dbName)

module.exports = collection

//本地用mongdb搭建的數據庫,調用方法用的monk插件,不瞭解的能夠去github搜索 
複製代碼

index.js:app

//VIEW
const index = require('./view/index')
const home = require('./view/home')
const editText = require('./view/editText')
const essay = require('./view/essay')
const myself = require('./view/myself')

//API
const getListInfor = require('./api/getListInfor')
const loginInfor   = require('./api/loginInfor')
const POST = 'post'
const GET  = 'get'


module.exports = {
    view:{// 不須要請求方式
        index,
        home,
        editText,
        essay,
        myself,
    },
    api:{
        getListInfor:{
            method:GET,
            getListInfor
        },
        loginInfor:{
            method:POST,
            loginInfor
        }
    }

  }
複製代碼

3.router

const router = require('./node_modules/koa-router')()
const Controller = require('../controller')

const koaRoute = (app,handle) =>{   //把view層和api層掛載到router
        // view 
        const {view,api} = Controller  
        for(item in view){
            let _name = null;
            let _moudle = null
            if(item == 'index'){
                _name = '/';
                _moudle = view['index']
            }else{
                _name = '/' + item;
                _moudle = view[item]
            }
            router.get(_name,_moudle(app))
        }
        //api 
        for(item in api){
           let  _method = api[item].method
           let _name    = '/' + item;
           let _moudle  = api[item][item]
          router[_method](_name,_moudle(app))
      }
        
          router.get('*', async ctx => {
            await handle(ctx.req, ctx.res)
            ctx.respond = false
          })
      
          return router.routes()  //啓動路由
      }

module.exports = (server,app,handle) =>{
    server.use(koaRoute(app,handle))
}
複製代碼

這時候能夠再看一下apps.js是怎麼引入的:cors

const app = next({ dev })
const handle = app.getRequestHandler()
const koaRoute = require('./router')


app.prepare()
  .then(() => {
    const server = new Koa()
    //注入路由
    koaRoute(server,app,handle)  // 至關於koa裏面app.use(router.routes()) 啓動路由......
複製代碼

未完待續。。。

相關文章
相關標籤/搜索