
Express + TypeScript 專案從零開始的步驟

前置說明
本文將教你如何使用 pnpm 來從零開始建立一個 Express + TypeScript 的專案。使用 pnpm 的好處在於它提供了快速、節省磁碟空間的套件管理方式,並且非常適合大型專案的依賴管理。接下來,我們會一步步完成專案的初始化、基本架構的搭建,以及一些 Express 與 TypeScript 的最佳實踐。
1. 建立專案目錄
首先,進入到你想要創建專案的目錄並初始化專案:
mkdir express_ts_proto
cd express_ts_proto
pnpm initpnpm init 會初始化專案並生成 package.json 文件,這將作為專案的基礎設定檔。
還有要新增 .gitignore 檔案,把常見的檔案都 ignore 掉。
2. 安裝 Express 和相關依賴
使用 pnpm 安裝 Express 和相關的依賴:
pnpm add express cookie-parser morgan這個指令會安裝 Express 框架以及常用的中介軟體,例如處理 cookie 的 cookie-parser 和記錄 HTTP 請求的 morgan。
3. 安裝 TypeScript 和相關開發依賴
接著,安裝 TypeScript 及相關的型別定義檔案,讓專案支援 TypeScript:
pnpm add -D typescript @types/node @types/express @types/cookie-parser @types/morgan ts-node @types/debug這些開發依賴會幫助專案在開發階段支援 TypeScript 型別檢查。
4. 初始化 TypeScript 配置
創建一個 tsconfig.json 文件來設置 TypeScript 編譯器的配置:
pnpm exec tsc --init修改 tsconfig.json 文件如下,來配置輸出和根目錄:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true
},
"include": ["src/**/*"]
}這樣的配置可以確保 TypeScript 會將編譯後的 JavaScript 文件輸出到 dist 目錄,並設置專案的源文件路徑為 src。
5. 建立 Express 應用模板
使用 express-generator 來生成基本的 Express 應用結構,並指定不使用視圖引擎:
pnpm add express-generator --save-dev
pnpm exec express --no-view這將會建立一個預設的應用結構,隨後我們會將其轉換為 TypeScript 格式。
6. 安裝 dotenv 用來管理環境變數
安裝 dotenv 來處理 .env 環境變數文件:
pnpm add dotenv7. 建立 .env 文件
在專案根目錄創建 .env 文件來定義環境變數:
PORT=3000
DEBUG=*
這裡設定了應用的預設埠和調試模式。
8. 建立應用文件結構
新增 src/ 目錄並且在 src/ 下建立以下文件結構:
/src
/bin
www.ts
/routes
index.ts
users.ts
app.ts9. 編寫 src/app.ts
請將原本的 app.js 重新命名修改為 app.ts,並且確認搬移到 src/ 資料夾裡面。
app.ts 是應用的核心,負責設置中介軟體(Middleware)和路由。
import express from 'express';
import { join } from 'path';
import cookieParser from 'cookie-parser';
import logger from 'morgan';
import routes from './routes';
const app = express();
// Middleware
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
// Uncomment if needed for serving static files
// app.use(express.static(join(__dirname, 'public')));
// Use centralized routes
app.use(routes);
export default app;10. 編寫 src/bin/www.ts
請講原本的 bin/www 移動並且修改副檔案名 src/bin/www.ts。
www.ts 負責啟動伺服器並處理錯誤。
#!/usr/bin/env node
import 'dotenv/config'; // Load .env variables
import app from '../app';
import http from 'http';
import debug from 'debug';
const normalizePort = (val: string) => {
const port = parseInt(val, 10);
if (isNaN(port)) return val;
if (port >= 0) return port;
return false;
};
const onError = (error: any) => {
if (error.syscall !== 'listen') {
throw error;
}
const bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
};
const onListening = () => {
const addr = server.address();
if (addr !== null && typeof addr !== 'string') {
const bind = 'port ' + addr.port;
debug('Listening on ' + bind);
} else if (addr !== null && typeof addr === 'string') {
const bind = 'pipe ' + addr;
debug('Listening on ' + bind);
} else {
console.error('Server address is null.');
}
};
const port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
const server = http.createServer(app);
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);11. 建立 src/routes/index.ts
這個文件管理首頁的路由邏輯。
import { Router, Request, Response } from 'express';
import usersRouter from './users';
const router = Router();
router.get('/', (req: Request, res: Response) => {
res.send('Welcome to the Home Page')
});
router.use('/users', usersRouter);
export default router;12. 建立 src/routes/users.ts
users.ts 負責管理 /users 路由邏輯。
import { Router, Request, Response } from 'express';
const router = Router();
/* GET users listing. */
router.get('/', (req: Request, res: Response) => {
res.send('respond with a resource');
});
export default router;13. 更新 package.json
在 package.json 中添加 start 腳本來啟動應用:
"scripts": {
"start": "ts-node ./src/bin/www"
}14. 運行專案
現在,應用可以通過 pnpm start 命令啟動:
pnpm start如果一切順利,你應該會看到伺服器成功啟動並開始監聽指定的端口。
15. 最佳實踐與未來發展
- 環境變數管理:通過
.env文件靈活管理專案的環境設置。 - TypeScript 錯誤處理:確保每個文件中的參數、返回值都有正確的型別註解。
- 中介軟體與路由的拆分:未來可以將中介軟體和路由拆分成更多模組以便