手写Express.js源码

时间:2021-1-8 作者:admin

上一篇文章我们讲了怎么用Node.js原生API来写一个web服务器,虽然代码比较丑,但是基本功能还是有的。但是一般我们不会直接用原生API来写,而是借助框架来做,比如本文要讲的Express。通过上一篇文章的铺垫,我们可以猜测,Express其实也没有什么黑魔法,也仅仅是原生API的封装,主要是用来提供更好的扩展性,使用起来更方便,代码更优雅。本文照例会从Express的基本使用入手,然后自己手写一个Express来替代他,也就是源码解析。

本文可运行代码已经上传GitHub,拿下来一边玩代码,一边看文章效果更佳:github.com/dennis-jian…

简单示例

使用Express搭建一个最简单的Hello World也是几行代码就可以搞定,下面这个例子来源官方文档:

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});

可以看到Express的路由可以直接用app.get这种方法来处理,比我们之前在http.createServer里面写一堆if优雅多了。我们用这种方式来改写下上一篇文章的代码:

const path = require("path");
const express = require("express");
const fs = require("fs");
const url = require("url");

const app = express();
const port = 3000;

app.get("/", (req, res) => {
  res.end("Hello World");
});

app.get("/api/users", (req, res) => {
  const resData = [
    {
      id: 1,
      name: "小明",
      age: 18,
    },
    {
      id: 2,
      name: "小红",
      age: 19,
    },
  ];
  res.setHeader("Content-Type", "application/json");
  res.end(JSON.stringify(resData));
});

app.post("/api/users", (req, res) => {
  let postData = "";
  req.on("data", (chunk) => {
    postData = postData + chunk;
  });

  req.on("end", () => {
    // 数据传完后往db.txt插入内容
    fs.appendFile(path.join(__dirname, "db.txt"), postData, () => {
      res.end(postData); // 数据写完后将数据再次返回
    });
  });
});

app.listen(port, () => {
  console.log(`Server is running on http://localhost:${port}/`);
});

Express还支持中间件,我们写个中间件来打印出每次请求的路径:

app.use((req, res, next) => {
  const urlObject = url.parse(req.url);
  const { pathname } = urlObject;

  console.log(`request path: ${pathname}`);

  next();
});

Express也支持静态资源托管,不过他的API是需要指定一个文件夹来单独存放静态资源的,比如我们新建一个public文件夹来存放静态资源,使用express.static中间件配置一下就行:

app.use(express.static(path.join(__dirname, 'public')));

然后就可以拿到静态资源了:

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。