1. 初始化企业级项目结构
任务说明
本案例目标为:搭建一个包含前端、后端、共享模块的多层项目结构,并完成版本控制与依赖管理的初始化配置。最终交付一个可直接克隆并运行的最小可复现工程骨架,不包含业务逻辑代码。
项目结构设计
采用 pnpm workspace 管理 monorepo,目录划分如下:
- apps/web:前端(Vite + Vue 3 + TypeScript)
- apps/server:后端(Express + TypeScript)
- packages/shared:共享类型与工具函数
版本控制使用 Git,依赖管理使用 pnpm(锁文件 pnpm-lock.yaml 保证依赖一致性)。共享模块通过 workspace 协议被前后端引用,实现类型与代码复用。
实现步骤
以下文件构成完整工程骨架,按路径创建即可。
1. 根目录配置
// package.json(根)
{
"name": "enterprise-monorepo",
"private": true,
"scripts": {
"dev:web": "pnpm --filter web dev",
"dev:server": "pnpm --filter server dev",
"build": "pnpm -r build",
"typecheck": "pnpm -r typecheck"
},
"devDependencies": {
"typescript": "^5.4.0"
},
"packageManager": "pnpm@9.0.0"
}
// pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"
// .gitignore
node_modules/
dist/
*.log
.env
2. 共享模块 packages/shared
// packages/shared/package.json
{
"name": "@company/shared",
"version": "1.0.0",
"main": "src/index.ts",
"types": "src/index.ts",
"scripts": {
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"typescript": "^5.4.0"
}
}
// packages/shared/src/index.ts
export interface ApiResponse<T> {
code: number;
data: T;
message: string;
}
export function createSuccessResponse<T>(data: T): ApiResponse<T> {
return { code: 0, data, message: "ok" };
}
export const API_VERSION = "v1";
// packages/shared/tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"skipLibCheck": true
},
"include": ["src"]
}
3. 后端 apps/server
// apps/server/package.json
{
"name": "server",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@company/shared": "workspace:*",
"express": "^4.19.0"
},
"devDependencies": {
"@types/express": "^4.17.21",
"tsx": "^4.7.0",
"typescript": "^5.4.0"
}
}
// apps/server/src/index.ts
import express from "express";
import { createSuccessResponse, API_VERSION } from "@company/shared";
const app = express();
const port = 3000;
app.get(`/api/${API_VERSION}/health`, (_req, res) => {
res.json(createSuccessResponse({ status: "healthy" }));
});
app.listen(port, () => {
console.log(`Server listening on http://localhost:${port}`);
});
// apps/server/tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"outDir": "dist",
"rootDir": "src",
"skipLibCheck": true
},
"include": ["src"]
}
4. 前端 apps/web
// apps/web/package.json
{
"name": "web",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"typecheck": "vue-tsc --noEmit"
},
"dependencies": {
"@company/shared": "workspace:*",
"vue": "^3.4.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.0",
"typescript": "^5.4.0",
"vite": "^5.2.0",
"vue-tsc": "^2.0.0"
}
}
// apps/web/index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>Web App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
// apps/web/src/main.ts
import { createApp } from "vue";
import App from "./App.vue";
import { API_VERSION } from "@company/shared";
console.log(`Frontend using API version: ${API_VERSION}`);
createApp(App).mount("#app");
// apps/web/src/App.vue
<template>
<div>企业级前端应用已启动</div>
</template>
<script setup lang="ts">
import { createSuccessResponse } from "@company/shared";
const demo = createSuccessResponse({ message: "shared module works" });
console.log(demo);
</script>
// apps/web/tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"jsx": "preserve",
"skipLibCheck": true
},
"include": ["src/**/*.ts", "src/**/*.vue"]
}
// apps/web/vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
export default defineConfig({
plugins: [vue()],
server: {
port: 5173
}
});
依赖安装与版本控制初始化
# 在项目根目录执行
git init
pnpm install
执行后,pnpm 会根据 workspace 配置自动链接 @company/shared 到前后端,并生成 pnpm-lock.yaml 锁文件。
验证方法与判定标准
- 类型检查:在根目录运行
pnpm typecheck,若所有包均无 TypeScript 错误,说明共享模块引用与类型配置正确。 - 后端启动:运行
pnpm dev:server,控制台输出Server listening on http://localhost:3000,访问http://localhost:3000/api/v1/health,预期返回 JSON:{"code":0,"data":{"status":"healthy"},"message":"ok"}。该输出由代码逻辑直接确定,非实测结果。 - 前端启动:运行
pnpm dev:web,浏览器打开http://localhost:5173,页面显示“企业级前端应用已启动”,且浏览器控制台输出Frontend using API version: v1与{code: 0, data: {message: 'shared module works'}, message: 'ok'},证明共享模块在前端生效。 - 版本控制:执行
git status,确认node_modules与dist未被跟踪,pnpm-lock.yaml已被跟踪。
判定标准:上述 4 项验证全部通过,即视为本案例目标达成。