Node-web01_01Express入门

Express

为什么有web框架

功能

  • 更方便的处理 HTTP 请求和响应
  • 更方便的链接数据库、Redis
  • 更方便的路由
  • 其他:HTML模版

理念

  • web框架主流思想都是 MVC
  • Model 处理数据相关逻辑
  • View 处理视图相关逻辑,前后端分离之后,view不重要
  • Controller 负责其他逻辑

CRM 来开始 hello world

  • 创建项目 express-demo-1
  • git init
  • yarn init -y
  • .gitignore 添加忽略文件
  • express官网 抄代码
  • 添加依赖 yarn add express
  • 新建 app.js
1
2
3
4
5
6
7
8
9
10
var express = require('express');
var app = express();

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

app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
  • 项目根目录运行 node app.js
  • 然后开始做修改 如果你想热更新
  • npm i node-dev -g
  • node-dev app.js 这样修改代码就会自动生效

给 Express 加入 TS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 安装全局工具
yarn global add typescript ts-node
# 安装类型支持
yarn add @types/express

# 项目根目录运行,初始化 ts配置文件
tsc --init

# 修改 tsconfig的 target 和 nolmplicitAny
{
"target": "es2015",
"noImplicitAny": true
}

# 修改 require 为 import
import express from 'express';
  • 新建 app2.ts
1
2
3
4
5
6
7
8
9
10
import express from 'express';
const app = express();

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

app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
  • 运行 ts-node app2.ts 成功即可

app的类型

由于我们用的是ts所以可以看代码

  • 点击 const app = express(); 中的 express
  • 看到 declare function e(): core.Express; 继续点击 core.Express
  • 看到 export interface Express extends Application { ... } 点击 Application
  • 看到 export interface Application extends EventEmitter, IRouter, Express.Application {...}
    • EventEmitter 是个事件触发器
    • 点击 IRouter
      • 包含了 get/post/put 等方法
  • 有了 TS 都不用看文档了

代码仓库

express 脚手架

  • 安装 yarn global add express-generator

使用 express-generator

  • express -h 查看帮助
  • mkdir express-demo-2
  • cd express-demo-2
  • express --view=ejs .
  • yarn install 安装依赖
  • yarn start 运行项目后 可访问 http://localhost:3000

将项目升级为TS

  • app.js 复制到 app.ts
  • yarn add @types/node --dev 这样才能用 require
  • yarn add @types/express --dev
  • 你可以用 import 代替 require
  • 你可以用 const 代替 var
  • 需 RequestHandler 和 ResponseHandler 断言
  • 将 bin/www 里的入口改为 app.ts
  • 添加 start:ts 脚本,将 node 改为 ts-node

疑问

  • 为什么ts-node 可以运行js
    • 本来就可以啊,只是添加了 ts 的支持
  • 不要在生产环境里这样用

Express核心概念

中间件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const express = require('express');
const app = express();

app.get('/', function (req, res, next) {
console.log('中间件1')
next();
});

app.get('/', function (req, res, next) {
console.log('中间件2')
next();
});

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

app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});

/*
访问 http://localhost:3000/
// 运行结果
中间件1
中间件2
*/

优点

  • 模块化
  • app.use 将这个函数整合起来

路由

1
2
3
4
5
6
7
8
9
10
11
12
app.use('/', function (req, res, next) {
if(req.path == '/xxx'){
res.write('home');
}
next();
});


app.get
app.post
app.use
// ....

异常处理

  • next()会进入下一个中间件
  • next(error) 会直接进入 errorHandler,不执行后面的中间件
  • next('route')
    • 这是一个特殊参数

express 知识点请参考这个