这是渐进式 Express 源码学习 | 小白也能懂源码系列文章的第一篇。
请结合该节代码阅读Lesson1-万物归宗
这篇文章我们实现一个最最基础的 Web 框架,功能包括
具体的用法如下(我们用 my-express 表示这个框架)
const express = require('../index.js')
const app = express()
app.listen(3000)
首先在 Node 中,和网络请求相关的模块是 http,我们可以用 http 搭建一个简单的 web 服务器,如下代码
const http = require('http')
const server = http.createServer(function (req,res) {
res.end('Response From Server')
})
server.listen(3000)
上面的代码中,我们调用 http 模块的 createServer 函数,传入一个相应请求的函数。这个就是一个简单的 Web 服务,非常好理解。Node 文档里对 createServer 函数有说明。
基于上面的代码,我们稍微做下调整,就是我们第一个 Express 的源码,如下
const http = require('http')
const mixin = require('merge-descriptors')
module.exports = function createServer() {
const app = function (req, res) {
res.end('Response From Server')
}
mixin(app, proto, false)
return app
}
const proto = Object.create(null)
proto.listen = function (port) {
const server = http.createServer(this)
return server.listen.apply(server, arguments)
}
代码开头,我们引入 http 模块和 merge-descriptors 模块。http 模块是 Node 原生模块不多说,merge-descriptors 是第三方模块,主要是通过 descrptors 合并对象,他的用法是
var thing = {
get name() {
return 'jon'
}
}
var animal = {
}
merge(animal, thing)
animal.name === 'jon'
更多关于 merge-descriptors 的实现可以看 https://github.com/component/merge-descriptors
然后我们 exports 是一个函数,用户调用之后,会拿到一个对象,这个对象本身是一个函数,并且还有一个 listen 方法。当调用 app.listen 的时候,实际上就调用了 http 模块的 createServer 函数,然后把自己当做 requestListener 传入
目前我们整个项目的文件结构是
我们首先通过命令 node example/index.js 运行样例 然后我们通过下面命令来测试我们的程序是否正常工作
curl http://localhost:3000
结果如图
所以我们的程序是正常工作了,我们第一个版本的 Express 也实现好了。现实的 Express 还有很多其他功能,我们一步一步添加。
本文实现了一个最基础的 Express,他能默认响应客户端的请求。本质上他是从 http 模块衍生来的,同样的,express 也是从 http 衍生过来的。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.