1 前言
TypeScript 的 Express 服务端框架是一种结合了 TypeScript 静态类型检查特性和 Express 的轻量级、高效 Web 框架的开发方式。它适合构建现代化、可维护性高的后端服务。
1.1 什么是 Express?
Express 是一个基于 Node.js 的轻量级 Web 框架,特点如下:
- 轻量和灵活:提供了路由、请求处理、中间件等基础功能。
- 丰富的中间件生态:支持各种功能扩展,如身份验证、日志记录、静态文件服务等。
- 快速开发:简洁的 API 设计适合快速构建服务。
1.2 为什么使用 TypeScript 搭配 Express?
TypeScript 为 Express 增强了静态类型支持,带来了以下好处:
- 类型安全:通过类型检查减少运行时错误。
- 代码提示:更智能的代码补全和提示,提高开发效率。
- 面向对象编程:支持类、接口等高级特性,代码更易维护。
- 可维护性:大项目中,类型系统可以显著降低代码复杂性。
1.3 基础架构
搭建一个基于 TypeScript 的 Express 项目,一般包括以下部分:
- 入口文件:初始化服务器,配置路由和中间件。
- 路由模块:定义各个 API 路由。
- 控制器模块:处理具体的业务逻辑。
- 服务层:封装具体功能(如数据库操作)。
- 中间件:处理日志、身份验证、错误捕获等通用功能。
- 配置文件:管理环境变量、数据库配置等。
2 初始化项目
mkdir ts-server
cd ts-server
npm init -y
npm install express
npm install -D typescript @types/node @types/express ts-node-dev
3 配置 TypeScript
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"rootDir": "./src",
"outDir": "./dist",
"strict": true,
"esModuleInterop": true
},
"include": ["src"]
}
4 创建 TypeScript 文件
mkdir src
touch src/server.ts
4.1 服务端代码src/server.ts
import express, { Request, Response } from 'express';
const app = express();
const PORT = 3000;
app.use(express.json());
app.get('/test', (req: Request, res: Response) => {
res.json({ message: '有勇气的牛排,nodejs服务端测试' });
});
app.listen(PORT, () => {
console.log(`Server is running at http://localhost:${PORT}`);
});
5 package.json添加配置
"scripts": {
"dev": "ts-node-dev src/server.ts"
}
6 执行
npm run dev
http://localhost:3000/test

