搭建 Node.js 與 TypeScript 開發環境

3 min read

Setup

確保系統已安裝 Node.js 與 pnpm 或其他套件管理工具

創建專案資料夾

mkdir node-ts-template code node-ts-template

生成 package.json

pnpm init

安裝 tsx ( TypeScript Execute ) 與 @types/node

pnpm i -D tsx @types/node

創建 src 資料夾 與 main.ts entry

code src/main.ts
main.ts
var console: Consoleconsole.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)log('Hello, TypeScript!')

更新 package.json

package.json
{ "name": "node-ts-template", "type": "module", "scripts": { "start": "tsx src/main.ts --no-warnings", "watch": "tsx src/main.ts --no-warnings --watch" }, "devDependencies": { "@types/node": "^22.0.2", "tsx": "^4.16.3" } }
note

根據需求移除不需要的 fields

測試 entry

pnpm start

輸出結果:

> tsx src/main.ts --no-warnings Hello, TypeScript!

Type Check & Alias

安裝 typescript

pnpm i -D typescript

設定 tsconfig.json

tsconfig.json
{ "compilerOptions": { /* Base Options */ "moduleDetection": "force", "esModuleInterop": true, "allowJs": true, "resolveJsonModule": true, "isolatedModules": true, "skipLibCheck": true, /* Strictness */ "strict": true, "checkJs": true, "noUncheckedIndexedAccess": true, /* Bundled projects */ "moduleResolution": "Bundler", "module": "ESNext", "target": "ESNext", "noEmit": true, /* Path Aliases */ "baseUrl": ".", "paths": { "~/*": ["./src/*"] } }, "include": ["src/**/*"], "exclude": ["node_modules"] }

更新 package.json

package.json
{ "name": "node-ts-template", "type": "module", "scripts": { "start": "tsx src/main.ts --no-warnings", "watch": "tsx src/main.ts --no-warnings --watch", "typecheck": "tsc" }, "devDependencies": { "@types/node": "^22.0.2", "tsx": "^4.16.3", "typescript": "^5.5.4" } }

測試 Alias

code src/utils.ts
utils.ts
export function function addNumber(a: number, b: number): numberaddNumber(a: numbera: number, b: numberb: number) { return a: numbera + b: numberb }
main.ts
import { function addNumber(a: number, b: number): numberaddNumber } from '~/utils' var console: Consoleconsole.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)log(function addNumber(a: number, b: number): numberaddNumber(1, 2))
pnpm start

輸出結果

> tsx src/main.ts --no-warnings 3

測試 Type Check

main.ts
import { function addNumber(a: number, b: number): numberaddNumber } from '~/utils' var console: Consoleconsole.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)log(function addNumber(a: number, b: number): numberaddNumber(1, '2'))
Argument of type 'string' is not assignable to parameter of type 'number'.
pnpm typecheck

輸出結果

> tsc src/main.ts:3:25 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. 3 console.log(addNumber(1,'2')) ~~~ Found 1 error in src/main.ts:3

ESLint & Formatting

此設定將會使用新版的 Flat Config 以及個人 Config

安裝 ESLint

pnpm i -D eslint typescript-eslint @eslint/js @eslint/compat @types/eslint__js

安裝 Plugins

pnpm i -D globals @stylistic/eslint-plugin eslint-plugin-import eslint-plugin-simple-import-sort eslint-plugin-unicorn

安裝 Config

pnpm i -D @nekochan0122/config

創建 eslint.config.js

eslint.config.js
import nekoConfig from '@nekochan0122/config/eslint' import globals from 'globals' import tseslint from 'typescript-eslint' export default tseslint.config( ...nekoConfig.presets.base, { languageOptions: { globals: globals.node } } )

Reference