This is the second day of my participation in Gwen Challenge
Step1: Simple handwriting ultra simple version of KOA small frame (Pok) β¨
Simple functions implemented π
- Setting up the HTTP Service
- Simple route construction
- Middleware composition
- Request and Response encapsulation
Key points
- Context context. Js
File directory content π
- app.js
- pok.js
- context.js
- response.js
- router.js
Test file (app.js) π
const Pok = require('./pok')
const app = new Pok()
// ==============Router start================
const Router = require('./router')
const router = new Router()
router.get('/index'.async ctx => { ctx.body = 'index page'; });
router.get('/post'.async ctx => { ctx.body = 'post page'; });
router.get('/list'.async ctx => { ctx.body = 'list page'; });
router.post('/index'.async ctx => { ctx.body = 'post page'; });
app.use(router.routes());
// ==============Router end================
app.listen(3001.() = >{
console.log('Service started');
})
Copy the code
Encapsulate a koA-like framework, pokπ
// Introduce the base library
const http = require('http')
const context = require('./context')
const request = require('./request')
const response = require('./response')
//Pok
class Pok{
constructor(){
this.middlewares = []
}
listen(. args){
const server = http.createServer(async (req,res)=>{
// Create content context
const ctx = this.createContext(req,res);
// Merge middleware
const fn = this.compose(this.middlewares)
awaitfn(ctx) res.end(ctx.body) }) server.listen(... args) }use(middleware){
this.middlewares.push(middleware)
}
// Create content context
createContext(req,res){
const ctx = Object.create(context)
ctx.request = Object.create(request)
ctx.response = Object.create(response)
ctx.request.req = req
ctx.response.res = res
return ctx
}
/ / middleware
compose(middlewares){
return function(ctx){
return ds(0)
function ds(i){
let fn = middlewares[i]
if(! fn){return Promise.resolve()
}else{
return Promise.resolve(
fn(ctx,function next(){
return ds(i+1)})}}}}}module.exports = Pok
Copy the code
Route encapsulation (router.js) π
class Router {
constructor() {
this.stack = []
}
resigter(method, path, middleware) {
this.stack.push({method, path, middleware})
}
get(path, middleware) {
this.resigter('get', path, middleware)
}
post(path, middleware) {
this.resigter('post', path, middleware)
}
routes() {
let stock = this.stack;
return async function(ctx, next) {
let currentPath = ctx.url;
console.log(currentPath);
let route;
for (let i = 0; i < stock.length; i++) {
let item = stock[i];
console.log(item);
if (currentPath === item.path && item.method.indexOf(ctx.method) >= 0) {
// Determine path and method
route = item.middleware;
break; }}if (typeof route === 'function') {
route(ctx, next);
return;
}
awaitnext(); }; }}module.exports = Router
Copy the code
Request and Response encapsulation (request.js)π
module.exports = {
get url() {return this.req.url
},
get method() {return this.req.method.toLowerCase()
}
};
response.js
module.exports = {
get body() {return this._body
},
set body(val) {this._body = val
}
};
Copy the code
Context encapsulation (context.js) π
module.exports = {
get url() {
return this.request.url
},
get body() {
return this.response.body
},
set body(val) {this.response.body = val
},
get method() {
return this.request.method
}
}
Copy the code
Step2: simply write Egg framework to implement MVC layering (based on koa)
Simple functions implemented π
- Encapsulate KOA and implement MVC layering
Main contents π
- initRouter
- initController
- initService
- LoadConfig
- Updated…
Test file (app.js) π
const pgg = require('./pgg')
const app = new pgg()
app.start(3000) # Encapsulate an Egg-like framework PGGconst koa = require('koa');
const {initRouter, initController, initService,LoadConfig} = require('./pgg-loader')
class Pgg{
constructor(conf){
this.$app = new koa(conf)
LoadConfig(this)
this.$service = initService(this)
this.$ctrl = initController(this)
this.$router = initRouter(this)
// Mount the route
console.dir(this.$ctrl);
// Call the routes function
this.$app.use(this.$router.routes())
}
start(port){
this.$app.listen(port,() = >{
console.log(` server${port}Successful startup '); }}})module.exports = Pgg
Copy the code
Read different files (pgg-loader.js) π
const fs = require('fs')
const path = require('path')
const Router = require('koa-router')
const Sequelize = require('sequelize')
// Read files to convert method paths and functions into objects
function load(dir,cb) {
// Convert to absolute path
const url = path.resolve(__dirname,dir)
// Read the names of all files in the specified directory.
const files = fs.readdirSync(url)
// Walk through the file and read the contents
files.forEach(filename= >{
filename = filename.replace('.js'.' ')
const file= require(url+'/'+filename)
console.log(filename,'File name');
// File name
cb(filename,file)
})
}
// Initialize the routing page
function initRouter(app) {
const router = new Router()
// Initializes the routing file in the route file path
load("routes".(filename,routes) = >{
// index prefix processing
const prefix = filename === 'index'?' ':` /${filename}`
// Determine the route type
routes = typeof routes=== 'function'? routes(app):routes// Iterate over the add route configuration
Object.keys(routes) .forEach(key= >{
// Get the request method and path
const[method,path] = key.split(' ');
console.log(` ${method.toLocaleUpperCase()} ${prefix}${path}\n,${routes[key]}`);
router[method](prefix + path,async ctx=>{
app.ctx = ctx
await routes[key](ctx)
})
})
})
return router
}
// Control layer initialization
function initController(app) {
const controllers = {}
load('controller'.(filename,controller) = >{
controllers[filename] = controller(app)
})
return controllers
}
// Initialization of the service layer
function initService() {
const services = {}
load('service'.(filename,service) = >{
services[filename] = service
})
return services
}
// Configure persistence
function LoadConfig(app) {
load('config'.(filename,config) = >{
if(config.db){
app.$db = new Sequelize(config.db)
}
app.$model = {}
load('model'.(filename,{schema, options}) = >{ app.$model[filename] = app.$db.define(filename, schema, options) }); app.$db.sync(); })}// Initialization of the persistence layer
module.exports = {initRouter,initController,initService,LoadConfig}
Copy the code
I’ll put the file ingithubon