上节课我们讲到使用express脚手架快速搭建express应用,本次课程我们继续聊聊express。
- 开始将app.js中的内容改成ts
- 改写
- 先直接将内容复制到app2.ts
yarn add @types/node@16.15.0 --dev
,这样才能使用requireyarn add @types/express@4.16.1 --dev
,这样才能使用require- 可以用import代替require
- 可以用const代替var
- 需RequestHandler和ErrorRequestHandler断言
js
import { ErrorRequestHandler, RequestHandler } from 'express-serve-static-core';
...
app.use(function (req, res, next) {
next(createError(404));
} as RequestHandler);
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
res.status(err.status || 500);
res.render('error');
next()
} as ErrorRequestHandler);
module.exports = app;
- 将bin/www中的入口改为app2.ts
- 添加yarn start ts脚本,将node改为ts-node
- 其它地方想要用ts的也需要这样改
- 深入了解express编程模型
- app.use()的作用
- 创建express-demo2,使用刚才创建的starter
bash
clone git@github.com:codingories/express-starter-1.git .
yarn install
- 删除app.js自己重新写一下,运行node-dev app.js
js
const express = require('express')
const app = express()
app.use((request, response, next)=> {
console.log(request.url)
response.write('hi')
next()
})
app.use((request, response, next)=> {
console.log(2)
response.write('hi')
next()
})
app.use((request, response, next)=> {
response.end()
next()
})
app.listen(3000, () => {
console.log('正在 listen 3000')
})
- 访问localhost:3000,得到hihi,通过这个例子我们可以简单的体会一下app.use使用中间件
- 什么是中间件
- express的编程模型
- 中间件的概念:通过app.use注册了一系列中间件。允许你在请求到达路由处理之前或之后执行一些操作
- 例子
js
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
- 中间件的优点
- 这种模型使得每个功能都能通过一个函数实现
- 然后通过app.use将这个函数整合起来
- 如果把函数放到文件或npm里,就实现了模块化
- 自己写一个中间件,新建logger.js
js
const logger = (prefix) => {
return (request, response, next) => {
console.log(`${prefix} ${request.url}`)
next()
}
}
module.exports = logger
- 然后在app.js中使用,这样就独立完成了一个logger的中间件
js
const fn = logger('dev')
app.use(fn)
app.use((request, response, next)=> {
response.end()
next()
})
- 题外话,我们可以将以下代码设置成live template来快速生成,之后直接输入app.use加tab就可以生成,$end表示停的位置
js
app.use((request, response, next)=> {
})
- app.use如何实现路由
js
app.use((request, response, next)=>{
if(request.path==='/xxx' && request.method === 'get') {
request.write('home')
}
next()
})
- 路由更简单的实现方式
js
const fn = () => {}
app.use('/aaa', fn)
app.get('/yyy', fn)
app.post('/zzz', fn)
app.route('/xxx').all(f1).get(f2).post(f3)
- 处理路由我们更推荐用express.Router()
- 通过express.Router(),可以将每个路由的处理逻辑独立分离,使代码更易于维护。
- 具体代码
js
// 创建一个路由器
const router = express.Router();
// 定义路由处理程序
router.get('/', (req, res) => {
res.send('首页');
});
router.get('/about', (req, res) => {
res.send('关于我们');
});
router.get('/contact', (req, res) => {
res.send('联系我们');
});
// 将路由器挂载到'/app'路径上
app.use('/', router);
app.listen(3000, () => {
console.log('正在 listen 3000')
})
- 错误处理
- 例子
js
// 模拟一个可能出错的路由处理
app.get('/error', (req, res, next) => {
// 在这个例子中,模拟一个异步操作,比如查询数据库时发生了错误
setTimeout(() => {
// 模拟错误
next(new Error('这是一个模拟的错误'));
}, 1000);
});
// 错误处理中间件
app.use((err, req, res, next) => {
console.error(err.stack);
// 判断错误类型并发送相应的响应
if (err instanceof SyntaxError) {
res.status(400).send('Bad Request');
} else {
res.status(500).send('Something went wrong!');
}
});
// 启动服务器
app.listen(3000, () => {
console.log('服务器正在监听端口 3000');
});
- next(error),会直接进入errorHandler,不执行后面的中间件
- 如何自定义errorHandler
js
app.use((err, req, res, next) => {
...
});
- 总结
- 本次课程我们深入了解Express的编程模型与中间件。
- 首先,通过Curl命令、HTTP请求与响应的处理,我们夯实了对Web框架的基础认识。
- 接着,我们将探讨Express的编程模型,了解中间件的概念与优势,并通过自定义中间件和路由进行实践。
- 进一步地,我们将学习错误处理的重要性,通过示例了解如何处理可能出错的路由,以及如何自定义错误处理中间件。
- 通过这些实例,我们将更深入地了解Express的强大功能。
- 最后,让我们继续深入学习Express,为构建强大的Node.js应用程序打下坚实基础。