This commit is contained in:
WangXinghao
2025-11-04 18:08:19 +08:00
commit da90aa774a
10 changed files with 2299 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
node_modules

2182
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

27
package.json Normal file
View File

@@ -0,0 +1,27 @@
{
"name": "dist",
"version": "1.0.0",
"description": "",
"license": "ISC",
"author": "",
"type": "module",
"main": "index.js",
"scripts": {
"dev": "tsx src/server.ts",
"build": "tsc",
"start": "node dist/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"axios": "^1.13.1",
"express": "^5.1.0"
},
"devDependencies": {
"@types/express": "^5.0.5",
"@types/node": "^24.10.0",
"nodemon": "^3.1.10",
"ts-node": "^10.9.2",
"tsx": "^4.20.6",
"typescript": "^5.9.3"
}
}

0
src/app.ts Normal file
View File

11
src/server.ts Normal file
View File

@@ -0,0 +1,11 @@
import express from 'express';
const app = express();
const PORT = process.env.PORT || 3000;
app.get('/', (_req, res) => {
res.send('Hello, TypeScript + Express!');
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});

View File

@@ -0,0 +1,14 @@
import { http } from '@/utils/http';
interface User {
id: number;
name: string;
}
export const fetchUser = (id: number) => {
return http.get<User>(`/users/${id}`);
};
export const createUser = (data: Partial<User>) => {
return http.post<User>('/users', data);
};

0
src/utils/common.ts Normal file
View File

33
src/utils/http/client.ts Normal file
View File

@@ -0,0 +1,33 @@
import axios from 'axios';
import type { AxiosInstance } from 'axios';
const createHttpClient = (baseURL: string): AxiosInstance => {
const instance = axios.create({
baseURL,
timeout: 10000,
headers: { 'Content-Type': 'application/json' },
});
// 请求拦截器(可加 token、日志等
instance.interceptors.request.use(
(config) => {
// 例如config.headers.Authorization = `Bearer ${getToken()}`;
return config;
},
(error) => Promise.reject(error)
);
// 响应拦截器(统一错误处理)
instance.interceptors.response.use(
(response) => response.data, // 直接返回 data
(error) => {
// 统一错误日志或上报
console.error('HTTP Error:', error.response?.data || error.message);
return Promise.reject(error);
}
);
return instance;
};
export default createHttpClient;

12
src/utils/http/index.ts Normal file
View File

@@ -0,0 +1,12 @@
import createHttpClient from './client';
import type { AxiosRequestConfig } from 'axios';
// 按服务划分多个 client可选
const apiClient = createHttpClient(process.env.API_BASE_URL || 'http://localhost:3000');
export const http = {
get: <T>(url: string, config?: AxiosRequestConfig) => apiClient.get<T>(url, config),
post: <T>(url: string, data?: any, config?: AxiosRequestConfig) => apiClient.post<T>(url, data, config),
put: <T>(url: string, data?: any, config?: AxiosRequestConfig) => apiClient.put<T>(url, data, config),
delete: <T>(url: string, config?: AxiosRequestConfig) => apiClient.delete<T>(url, config),
};

19
tsconfig.json Normal file
View File

@@ -0,0 +1,19 @@
{
"compilerOptions": {
"rootDir": "src",
"outDir": "dist",
"module": "CommonJS",
"moduleResolution": "node",
"target": "ES2020",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}