V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
sunkuku
V2EX  ›  程序员

渐进式 Express 源码学习 1-万物归宗

  •  
  •   sunkuku · 2017-12-05 13:33:24 +08:00 · 1827 次点击
    这是一个创建于 2327 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这是渐进式 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 衍生过来的。

    2 条回复    2017-12-06 11:47:24 +08:00
    zcc0810
        1
    zcc0810  
       2017-12-05 17:16:56 +08:00
    还没细看 = =默默地点了 star
    sunkuku
        2
    sunkuku  
    OP
       2017-12-06 11:47:24 +08:00
    谢谢支持
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2759 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 12:43 · PVG 20:43 · LAX 05:43 · JFK 08:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.