app.use 用来注册中间件,先收集起来
遇到 http 请求,根据 path 和 method 判断触发哪些
实现 next 机制,即上一个通过next触发下一个
const http = require('http')
const slice = Array.prototype.slice
class LikeExpress {
constructor() {
this.routes = {
all: [],
get: [],
post: []
}
}
register(path) {
const info = {}
if (typeof path === 'string') {
info.path = path
info.stack = slice.call(arguments, 1)
} else {
info.path = '/'
info.stack = slice.call(arguments, 0)
}
return info
}
use(){
const info = this.register.apply(this, arguments)
this.routes.all.push(info)
}
get() {
const info = this.register.apply(this, arguments)
this.routes.get.push(info)
}
post() {
const info = this.register.apply(this, arguments)
this.routes.post.push(info)
}
match(method, url) {
let stack = []
if (url === '/favicon.ico') {
return stack
}
let curRoutes = []
curRoutes = curRoutes.concat(this.routes.all)
curRoutes = curRoutes.concat(this.routes[method])
curRoutes.forEach(routrInfo => {
if (url.indexOf(routrInfo.path) === 0) {
stack = stack.concat(routrInfo.stack)
}
})
return stack
}
handle(req, res, stack) {
const next = () => {
const middleware = stack.shift()
if (middleware) {
middleware(req, res, next)
}
}
next()
}
callback() {
return (req, res) => {
res.json = data => {
res.setHeader('Content-type', 'application/json')
res.end(
JSON.stringify(data)
)
}
const url = req.url
const method = req.method.toLowerCase()
const resultList = this.match(method, url)
this.handle(req, res, resultList)
}
}
listen(...args) {
const server = http.createServer(this.callback())
server.listen(...args)
}
}
module.exports = () => {
return new LikeExpress()
}
const express = require('./express/like-express')
const app = express()
app.use((req, res, next) => {
console.log('请求开始...', req.method, req.url)
next()
})
app.use((req, res, next) => {
console.log('处理 cookie ...')
req.cookie = {
userId: 'abc123'
}
next()
})
app.use('/api', (req, res, next) => {
console.log('处理 /api 路由')
next()
})
app.get('/api', (req, res, next) => {
console.log('get /api 路由')
next()
})
function loginCheck(req, res, next) {
setTimeout(() => {
console.log('模拟登陆成功')
next()
})
}
app.get('/api/get-cookie', loginCheck, (req, res, next) => {
console.log('get /api/get-cookie')
res.json({
errno: 0,
data: req.cookie
})
})
app.listen(8000, () => {
console.log('server is running on port 8000')
})