import os
import json
def create_nodejs_project_structure(project_name):
"""创建完整的Node.js项目结构"""
# 基础目录结构
directories = [
project_name,
f"{project_name}/src",
f"{project_name}/src/routes",
f"{project_name}/src/controllers",
f"{project_name}/src/models",
f"{project_name}/src/middlewares",
f"{project_name}/src/utils",
f"{project_name}/src/config",
f"{project_name}/tests",
f"{project_name}/tests/unit",
f"{project_name}/tests/integration",
f"{project_name}/public",
f"{project_name}/public/css",
f"{project_name}/public/js",
f"{project_name}/public/images",
f"{project_name}/views",
f"{project_name}/logs",
f"{project_name}/docs"
]
# 创建目录
for directory in directories:
os.makedirs(directory, exist_ok=True)
print(f"创建目录: {directory}")
# package.json 内容
package_json = {
"name": project_name.lower().replace(" ", "-"),
"version": "1.0.0",
"description": "Node.js项目",
"main": "src/server.js",
"scripts": {
"start": "node src/server.js",
"dev": "nodemon src/server.js",
"test": "jest",
"test:watch": "jest --watch",
"lint": "eslint src/",
"format": "prettier --write \"src/**/*.js\""
},
"keywords": ["nodejs", "express"],
"author": "Your Name",
"license": "MIT",
"dependencies": {
"express": "^4.18.0",
"dotenv": "^16.0.0",
"cors": "^2.8.5",
"helmet": "^7.0.0",
"compression": "^1.7.0"
},
"devDependencies": {
"nodemon": "^3.0.0",
"jest": "^29.0.0",
"supertest": "^6.3.0",
"eslint": "^8.0.0",
"prettier": "^3.0.0"
},
"engines": {
"node": ">=16.0.0"
}
}
# 创建文件
files = {
f"{project_name}/package.json": json.dumps(package_json, indent=2),
f"{project_name}/.gitignore": """node_modules/
.env
.DS_Store
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
coverage/
dist/
# IDE相关
.vscode/
.idea/
# 环境变量
.env.local
.env.development.local
.env.test.local
.env.production.local""",
f"{project_name}/.env.example": """NODE_ENV=development
PORT=3000
DATABASE_URL=mongodb://localhost:27017/mydb
JWT_SECRET=your_jwt_secret_key_here
API_KEY=your_api_key_here""",
f"{project_name}/README.md": f"""# {project_name}
## 项目描述
这是一个使用Node.js和Express框架构建的项目。
## 安装
\`\`\`bash
npm install
\`\`\`
## 环境配置
1. 复制 .env.example 为 .env
2. 根据实际情况修改环境变量
\`\`\`bash
cp .env.example .env
\`\`\`
## 运行
开发模式:
\`\`\`bash
npm run dev
\`\`\`
生产模式:
\`\`\`bash
npm start
\`\`\`
## 测试
运行测试:
\`\`\`bash
npm test
\`\`\`
## 项目结构
\`\`\`
{project_name}/
├── src/
│ ├── server.js # 应用入口
│ ├── app.js # Express应用配置
│ ├── routes/ # 路由文件
│ ├── controllers/ # 控制器
│ ├── models/ # 数据模型
│ ├── middlewares/ # 中间件
│ ├── utils/ # 工具函数
│ └── config/ # 配置文件
├── tests/ # 测试文件
├── public/ # 静态文件
├── views/ # 视图文件
├── .env # 环境变量
├── .gitignore # Git忽略文件
├── package.json # 项目依赖
└── README.md # 项目说明
\`\`\`
## API文档
[API文档链接](docs/api.md)
## 许可证
MIT""",
f"{project_name}/src/server.js": """const app = require('./app');
const dotenv = require('dotenv');
// 加载环境变量
dotenv.config();
const PORT = process.env.PORT || 3000;
// 启动服务器
app.listen(PORT, () => {
console.log(`🚀 服务器运行在 http://localhost:${PORT}`);
console.log(`📝 环境: ${process.env.NODE_ENV}`);
});
// 处理未捕获的异常
process.on('unhandledRejection', (reason, promise) => {
console.error('未处理的Promise拒绝:', reason);
});
process.on('uncaughtException', (error) => {
console.error('未捕获的异常:', error);
process.exit(1);
});""",
f"{project_name}/src/app.js": """const express = require('express');
const helmet = require('helmet');
const cors = require('cors');
const compression = require('compression');
const path = require('path');
// 导入路由
const indexRouter = require('./routes/index');
const app = express();
// 安全中间件
app.use(helmet());
// CORS配置
app.use(cors({
origin: process.env.CORS_ORIGIN || '*',
credentials: true
}));
// 压缩响应
app.use(compression());
// 解析请求体
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 静态文件服务
app.use(express.static(path.join(__dirname, '../public')));
// 设置视图引擎
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, '../views'));
// 基础路由
app.get('/health', (req, res) => {
res.status(200).json({
status: 'ok',
timestamp: new Date().toISOString(),
uptime: process.uptime()
});
});
// 使用路由
app.use('/', indexRouter);
// 404处理
app.use((req, res) => {
res.status(404).json({
error: 'Not Found',
message: '请求的资源不存在'
});
});
// 错误处理中间件
app.use((err, req, res, next) => {
console.error(err.stack);
const statusCode = err.status || 500;
const message = process.env.NODE_ENV === 'production'
? '服务器内部错误'
: err.message;
res.status(statusCode).json({
error: 'Internal Server Error',
message: message,
...(process.env.NODE_ENV === 'development' && { stack: err.stack })
});
});
module.exports = app;""",
f"{project_name}/src/routes/index.js": """const express = require('express');
const router = express.Router();
// 主页路由
router.get('/', (req, res) => {
res.json({
message: '欢迎使用Node.js API',
version: '1.0.0',
documentation: '/api-docs'
});
});
// API版本前缀
router.use('/api/v1', require('./api'));
module.exports = router;""",
f"{project_name}/src/routes/api.js": """const express = require('express');
const router = express.Router();
// 示例API路由
router.get('/users', (req, res) => {
res.json({
users: [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]
});
});
router.post('/users', (req, res) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({
error: '缺少必要字段'
});
}
res.status(201).json({
message: '用户创建成功',
user: { name, email }
});
});
module.exports = router;""",
f"{project_name}/src/utils/logger.js": """const fs = require('fs');
const path = require('path');
class Logger {
constructor() {
this.logDir = path.join(__dirname, '../../logs');
// 确保日志目录存在
if (!fs.existsSync(this.logDir)) {
fs.mkdirSync(this.logDir, { recursive: true });
}
}
log(level, message, data = {}) {
const timestamp = new Date().toISOString();
const logEntry = {
timestamp,
level,
message,
...data
};
const logString = JSON.stringify(logEntry) + '\\n';
// 写入日志文件
const logFile = path.join(this.logDir, `${level}.log`);
fs.appendFileSync(logFile, logString, 'utf8');
// 控制台输出
console.log(`[${timestamp}] ${level.toUpperCase()}: ${message}`);
}
info(message, data = {}) {
this.log('info', message, data);
}
error(message, error = null, data = {}) {
const errorData = error ? {
error: error.message,
stack: error.stack
} : {};
this.log('error', message, { ...data, ...errorData });
}
warn(message, data = {}) {
this.log('warn', message, data);
}
debug(message, data = {}) {
if (process.env.NODE_ENV === 'development') {
this.log('debug', message, data);
}
}
}
module.exports = new Logger();""",
f"{project_name}/src/config/database.js": """const mongoose = require('mongoose');
const connectDB = async () => {
try {
const conn = await mongoose.connect(process.env.DATABASE_URL, {
useNewUrlParser: true,
useUnifiedTopology: true
});
console.log(`✅ MongoDB连接成功: ${conn.connection.host}`);
return conn;
} catch (error) {
console.error(`❌ MongoDB连接失败: ${error.message}`);
process.exit(1);
}
};
module.exports = connectDB;""",
f"{project_name}/.eslintrc.json": """{
"env": {
"node": true,
"es2021": true,
"jest": true
},
"extends": ["eslint:recommended"],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"no-console": "warn",
"no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"eqeqeq": "error",
"curly": "error",
"semi": ["error", "always"],
"quotes": ["error", "single"]
}
}""",
f"{project_name}/jest.config.js": """module.exports = {
testEnvironment: 'node',
testMatch: ['**/tests/**/*.test.js'],
collectCoverageFrom: [
'src/**/*.js',
'!src/server.js',
'!**/node_modules/**'
],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80
}
},
verbose: true,
setupFilesAfterEnv: ['<rootDir>/tests/setup.js']
};""",
f"{project_name}/tests/setup.js": """// 测试环境配置
process.env.NODE_ENV = 'test';
// 加载环境变量
require('dotenv').config({ path: '.env.test' });""",
f"{project_name}/tests/unit/example.test.js": """describe('示例测试', () => {
test('加法测试', () => {
expect(1 + 1).toBe(2);
});
test('对象相等测试', () => {
const data = { one: 1 };
data['two'] = 2;
expect(data).toEqual({ one: 1, two: 2 });
});
test('真值测试', () => {
expect(true).toBeTruthy();
expect(false).toBeFalsy();
});
});""",
f"{project_name}/docs/api.md": """# API 文档
## 基础信息
- **基础URL**: `http://localhost:3000`
- **API版本**: `v1`
## 接口列表
### 健康检查
- **GET** `/health`
- 响应示例:
```json
{
"status": "ok",
"timestamp": "2024-01-01T00:00:00.000Z",
"uptime": 123.456
}
/api/v1/users{
"users": [
{
"id": 1,
"name": "Alice"
}
]
}
POST /api/v1/users
请求体:
{
"name": "John Doe",
"email": "john@example.com"
}
响应示例:
{
"message": "用户创建成功",
"user": {
"name": "John Doe",
"email": "john@example.com"
}
}
```"""
}
# 写入文件
for file_path, content in files.items():
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
print(f"创建文件: {file_path}")
print(f"\n✅ 项目 '{project_name}' 创建完成!")
print(f"📂 位置: {os.path.abspath(project_name)}")
print(f"\n📋 后续步骤:")
print(f"1. cd {project_name}")
print(f"2. npm install")
print(f"3. cp .env.example .env")
print(f"4. npm run dev")
if name == "main": project_name = input("请输入项目名称: ").strip() if not project_name: project_name = "my-nodejs-project"
create_nodejs_project_structure(project_name)
## 方法2:简洁版生成器
```python
import os
def create_minimal_nodejs_structure(project_name):
"""创建最简化的Node.js项目结构"""
structure = {
"package.json": """{
"name": "%s",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js"
},
"dependencies": {
"express": "^4.18.0"
},
"devDependencies": {
"nodemon": "^3.0.0"
}
}""" % project_name,
"index.js": """const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
app.use(express.json());
app.get('/', (req, res) => {
res.json({ message: 'Hello, World!' });
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});""",
".gitignore": """node_modules/
.env
*.log
.DS_Store""",
"README.md": """# %s
## Getting Started
1. Install dependencies:
\`\`\`bash
npm install
\`\`\`
2. Run in development mode:
\`\`\`bash
npm run dev
\`\`\`
3. Run in production mode:
\`\`\`bash
npm start
\`\`\`""" % project_name
}
os.makedirs(project_name, exist_ok=True)
for filename, content in structure.items():
filepath = os.path.join(project_name, filename)
with open(filepath, 'w', encoding='utf-8') as f:
f.write(content)
print(f"Created: {filepath}")
print(f"\n✅ Project '{project_name}' created successfully!")
# 使用示例
create_minimal_nodejs_structure("my-app")
import argparse
import os
import sys
def main():
parser = argparse.ArgumentParser(description='快速生成Node.js项目结构')
parser.add_argument('name', help='项目名称')
parser.add_argument('--type', choices=['minimal', 'full', 'api', 'cli'],
default='full', help='项目类型 (default: full)')
parser.add_argument('--no-git', action='store_true', help='不创建.git目录')
args = parser.parse_args()
if args.type == 'minimal':
create_minimal_nodejs_structure(args.name)
elif args.type == 'full':
create_nodejs_project_structure(args.name)
elif args.type == 'api':
create_api_project_structure(args.name)
elif args.type == 'cli':
create_cli_project_structure(args.name)
if not args.no_git:
init_git_repo(args.name)
print(f"\n🎉 项目生成完成!")
print(f"👉 进入项目目录: cd {args.name}")
def init_git_repo(project_name):
"""初始化Git仓库"""
import subprocess
try:
os.chdir(project_name)
subprocess.run(['git', 'init'], check=True)
subprocess.run(['git', 'add', '.'], check=True)
subprocess.run(['git', 'commit', '-m', 'Initial commit'], check=True)
os.chdir('..')
print("✅ Git仓库初始化完成")
except Exception as e:
print(f"⚠️ Git初始化失败: {e}")
if __name__ == "__main__":
main()
# 运行完整版本
python nodejs_generator.py
# 运行命令行版本
python nodejs_cli_generator.py my-project --type minimal
# 创建API项目
python nodejs_cli_generator.py my-api --type api
这个脚本会生成一个完整的、生产就绪的Node.js项目结构,包含了最佳实践和常用配置。