1. Convention over Configuration

  1. Preset the default configuration
  2. Generate configurations based on custom conventions
  3. Only special configurations are required
  4. The goal is to simplify the configuration by doing little convention generation code logic

2. MVC architecture of Egg

  1. Controller: The control layer that interacts with view, model, and serive to perform database operations
  2. Service: General business logic layer, SMS/email, image upload encapsulation, or access to the database
  3. Model: Database persistence operation
  4. View: The view layer, generally egg only provides services, does not do HTML output
  • Router: Distributes different controller control layers uniformly through routes.

3. Structure directory

3. Implement the architecture diagram yourself

  1. JGG unified hypervisor entry bus, including KOA instantiation and startup, jGG-Loader loaded out of all module functions
  2. Jgg-loader implements folder traversal, loading all classes under the folder, key value and method mapping
  3. All modules are passed in via JGG instance $app for data sharing

4. Specific code implementation

// KoA koa- Router node-schedule sequelize
//index.js
const jgg = require("./jgg")
const app = new jgg()
app.start(3000)

//jgg.js
const koa =  require('koa')
const {initRoute,initController,initService,initConfig,initSchedule} = require('./jgg-loader')
class jgg {
    constructor(conf){
        this.$app = new koa(conf)
        initConfig(this)
        initSchedule(this)
        this.$service = initService(this)
        this.$ctrl = initController(this)
        this.$app.use(initRoute(this).routes())
    }
    start(port){
        this.$app.listen(port, () = > {
            console.log("Server is up, port.",port)
        })
    }
}
module.exports = jgg

//jgg-loader.js
const fs = require('fs')
const path = require('path')
const Router = require('koa-router')

function load(dir,cb) {
    console.log("dir",dir)
    const url = path.resolve(__dirname,dir)
    const files = fs.readdirSync(url)
    files.forEach( filename= > {
        // remove the suffix
        filename = filename.replace('.js'.' ')
        // Import the file
        const file = require(url + '/' + filename)
        cb(filename, file)
    })
}
function initRoute(app) {
    const router = new Router()
    load("routes".(filename,fileObj) = > {
        console.log(filename,fileObj)
        if(typeof fileObj === 'function') {
            fileObj = fileObj(app)
        }
        let prefix = filename === 'index' ? ' ': "/" + filename
        Object.keys(fileObj).forEach( key= > {
            let [method,path] = key.split("") 
            console.log('Mapping address${method.toLocaleUpperCase()} ${prefix}${path}`)
            console.log("fileObj ",fileObj)
            let func = fileObj[key] 
            router[method](prefix + path,async ctx => {
                app.ctx = ctx
                await func(app)
            }) 
            
        })
    })
    return router;
}
function initController(app) {
    let controllers = []
    load("controllers".(filename,fileObj) = > {
            controllers[filename] = fileObj(app)
    })
    return controllers;
}
function initService(app) {
    let services = []
    load("service".(filename,fileObj) = > { 
            services[filename] = fileObj(app)
    })
    return services;
}

/ / timer
const schedule = require("node-schedule")
function initSchedule(app) {
    load("schedule".(filename,fileObj) = >{ schedule.scheduleJob(fileObj.interval, fileObj.handler); })}const Sequelize = require('sequelize')
function initConfig(app) {
    load('conf'.(filename, conf) = > {
        if (conf.db) {
            app.$db = new Sequelize(conf.db)

            // Load the model
            app.$model = {}
            load('model'.(filename, { schema, options }) = > {
                app.$model[filename] = app.$db.define(filename, schema, options)
            })
            app.$db.sync()
        }

        if (conf.middleware) {
            conf.middleware.forEach(mid= > {
                const midPath = path.resolve(__dirname, 'middleware', mid)
                app.$app.use(require(midPath))
            })
        }
    })
}
module.exports = {
    initRoute,initController,initService,initConfig,initSchedule
}
//routes/index.js
module.exports = (app) = > ({
    "get /" :  app.$ctrl.home.index,
    "get /detail" : app.$ctrl.home.detail,
})
//routes/user.js
module.exports = (app) = > ({
    "get /aaa": async app => {
        const name = await app.$service.user.getName()
        app.ctx.body = "Xxx111 users" + name;
      },
      
  // /user/info
  "get /info": app= > {
    app.ctx.body = "XXX user age"+ app.$service.user.getAge(); }})//controller/home.js
module.exports = (app) = > ({
    index :  async app => {
        // const name = await app.$service.user.getName()
        // app.ctx.body = "con" + name;
        app.ctx.body = await app.$model.user.findAll()
      },

   
    detail : async app => {
        const name = await app.$service.user.getAge()
        app.ctx.body = "con"+ name; }})//service/user.js
const delay = (data, tick) = > new Promise(resolve= > {
    setTimeout(() = > {
        resolve(data)
    }, tick)
})

module.exports = (app) = > ({
    getName() { 
       return   app.$model.user.findAll()
    },
    getAge() {
        return 20}})//model/user.js
const { STRING } = require("sequelize");
module.exports = {
  schema: {
    name: STRING(30)},options: {
    timestamps: false}};//conf/index.js Configuration information
module.exports = {
    db: {
        dialect: 'mysql'.host: '81.71. XXX. XXX'.database: 'xxxx'.username: 'root'.password: 'xxxx'
    },
    middleware: ['logger']}//middleware/logger.js
module.exports = async (ctx, next) => {
    console.log(ctx.method + "" + ctx.path);
    const start = new Date(a);await next();
    const duration = new Date() - start;
    console.log(
        ctx.method + "" + ctx.path + "" + ctx.status + "" + duration + "ms"
    );
};
//schedule/log.js
module.exports = {
    interval:'*/3 * * * * *'.handler(){
        console.log('Timed task heh heh every three seconds'+ new Date()}}Copy the code