Node.js + TypeScript 環境設定
本篇將帶你從零開始配置 Node.js + TypeScript 開發環境,包含多種執行方式和最佳實踐。
一、 初始化專案
1.1 建立專案
bash
mkdir my-node-app
cd my-node-app
npm init -y1.2 安裝 TypeScript
bash
npm install -D typescript @types/node1.3 初始化 tsconfig.json
bash
npx tsc --init二、 tsconfig.json 配置
2.1 Node.js 推薦配置
json
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": ["ES2022"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}2.2 重要選項說明
| 選項 | 說明 |
|---|---|
target | 編譯目標,Node 18+ 用 ES2022 |
module | 模組系統,NodeNext 支援 ESM |
moduleResolution | 模組解析策略 |
outDir | 輸出目錄 |
rootDir | 原始碼目錄 |
strict | 嚴格模式 |
esModuleInterop | CommonJS 相容 |
declaration | 產生 .d.ts 檔案 |
三、 執行方式
3.1 編譯後執行
bash
# 編譯
npx tsc
# 執行
node dist/index.js3.2 使用 ts-node
bash
npm install -D ts-node
# 執行
npx ts-node src/index.ts3.3 使用 tsx(推薦)
bash
npm install -D tsx
# 執行
npx tsx src/index.ts
# 監聽模式
npx tsx watch src/index.ts> `tsx` 比 `ts-node` 更快,支援 ESM,推薦使用。
四、 開發腳本
4.1 package.json 腳本
json
{
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc",
"start": "node dist/index.js",
"lint": "eslint src --ext .ts",
"type-check": "tsc --noEmit"
}
}4.2 使用 nodemon
bash
npm install -D nodemonjson
{
"scripts": {
"dev": "nodemon --exec tsx src/index.ts"
}
}nodemon.json:
json
{
"watch": ["src"],
"ext": "ts,json",
"ignore": ["dist"],
"exec": "tsx src/index.ts"
}五、 ESM 與 CommonJS
5.1 使用 ESM
package.json:
json
{
"type": "module"
}tsconfig.json:
json
{
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext"
}
}typescript
// ESM 語法
import { readFile } from 'fs/promises';
import path from 'path';
const content = await readFile(path.join(process.cwd(), 'data.json'), 'utf-8');5.2 使用 CommonJS
package.json(不設定 type 或設為 commonjs):
json
{
"type": "commonjs"
}tsconfig.json:
json
{
"compilerOptions": {
"module": "CommonJS",
"moduleResolution": "Node"
}
}typescript
// CommonJS 語法
import fs from 'fs';
import path from 'path';
const content = fs.readFileSync(path.join(__dirname, 'data.json'), 'utf-8');六、 路徑別名
6.1 設定 tsconfig.json
json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@utils/*": ["src/utils/*"]
}
}
}6.2 使用 tsconfig-paths
bash
npm install -D tsconfig-pathsjson
{
"scripts": {
"dev": "ts-node -r tsconfig-paths/register src/index.ts"
}
}6.3 使用 tsx(自動支援)
bash
npx tsx src/index.ts # 自動解析路徑別名七、 環境變數
7.1 使用 dotenv
bash
npm install dotenv
npm install -D @types/nodetypescript
// src/index.ts
import dotenv from 'dotenv';
dotenv.config();
const port = process.env.PORT ?? 3000;
const dbUrl = process.env.DATABASE_URL;
console.log(`Server running on port ${port}`);7.2 類型安全的環境變數
typescript
// src/env.ts
import { z } from 'zod';
const envSchema = z.object({
NODE_ENV: z
.enum(['development', 'production', 'test'])
.default('development'),
PORT: z.string().transform(Number).default('3000'),
DATABASE_URL: z.string().url(),
});
const parsed = envSchema.safeParse(process.env);
if (!parsed.success) {
console.error('Invalid environment variables:', parsed.error.flatten());
process.exit(1);
}
export const env = parsed.data;typescript
// 使用
import { env } from './env';
console.log(env.PORT); // number
console.log(env.NODE_ENV); // 'development' | 'production' | 'test'
console.log(env.DATABASE_URL); // string八、 專案結構
8.1 推薦結構
my-node-app/
├── src/
│ ├── config/
│ │ └── env.ts
│ ├── controllers/
│ ├── middleware/
│ ├── routes/
│ ├── services/
│ ├── types/
│ │ └── index.ts
│ ├── utils/
│ └── index.ts
├── dist/
├── .env
├── .env.example
├── .gitignore
├── package.json
├── tsconfig.json
└── nodemon.json8.2 類型定義
typescript
// src/types/index.ts
export interface User {
id: number;
name: string;
email: string;
}
export interface ApiResponse<T> {
success: boolean;
data: T;
message?: string;
}九、 ESLint 配置
9.1 安裝
bash
npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin9.2 .eslintrc.cjs
javascript
module.exports = {
root: true,
env: {
node: true,
es2022: true,
},
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json',
},
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
],
rules: {
'@typescript-eslint/no-unused-vars': 'warn',
'@typescript-eslint/explicit-function-return-type': 'off',
semi: ['error', 'never'],
quotes: ['error', 'single'],
},
};總結
| 工具 | 用途 | 推薦 |
|---|---|---|
tsc | 編譯 | 生產環境 |
ts-node | 直接執行 | 一般 |
tsx | 快速執行 | 推薦 |
nodemon | 監聽變更 | 搭配使用 |
| 設定 | ESM | CommonJS |
|---|---|---|
| package.json type | module | commonjs |
| tsconfig module | NodeNext | CommonJS |
| 匯入語法 | import from | import from |
> **推薦配置**:
- 使用 ESM(
"type": "module") - 開發用
tsx watch - 生產用
tsc編譯後執行
進階挑戰
- 設定一個支援熱重載的開發環境
- 配置 Jest 測試框架 + TypeScript
- 建立一個 CLI(命令列工具)應用