7 代码优化
7.1 通用json返回封装
ResponseUtil.ts
class ResponseUtil {
static success(res: any, data: any, message: string = '查询成功', code: number = 20000): void {
res.json({
code,
msg: message,
data
});
}
static fail(res: any, message: string = '失败', code: number = -1): void {
res.json({
code,
msg: message
});
}
static error(res: any, message: string = '请求失败', code: number = 50000): void {
res.status(500).json({
code,
msg: message,
data: null
});
}
}
export default ResponseUtil;
7.2 路由分离
参考Java服务端分层设计理念。
ExampleController.ts
import { Request, Response, Router } from 'express';
import ResponseUtil from '../utils/ResponseUtil';
const router = Router();
router.get('/test6', async (req: Request, res: Response) => {
ResponseUtil.success(res, {}, "查询成功", 20000);
});
export default router;
server.ts
注册路由
import ExampleController from "./controller/ExampleController";
app.use('/api/v1', CodeEncryController);
<h2><a id="1__0"></a>1 前言</h2>
<p>TypeScript 的 Express 服务端框架是一种结合了 TypeScript 静态类型检查特性和 Express 的轻量级、高效 Web 框架的开发方式。它适合构建现代化、可维护性高的后端服务。</p>
<h3><a id="11__Express_4"></a>1.1 什么是 Express?</h3>
<p>Express 是一个基于 Node.js 的轻量级 Web 框架,特点如下:</p>
<ul>
<li><strong>轻量和灵活</strong>:提供了路由、请求处理、中间件等基础功能。</li>
<li><strong>丰富的中间件生态</strong>:支持各种功能扩展,如身份验证、日志记录、静态文件服务等。</li>
<li><strong>快速开发</strong>:简洁的 API 设计适合快速构建服务。</li>
</ul>
<h3><a id="12__TypeScript__Express_12"></a>1.2 为什么使用 TypeScript 搭配 Express?</h3>
<p>TypeScript 为 Express 增强了静态类型支持,带来了以下好处:</p>
<ul>
<li><strong>类型安全</strong>:通过类型检查减少运行时错误。</li>
<li><strong>代码提示</strong>:更智能的代码补全和提示,提高开发效率。</li>
<li><strong>面向对象编程</strong>:支持类、接口等高级特性,代码更易维护。</li>
<li><strong>可维护性</strong>:大项目中,类型系统可以显著降低代码复杂性。</li>
</ul>
<h3><a id="13__21"></a>1.3 基础架构</h3>
<p>搭建一个基于 TypeScript 的 Express 项目,一般包括以下部分:</p>
<ul>
<li><strong>入口文件</strong>:初始化服务器,配置路由和中间件。</li>
<li><strong>路由模块</strong>:定义各个 API 路由。</li>
<li><strong>控制器模块</strong>:处理具体的业务逻辑。</li>
<li><strong>服务层</strong>:封装具体功能(如数据库操作)。</li>
<li><strong>中间件</strong>:处理日志、身份验证、错误捕获等通用功能。</li>
<li><strong>配置文件</strong>:管理环境变量、数据库配置等。</li>
</ul>
<h2><a id="2__34"></a>2 初始化项目</h2>
<pre><div class="hljs"><code class="lang-shell">mkdir ts-server
cd ts-server
npm init -y
npm install express
npm install -D typescript @types/node @types/express ts-node-dev
</code></div></pre>
<h2><a id="3__TypeScript_46"></a>3 配置 TypeScript</h2>
<pre><div class="hljs"><code class="lang-json"><span class="hljs-punctuation">{</span>
<span class="hljs-attr">"compilerOptions"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"target"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"ES6"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"module"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"commonjs"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"rootDir"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"./src"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"outDir"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"./dist"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"strict"</span><span class="hljs-punctuation">:</span> <span class="hljs-keyword">true</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"esModuleInterop"</span><span class="hljs-punctuation">:</span> <span class="hljs-keyword">true</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"include"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">"src"</span><span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span>
</code></div></pre>
<h2><a id="4__TypeScript__62"></a>4 创建 TypeScript 文件</h2>
<pre><div class="hljs"><code class="lang-shell">mkdir src
touch src/server.ts
</code></div></pre>
<h3><a id="41_srcserverts_69"></a>4.1 服务端代码src/server.ts</h3>
<pre><div class="hljs"><code class="lang-typescript"><span class="hljs-keyword">import</span> express, { <span class="hljs-title class_">Request</span>, <span class="hljs-title class_">Response</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-keyword">const</span> app = <span class="hljs-title function_">express</span>();
<span class="hljs-keyword">const</span> <span class="hljs-variable constant_">PORT</span> = <span class="hljs-number">3000</span>;
<span class="hljs-comment">// 中间件</span>
app.<span class="hljs-title function_">use</span>(express.<span class="hljs-title function_">json</span>());
<span class="hljs-comment">// 定义 /test 路由</span>
app.<span class="hljs-title function_">get</span>(<span class="hljs-string">'/test'</span>, <span class="hljs-function">(<span class="hljs-params">req: Request, res: Response</span>) =></span> {
res.<span class="hljs-title function_">json</span>({ <span class="hljs-attr">message</span>: <span class="hljs-string">'有勇气的牛排,nodejs服务端测试'</span> });
});
<span class="hljs-comment">// 启动服务</span>
app.<span class="hljs-title function_">listen</span>(<span class="hljs-variable constant_">PORT</span>, <span class="hljs-function">() =></span> {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`Server is running at http://localhost:<span class="hljs-subst">${PORT}</span>`</span>);
});
</code></div></pre>
<h2><a id="5_packagejson_91"></a>5 package.json添加配置</h2>
<pre><div class="hljs"><code class="lang-json"><span class="hljs-attr">"scripts"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"dev"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"ts-node-dev src/server.ts"</span>
<span class="hljs-punctuation">}</span>
</code></div></pre>
<h2><a id="6__99"></a>6 执行</h2>
<pre><div class="hljs"><code class="lang-shell">npm run dev
</code></div></pre>
<p>http://localhost:3000/test</p>
<p><img src="https://static.couragesteak.com/article/27b62372b71dcebbf53aa21b7bc7b936.png" alt="image.png" /></p>
<h2><a id="7__113"></a>7 代码优化</h2>
<h3><a id="71_json_115"></a>7.1 通用json返回封装</h3>
<p><code>ResponseUtil.ts</code></p>
<pre><div class="hljs"><code class="lang-tsx"><span class="hljs-comment">// utils/ResponseUtil.ts</span>
<span class="hljs-keyword">class</span> <span class="hljs-title class_">ResponseUtil</span> {
<span class="hljs-comment">// 返回成功的 JSON 响应</span>
<span class="hljs-keyword">static</span> <span class="hljs-title function_">success</span>(<span class="hljs-attr">res</span>: <span class="hljs-built_in">any</span>, <span class="hljs-attr">data</span>: <span class="hljs-built_in">any</span>, <span class="hljs-attr">message</span>: <span class="hljs-built_in">string</span> = <span class="hljs-string">'查询成功'</span>, <span class="hljs-attr">code</span>: <span class="hljs-built_in">number</span> = <span class="hljs-number">20000</span>): <span class="hljs-built_in">void</span> {
res.<span class="hljs-title function_">json</span>({
code,
<span class="hljs-attr">msg</span>: message,
data
});
}
<span class="hljs-keyword">static</span> <span class="hljs-title function_">fail</span>(<span class="hljs-attr">res</span>: <span class="hljs-built_in">any</span>, <span class="hljs-attr">message</span>: <span class="hljs-built_in">string</span> = <span class="hljs-string">'失败'</span>, <span class="hljs-attr">code</span>: <span class="hljs-built_in">number</span> = -<span class="hljs-number">1</span>): <span class="hljs-built_in">void</span> {
res.<span class="hljs-title function_">json</span>({
code,
<span class="hljs-attr">msg</span>: message
});
}
<span class="hljs-comment">// 返回失败的 JSON 响应</span>
<span class="hljs-keyword">static</span> <span class="hljs-title function_">error</span>(<span class="hljs-attr">res</span>: <span class="hljs-built_in">any</span>, <span class="hljs-attr">message</span>: <span class="hljs-built_in">string</span> = <span class="hljs-string">'请求失败'</span>, <span class="hljs-attr">code</span>: <span class="hljs-built_in">number</span> = <span class="hljs-number">50000</span>): <span class="hljs-built_in">void</span> {
res.<span class="hljs-title function_">status</span>(<span class="hljs-number">500</span>).<span class="hljs-title function_">json</span>({
code,
<span class="hljs-attr">msg</span>: message,
<span class="hljs-attr">data</span>: <span class="hljs-literal">null</span>
});
}
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">ResponseUtil</span>;
</code></div></pre>
<h3><a id="72__154"></a>7.2 路由分离</h3>
<p>参考Java服务端分层设计理念。</p>
<p><code>ExampleController.ts</code></p>
<pre><div class="hljs"><code class="lang-tsx"><span class="hljs-keyword">import</span> { <span class="hljs-title class_">Request</span>, <span class="hljs-title class_">Response</span>, <span class="hljs-title class_">Router</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-title class_">ResponseUtil</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'../utils/ResponseUtil'</span>; <span class="hljs-comment">// 导入 ResponseUtil 类</span>
<span class="hljs-keyword">const</span> router = <span class="hljs-title class_">Router</span>();
<span class="hljs-comment">// 获取用户信息</span>
<span class="hljs-comment">// http://localhost:3000/api/v1/test6</span>
router.<span class="hljs-title function_">get</span>(<span class="hljs-string">'/test6'</span>, <span class="hljs-keyword">async</span> (<span class="hljs-attr">req</span>: <span class="hljs-title class_">Request</span>, <span class="hljs-attr">res</span>: <span class="hljs-title class_">Response</span>) => {
<span class="hljs-title class_">ResponseUtil</span>.<span class="hljs-title function_">success</span>(res, {}, <span class="hljs-string">"查询成功"</span>, <span class="hljs-number">20000</span>);
});
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> router;
</code></div></pre>
<p><code>server.ts</code> 注册路由</p>
<pre><div class="hljs"><code class="lang-tsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">ExampleController</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"./controller/ExampleController"</span>;
app.<span class="hljs-title function_">use</span>(<span class="hljs-string">'/api/v1'</span>, <span class="hljs-title class_">CodeEncryController</span>);
</code></div></pre>
留言