Skip to content

Commit

Permalink
feat(express): update
Browse files Browse the repository at this point in the history
  • Loading branch information
dribble-njr committed Sep 19, 2024
1 parent 6268b16 commit a5e7a5b
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 3 deletions.
10 changes: 8 additions & 2 deletions docs/backend/node/express/01-overview-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ tag:

[Express](https://github.com/expressjs/express) 是适用于 Node.js 的极简网络应用程序框架。它为构建网络和移动应用程序提供了一套强大的功能。尽管简单,Express 却具有很强的可扩展性,允许开发人员添加中间件并自定义应用程序的行为。

::: warning

在代码解读中,贴上的源码有可能改为 TS 类型,在阅读源码时请注意。

:::

## 核心组件

包括 `Application``Request``Response``Router`
Expand Down Expand Up @@ -70,7 +76,7 @@ var removedMiddlewares = [

## lib 源码结构

Express@4.19.2 中,`lib` 目录结构如下:
Express@4.21.0 中,`lib` 目录结构如下:

```shell
lib/
Expand All @@ -89,8 +95,8 @@ lib/
└── view.js
```

- `application.js`: 定义了 Express 应用的核心功能,如 `app.use()``app.get()` 等方法。
- `express.js`: 主入口文件,导出了核心的 `express()` 函数。
- `application.js`: 定义了 Express 应用的核心功能,如 `app.use()``app.get()` 等方法。
- `middleware/`: 包含 Express 内置的 `middleware`,例如 `init.js` 用于初始化中间件,`query.js` 用于解析查询字符串。
- `request.js`: 定义了 `req` 对象的扩展和辅助方法。
- `response.js`: 定义了 `res` 对象的扩展和辅助方法。
Expand Down
50 changes: 49 additions & 1 deletion docs/backend/node/express/02-express.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,28 @@ tag:

`express.js` 文件定义了 Express 应用的主入口。它的核心功能是创建一个新的 Express 应用实例,并暴露相关的原型和构造函数,使应用能够处理 HTTP 请求并管理中间件(`middleware`)。

## Hello World

先看看官网的 Hello World:

```js
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 on port ${port}`)
})
```

思考一下,`express()` `app.get()``app.listen()` 分别做了什么?

接下来一步步看源码,就能看出它们的作用。

## 模块依赖

引入了一些依赖模块:
Expand Down Expand Up @@ -72,25 +94,51 @@ function createApplication() {
- `app.request``app.response`: 创建 `req``res` 的原型对象,并绑定 `app`
- `app.init()`: 初始化应用。

使用如下,实际上就相当于调用了 `createApplication()` 函数,返回一个新的 `app` 对象
调用下述代码时,实际上就相当于调用了 `createApplication()` 函数,返回一个新的 `app` 函数,它使用了 [混入模式](../../../reading/patterns/vanilla/06-mixin-pattern.md) 增强了一些功能(`proto``application.js` 暴露的对象),该原型提供了初始化 `init` 方法

```js
const express = require('express')
const app = express()

app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
```

`listen` 函数实际做了如下功能:

```js
app.listen = function listen() {
var server = http.createServer(this)
return server.listen.apply(server, arguments)
}
```

注意到他这里直接将 `app` 传入了 `http.createServer` 函数,该函数的签名为:`http.createServer([options][, requestListener])``requestListener` 函数的签名为 `(request, response) => void`。而在 `express.js` 中,`createApplication()` 中就已经声明 `app``requestListener` 类型的。

```js
var app = function (req, res, next) {
app.handle(req, res, next)
}
```

到这里为止,我们其实已经弄清楚了 Hello World 内部的实现。

## 暴露的接口

暴露的接口如下:

```js
// 原型
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.raw = bodyParser.raw
Expand Down

0 comments on commit a5e7a5b

Please sign in to comment.