Express框架实现原理

一、Express 源码的目录结构

在这里插入图片描述
首先,会去package.json项目(包)描述文件中寻找main属性的值,
main:入口文件。这个main的值就是入口文件所在的路径。
在这里插入图片描述

这里并没有配置main属性的值,默认会去找index.js文件作为入口文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

二、快速体验

在这里插入图片描述
在这里插入图片描述

const http = require('http')
const url = require('url')
const routes = [/*{ path: '', method: '', handler: () => {} }*/]
function createApplication() {
    
    
    return {
    
    
        get (path, handler) {
    
    
            routes.push({
    
    
                path,
                method: 'get',
                handler
            })
        },
        listen (...args) {
    
    
            const server = http.createServer((req, res) => {
    
    
                const {
    
     pathname } = url.parse(req.url)
                const method = req.method.toLowerCase()
                const route = routes.find(route => route.path === pathname && route.method === method)
                if (route) {
    
    
                    return route.handler(req, res)
                }
                res.end('404 Not Found.')
            })
            server.listen(...args)
        }
    }
}
module.exports = createApplication

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、抽取App模块

在这里插入图片描述

在这里插入图片描述

const http = require('http')
const url = require('url')
function App() {
    
    
    this.routes = []
}
// const routes = [/*{ path: '', method: '', handler: () => {} }*/]
App.prototype.get = function (path, handler) {
    
    
    this.routes.push({
    
    
        path,
        method: 'get',
        handler
    })
}
App.prototype.listen = function (...args) {
    
    
    const server = http.createServer((req, res) => {
    
    
        const {
    
    pathname} = url.parse(req.url)
        const method = req.method.toLowerCase()
        const route = this.routes.find(route => route.path === pathname && route.method === method)
        if (route) {
    
    
            return route.handler(req, res)
        }
        res.end('404 Not Found.')
    })
    server.listen(...args)

}
module.exports = App

四、提取路由模块

在这里插入图片描述

const url = require('url')

let Router = function Router() {
    
    
    this.stack = []
}

Router.prototype.get = function(path, handler){
    
    
    this.stack.push({
    
    
        path,
        method: 'get',
        handler
    })
}
Router.prototype.handle = function(req, res){
    
    
    const {
    
    pathname} = url.parse(req.url)
    const method = req.method.toLowerCase()
    const route = this.stack.find(route => route.path === pathname && route.method === method)
    if (route) {
    
    
        return route.handler(req, res)
    }

    res.end('404 Not Found.')
}
module.exports = Router

在这里插入图片描述

const http = require('http')
const Router = require('./router/index.js')
let App = function App() {
    
    
    this._router = new Router()
}
// 把路由收集起来
App.prototype.get = function (path, handler) {
    
    
    this._router.get(path, handler)
}
App.prototype.listen = function (...args) {
    
    
    const server = http.createServer((req, res) => {
    
    
        this._router.handle(req, res)
    })
    server.listen(...args)
}
module.exports = App

五、处理不同的请求方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

六、更强大的路由路径匹配模式(基本实现)

在这里插入图片描述
在这里插入图片描述

const url = require('url')
const methods = require('methods')
const pathRegexp = require('path-to-regexp')
let Router = function Router() {
    
    
    this.stack = []
}
methods.forEach(method => {
    
    
    // Router.prototype.get = function(path, handler){
    
    
    Router.prototype[method] = function(path, handler){
    
    
        this.stack.push({
    
    
            path,
            method,
            handler
        })
    }
})
Router.prototype.handle = function(req, res){
    
    
    const {
    
    pathname} = url.parse(req.url)
    const method = req.method.toLowerCase()
    const route = this.stack.find(route => {
    
    
        const keys = []
        const regexp = pathRegexp(route.path, keys, {
    
    })
        const match = regexp.exec(pathname)
        return match && route.method === method
    })
    if (route) {
    
    
        return route.handler(req, res)
    }
    res.end('404 Not Found.')
}
module.exports = Router

七、处理动态路由路径参数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

const url = require('url')
const methods = require('methods')
const pathRegexp = require('path-to-regexp')
let Router = function Router() {
    
    
    this.stack = []
}
methods.forEach(method => {
    
    
    // Router.prototype.get = function(path, handler){
    
    
    Router.prototype[method] = function(path, handler){
    
    
        this.stack.push({
    
    
            path,
            method,
            handler
        })
    }
})
Router.prototype.handle = function(req, res){
    
    
    const {
    
    pathname} = url.parse(req.url)
    const method = req.method.toLowerCase()
    const route = this.stack.find(route => {
    
    
        const keys = []
        const regexp = pathRegexp(route.path, keys, {
    
    })
        const match = regexp.exec(pathname)
        console.log('keys=>', keys)
        console.log('match=>', match)
        if (match) {
    
    
            req.params = req.params || {
    
    }
            keys.forEach((key, index) => {
    
    
                req.params[key.name] = match[index + 1]
            })
        }
        return match && route.method === method
    })
    if (route) {
    
    
        return route.handler(req, res)
    }
    res.end('404 Not Found.')
}
module.exports = Router

八、提取Layer处理模块

在这里插入图片描述
在这里插入图片描述

const url = require('url')
const methods = require('methods')
const Layer = require('./layer.js')
let Router = function Router() {
    
    
    this.stack = []
}
methods.forEach(method => {
    
    
    // Router.prototype.get = function(path, handler){
    
    
    Router.prototype[method] = function(path, handler){
    
    
        const layer = new Layer(path ,handler)
        layer.method = method
        this.stack.push(layer)
    }
})
Router.prototype.handle = function(req, res){
    
    
    const {
    
    pathname} = url.parse(req.url)
    const method = req.method.toLowerCase()
    const route = this.stack.find(layer => {
    
    
        const match = layer.match(pathname)
        if(match) {
    
    
            req.params = req.params || {
    
    }
            Object.assign(req.params, layer.params)
        }
        return match && layer.method === method
    })
    if (route) {
    
    
        return route.handler(req, res)
    }
    res.end('404 Not Found.')
}
module.exports = Router

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44827418/article/details/119487286