Node web 框架 - Express ( 200行实现基础功能,理解原理 )
Express 框架是基于 http 做一个一个 web 框架
具体做什么呢?
1、对 request 、response 进行封装,实现了一些方便简洁的方法
2、实现了 app.use 对 request 、response 进行处理
3、实现了 get 、post 等方法实现路由返回响应值的值
4、另外一些 render 等方法实现了使用模板引擎渲染页面
下面使用了 200 行代码展示了 use / get / post 的实现
const http = require('http') const regExpCompile = require('path-to-regexp') class Route { constructor(option) { // methods,path Object.assign(this, option) this.stack = [] } addLayer(method, handle) { const layer = { method, handle, } this.stack.push(layer) } dispatch(req, res, next) { const {stack} = this; const match = false; const layer = null const {method} = req let id = 0 let handle = null while (!handle && id < stack.length) { const layer = stack[id++] if (method.toLowerCase() === layer.method) { handle = layer.handle continue } } if (!handle) next && next() handle(req, res, next) } } class Layer { constructor(option, fn) { // path,name,regexp Object.assign(this, option) this.handle = fn } } class Router { constructor() { this.stack = [] } use(path, fn) { const layer = new Layer({ path, use: true, regexp: regExpCompile(path, []), }, fn) layer.route = null this.stack.push(layer) } route(path, fn, methods = []) { const route = new Route({ path }) methods.forEach(item => { route.addLayer(item, fn) }) const layer = new Layer({ path, regexp: regExpCompile(path, []), }, route.dispatch.bind(route)) layer.route = route this.stack.push(layer) } handle(req, res, callback) { const {url} = req const {stack} = this let idx = 0 next() function next() { let match = false let route = null let layer = null while (!match && idx < stack.length) { layer = stack[idx++] match = layer.regexp.exec(url) if (layer.use) match = true route = layer.route if (!match) continue if (!route) continue } if (!match) { callback && callback() return } layer.handle(req, res, next) } } } const app = { use: function (fn) { let router = this._router if (!router) { router = new Router() this._router = router } let path = '/' if (typeof fn !== 'function') { path = fn fn = arguments[1] } router.use(path, fn) }, get: function (fn) { let router = this._router if (!router) { router = new Router() this._router = router } let path = '/' if (typeof fn !== 'function') { path = fn fn = arguments[1] } router.route(path, fn, ['get']) }, post: function (fn) { let router = this._router if (!router) { router = new Router() this._router = router } let path = '/' if (typeof fn !== 'function') { path = fn fn = arguments[1] } router.route(path, fn, ['post']) }, all: function () { }, listen: function () { const _this = this const server = http.createServer(function (req, res) { _this._router.handle(req, res) }) server.listen.apply(server, arguments) } } app.use((req, res, next) => { req.test = 'test1' next() }) app.use((req, res, next) => { req.test2 = 'test2' next() }) app.get('/', (req, res) => { const tst = req.test const tst2 = req.test2 res.end('/' + tst + tst2) }) app.get('/get', (req, res) => { const tst = req.test const tst2 = req.test2 res.end('get' + tst + tst2) }) app.get('/test', (req, res) => { const tst = req.test const tst2 = req.test2 res.end('test' + tst + tst2) }) app.listen(3300)
代码仅供研究!
博客园小结巴巴: https://www.cnblogs.com/jiebba
感觉可以就推荐下吧!!
感觉可以就推荐下吧!!
感觉可以就推荐下吧!!
感觉可以就推荐下吧!!
感觉可以就推荐下吧!!