.1-浅析express源码之入口文件
2018-06-24 01:55:11来源:未知 阅读 ()
鸽了鸽了,webpack源码大垃圾,看了那么久,感觉自己越来越渣……还是换个口味,node了解一下?
尝试从express框架源码入手,学习一下node的http模块相关的知识。
入口文件
先从框架的主文件入手,该JS文件包含三大部分:
1、外部/工具模块引入与属性挂载
2、主函数定义
3、中间件的分离提示
首先是第一块,具体的相关代码如下:
var bodyParser = require('body-parser') var EventEmitter = require('events').EventEmitter; var mixin = require('merge-descriptors'); var proto = require('./application'); var Route = require('./router/route'); var Router = require('./router'); var req = require('./request'); var res = require('./response'); // 内部模块 exports.application = proto; exports.request = req; exports.response = res; // 构造方法 exports.Route = Route; exports.Router = Router; // 中间件 exports.json = bodyParser.json exports.query = require('./middleware/query'); exports.static = require('serve-static'); exports.urlencoded = bodyParser.urlencoded
昨天正正经经的刷了一遍官方文档,在API的那一块,很暴力的把express分为了5个模块:
1、express本身
2、Application
3、Request
4、Response
5、Router
从源码来看也正是这样的,值得注意的是,express内部自带了body-parser模块,并且将该模块用来解析application/json与application/x-www-form-urlencoded形式的方法添加到了express上面。
EventEmitter是node内置事件模块,不必多讲。剩下的就是mixin方法,可以看下源码:
var hasOwnProperty = Object.prototype.hasOwnProperty module.exports = function merge(dest, src, redefine) { // 错误处理 if (!dest) throw new TypeError('argument dest is required') if (!src) throw new TypeError('argument src is required') // 默认为true if (redefine === undefined) redefine = true Object.getOwnPropertyNames(src).forEach(function forEachOwnPropertyName(name) { // redefine参数的作用是在目标对象与源对象有冲突键时 是否进行覆盖定义 if (!redefine && hasOwnProperty.call(dest, name)) return // 复制所有键 包含不可枚举的 var descriptor = Object.getOwnPropertyDescriptor(src, name) Object.defineProperty(dest, name, descriptor) }) return dest }
所以说,在引入express模块后,除了直接执行获取app实例,还可以调用上面的一些方法。
第二块就来看主函数的定义了,大部分的情况下,express的使用不外乎下面两行代码:
var express = require('express'); var app = express();
也就是express模块本身在引入后是一个函数,而函数的源码如下:
function createApplication() { // 返回的app实例也是一个函数 var app = function(req, res, next) { app.handle(req, res, next); }; // 目标对象属性的复制 mixin(app, EventEmitter.prototype, false); mixin(app, proto, false); // 挂载req、res的属性 app.request = Object.create(req, { app: { configurable: true, enumerable: true, writable: true, value: app } }); app.response = Object.create(res, { app: { configurable: true, enumerable: true, writable: true, value: app } }); // 初始化 // 该方法来源于上面的proto app.init(); return app; }
函数十分简单,首先定义了一个函数,然后将EventEmitter、proto(application)上面的属性添加到函数上,把request、response的原型设置为引入的内部模块req、res,调用init初始化方法后,返回app。
4.18后记,补充一下这里的知识点:
这里返回函数是必要的,首先参照正常情况下创建node服务器的代码:
let http = require('http'); http.createServer((req, res) => { // ... }).listen(9123);
可以看出,第二步的方法调用接受一个函数,通常我们会在这处理请求并进行响应。
而app.listen方法(这里提前讲一下)的代码如下:
app.listen = function listen() { var server = http.createServer(this); return server.listen.apply(server, arguments); };
可以看到,基本上就是原生的方法,对应传进去的函数变成了this,this指向什么呢?就是生成的函数,当有请求时,触发的函数就是app.handle方法。
涉及的handle、init方法均来源于混入的proto中,这个后面再看。
第三块就是4.x的一个变化:Express 4 不再依赖 Connect,而且从内核中移除了除 express.static
外的所有内置中间件。
从代码来看就很直白:
// 分号确实是源码里的 // 因为上一行代码没有分号 ;[ 'bodyParser', 'compress', 'cookieSession', 'session', 'logger', 'cookieParser', 'favicon', 'responseTime', 'errorHandler', 'timeout', 'methodOverride', 'vhost', 'csrf', 'directory', 'limit', 'multipart', 'staticCache', ].forEach(function (name) { // 每次尝试在express上访问这些属性将会报错 Object.defineProperty(exports, name, { get: function () { throw new Error('Most middleware (like ' + name + ') is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.'); }, configurable: true }); });
对原有的中间件属性访问将会报错……但是问题是内部又引入了body-parser模块,看来还是不能完全脱离,偷偷用了一个。
完结。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇:nodejs异步转同步
- 浅析XMLHttpRequest的缓存问题 2020-02-25
- nodejs的express自动生成项目框架的方法 2020-02-20
- nodejs之express的中间件 2019-08-14
- 浅析libuv源码-node事件轮询解析(3) 2019-05-13
- 浅析libuv源码-node事件轮询解析(2) 2019-05-08
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash