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 = methodthis.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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470348.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nginx集群_使用Nginx+Tomcat+keepalived 搭建高性能高可用性负载均衡集群

在互联网项目中,往往面临着高用户量、高并发的问题,造成服务器的压力非常大,特别是电商项目,以淘宝天猫为例,近年双十一的成交量屡创新高,可想而知淘宝天猫的服务器面临的并发量有多大,单一服务…

Nodejs之http模块详解

一、Web服务器 什么是Web服务器? 当应用程序(客户端)需要某一个资源时,可以向一个台服务器,通过Http请求获取到这个资源;提供资源的这个服务器,就是一个Web服务器; 目前有很多开源…

iOS开源照片浏览器框架SGPhotoBrowser的设计与实现

简介 近日在制作一个开源加密相册时附带着设计了一个照片浏览器,在进一步优化后发布到了GitHub供大家使用,该框架虽然没有MWPhotoBrowser那么强大,但是使用起来更为方便,操作更符合常规相册习惯,自定义和修改源码也十分…

Koa框架

一、认识Koa 前面我们已经学习了express,另外一个非常流行的Node Web服务器框架就是Koa。 Koa官方的介绍: koa:next generation web framework for node.js;koa:node.js的下一代web框架; 事实上&#x…

Node使用MySQL

一、认识mysql2 如何可以在Node的代码中执行SQL语句来,这里我们可以借助于两个库: mysql:最早的Node连接MySQL的数据库驱动;mysql2:在mysql的基础之上,进行了很多的优化、改进;目前相对来说&a…

java安装后在哪里打开_冷却塔声屏障安装后降噪效果不理想,原因出在哪里?...

现有冷却塔大部分产品都不能满足噪音环保标准,只有少数几种低吨位超低噪声型号的冷却塔可以满足少部分区域噪声标准要求。在一些商住混合区,冷却塔的出风口强烈的噪声和热气往往干扰附近居民不得安宁,所以冷却塔的噪声问题成为环境投诉的热点…

iOS10 权限崩溃问题

iOS10 权限崩溃问题 原文: http://blog.csdn.net/runleelrg/article/details/51673025 今天 手机升级了 iOS10 Beta,然后用正在开发的项目 装了个ipa包,发现点击有关 权限访问 直接Crash了,并在控制台输出了一些信息: This app h…

Koa框架——coderhub实战

https://github.com/zep03/koa-coderhub/commits/main 一、coderhub功能接口说明 Coderhub旨在创建一个程序员分享生活动态的平台。 完整的项目接口包括: 面向用户的业务接口;面向企业或者内部的后台管理接口; 完成的功能如下:…

python 协程_Python多任务协程

协程协程,又称微线程,纤程。英文名Coroutine。协程是python个中另外一种实现多任务的方式,只不过比线程更小占用更小执行单元(理解为需要的资源)。为啥说它是一个执行单元,因为它自带CPU上下文。这样只要在合适的时机,…

JavaScript高级之构造函数和原型

1.1 概述 在典型的 OOP 的语言中(如 Java),都存在类的概念,类就是对象的模板,对象就是类的实例,但在 ES6之前, JS 中并没用引入类的概念。 ES6, 全称 ECMAScript 6.0 ,2…

JavaScript高级之继承

ES6之前并没有给我们提供 extends 继承。我们可以通过构造函数原型对象模拟实现继承,被称为组合继承。 2.1 call() 调用这个函数, 并且修改函数运行时的 this 指向 fun.call(thisArg, arg1, arg2, …) thisArg :当前调用函数 this 的指向对象arg1&…

【代码笔记】iOS-UILable电子表显示

一&#xff0c;效果图。 二&#xff0c;代码。 RootViewController.h #import <UIKit/UIKit.h>interface RootViewController : UIViewController {UILabel *label;NSDateFormatter *dateFormatter ; } end RootViewController.m #import "RootViewController.h&qu…

JavaScript高级之ES5 中的新增方法

3.1 ES5 新增方法概述 ES5 中给我们新增了一些方法&#xff0c;可以很方便的操作数组或者字符串&#xff0c;这些方法主要包括&#xff1a; 数组方法字符串方法对象方法 3.2 数组方法 迭代(遍历)方法&#xff1a;forEach()、map()、filter()、some()、every()&#xff1b; …

JavaScript高级之函数进阶

1. 函数的定义和调用 1.1 函数的定义方式 函数声明方式 function 关键字 (命名函数)函数表达式 (匿名函数)new Function() Function 里面参数都必须是字符串格式第三种方式执行效率低&#xff0c;也不方便书写&#xff0c;因此较少使用所有函数都是 Function 的实例(对象)…

react 前端解析二进制流_一年半前端跳槽面试经验(头条、微信、shopee)

在2019年末的时候&#xff0c;突然想搞点大事&#xff0c;思来想去&#xff0c;感觉只有跳槽是最刺激的。由于我比较懒&#xff0c;不想换城市&#xff0c;所以这次只面试了头条、微信和 shopee。十分幸运&#xff0c;都拿到了 offer。接下来就简单的说下大家关心的面试题吧。问…

国内app快速生成平台对比

泰格老虎 2013-03-07 00:39:10 这是海恒CEO高鹏写的一篇国内app快速生成平台对比文章&#xff0c;介绍了国内快速生成APP的平台与自己平台的对比&#xff0c;很有参考价值。同类网站安米网 http://www.appbyme.org/追信 http://app.zhui.cn/简网app工厂 http://app.cutt.com/ap…

JavaScript高级之正则表达式

1. 正则表达式概述 1.1 什么是正则表达式 正则表达式&#xff08; Regular Expression &#xff09;是用于匹配字符串中字符组合的模式。在 JavaScript中&#xff0c;正则表达式也是对象。 正则表通常被用来检索、替换那些符合某个模式&#xff08;规则&#xff09;的文本&am…

pushpop指令的操作数必须是字操作数_PLC的指令,电气人必须了解的基础内容

指令语句表编程语言是所有PLC都具有的最基本的编程语言。而指令语句表程序是由一条一条的指令堆砌而成的。因此&#xff0c;我们有必要对指令进行进一步的说明和解读。1、指令格式PLC的指令语句表程序和微机汇编语言程序非常的相似&#xff0c;我们也是以汇编语言的指令和指令系…

JavaScript高级之ECMAScript 6 新特性

2.1. let关键字 let关键字用来声明变量&#xff0c;使用 let声明的变量有几个特点&#xff1a; 不允许重复声明 块儿级作用域 不存在变量提升 不影响作用域链 应用场景&#xff1a;以后声明变量使用let就对了 案例&#xff1a;点击切换颜色 <!DOCTYPE html&g…

sql 关联使用id还是code_R语言实例:用glue批量生成SQL语句

背景在数据开发中&#xff0c;有些情况下&#xff0c;需要手动生成批量SQL&#xff0c;只需改变某个参数&#xff0c;比如日期&#xff0c;从某天到某天。之前有一个实例&#xff0c;是用 stringr::str_replace_all() 去实现&#xff0c;这次就用 glue 来做示例&#xff0c;会更…