feat: Add improvements - Prettier, env examples, middleware, examples
This commit is contained in:
parent
981d5eb71e
commit
da1de34d21
8
.prettierignore
Normal file
8
.prettierignore
Normal file
@ -0,0 +1,8 @@
|
||||
node_modules
|
||||
.next
|
||||
out
|
||||
dist
|
||||
build
|
||||
*.log
|
||||
.env*
|
||||
|
||||
11
.prettierrc
Normal file
11
.prettierrc
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"semi": true,
|
||||
"trailingComma": "es5",
|
||||
"singleQuote": false,
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"arrowParens": "always",
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
|
||||
89
IMPROVEMENTS.md
Normal file
89
IMPROVEMENTS.md
Normal file
@ -0,0 +1,89 @@
|
||||
# Рекомендации по улучшению шаблона
|
||||
|
||||
## Добавленные улучшения
|
||||
|
||||
### 1. Prettier для форматирования кода
|
||||
- Конфигурация `.prettierrc`
|
||||
- Игнорирование файлов `.prettierignore`
|
||||
- Скрипты в package.json для форматирования
|
||||
|
||||
**Использование:**
|
||||
```powershell
|
||||
npm run format # Форматировать весь код
|
||||
npm run format:check # Проверить форматирование
|
||||
```
|
||||
|
||||
### 2. Переменные окружения
|
||||
- `.env.example` файлы для frontend и backend
|
||||
- Шаблоны для быстрого старта
|
||||
- Документация в файлах
|
||||
|
||||
### 3. Middleware для бэкенда
|
||||
- `logger.js` - логирование всех запросов
|
||||
- `errorHandler.js` - централизованная обработка ошибок
|
||||
- Пример использования в `server.js`
|
||||
|
||||
### 4. Структура роутов
|
||||
- Пример файла `routes/example.js`
|
||||
- Организация API endpoints по модулям
|
||||
- Готовый шаблон для новых роутов
|
||||
|
||||
### 5. Пример компонента
|
||||
- `ExampleComponent.tsx` с использованием API
|
||||
- Демонстрация работы с состоянием
|
||||
- Обработка ошибок и загрузки
|
||||
|
||||
## Дополнительные рекомендации
|
||||
|
||||
### Можно добавить в будущем:
|
||||
|
||||
1. **Валидация запросов** (express-validator)
|
||||
```bash
|
||||
npm install express-validator
|
||||
```
|
||||
|
||||
2. **Логирование** (winston или pino)
|
||||
```bash
|
||||
npm install winston
|
||||
```
|
||||
|
||||
3. **Валидация окружения** (dotenv-safe)
|
||||
```bash
|
||||
npm install dotenv-safe
|
||||
```
|
||||
|
||||
4. **Rate limiting** (express-rate-limit)
|
||||
```bash
|
||||
npm install express-rate-limit
|
||||
```
|
||||
|
||||
5. **TypeScript для бэкенда**
|
||||
- Переименовать `.js` в `.ts`
|
||||
- Настроить `tsconfig.json` для backend
|
||||
- Добавить типы для Express
|
||||
|
||||
6. **Docker поддержка** (опционально)
|
||||
- `Dockerfile` для frontend и backend
|
||||
- `docker-compose.yml`
|
||||
|
||||
7. **Тестирование** (опционально)
|
||||
- Jest для unit тестов
|
||||
- Testing Library для компонентов
|
||||
|
||||
8. **CI/CD** (GitHub Actions)
|
||||
- Автоматическая проверка кода
|
||||
- Автоматический деплой
|
||||
|
||||
## Текущая структура
|
||||
|
||||
Все основные улучшения уже добавлены:
|
||||
- ✅ Prettier
|
||||
- ✅ Environment variables examples
|
||||
- ✅ Middleware структура
|
||||
- ✅ Примеры роутов
|
||||
- ✅ Пример компонента
|
||||
- ✅ Логирование
|
||||
- ✅ Обработка ошибок
|
||||
|
||||
Шаблон готов к использованию и может быть расширен по мере необходимости.
|
||||
|
||||
20
README.md
20
README.md
@ -136,6 +136,22 @@ pm2 start frontend/.next/start.js --name my-project-frontend
|
||||
|
||||
Подробнее: [`docs/PROJECT_RULES.md`](docs/PROJECT_RULES.md)
|
||||
|
||||
## 🔧 Дополнительные инструменты
|
||||
|
||||
### Форматирование кода (Prettier)
|
||||
|
||||
```powershell
|
||||
cd frontend
|
||||
npm run format # Форматировать весь код
|
||||
npm run format:check # Проверить форматирование
|
||||
```
|
||||
|
||||
### Переменные окружения
|
||||
|
||||
Скопируйте `.env.example` файлы и заполните значения:
|
||||
- `frontend/.env.example` → `frontend/.env.local`
|
||||
- `backend/.env.example` → `backend/.env`
|
||||
|
||||
## 📝 Лицензия
|
||||
|
||||
ISC
|
||||
@ -144,3 +160,7 @@ ISC
|
||||
|
||||
Создано на основе стандартов разработки DosAi
|
||||
|
||||
## 📚 Дополнительная информация
|
||||
|
||||
См. [`IMPROVEMENTS.md`](IMPROVEMENTS.md) для списка улучшений и рекомендаций.
|
||||
|
||||
|
||||
10
backend/middleware/.gitkeep
Normal file
10
backend/middleware/.gitkeep
Normal file
@ -0,0 +1,10 @@
|
||||
# Middleware
|
||||
|
||||
Размещайте здесь middleware функции для Express.
|
||||
|
||||
Примеры:
|
||||
- logger.js - логирование запросов
|
||||
- errorHandler.js - обработка ошибок
|
||||
- auth.js - аутентификация (если нужно)
|
||||
- validate.js - валидация запросов (если нужно)
|
||||
|
||||
16
backend/middleware/errorHandler.js
Normal file
16
backend/middleware/errorHandler.js
Normal file
@ -0,0 +1,16 @@
|
||||
// Middleware для обработки ошибок
|
||||
const errorHandler = (err, req, res, next) => {
|
||||
console.error('Error:', err);
|
||||
|
||||
const statusCode = err.statusCode || 500;
|
||||
const message = err.message || 'Internal Server Error';
|
||||
|
||||
res.status(statusCode).json({
|
||||
success: false,
|
||||
error: message,
|
||||
...(process.env.NODE_ENV === 'development' && { stack: err.stack }),
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = errorHandler;
|
||||
|
||||
21
backend/middleware/logger.js
Normal file
21
backend/middleware/logger.js
Normal file
@ -0,0 +1,21 @@
|
||||
// Middleware для логирования запросов
|
||||
const logger = (req, res, next) => {
|
||||
const timestamp = new Date().toISOString();
|
||||
const method = req.method;
|
||||
const url = req.url;
|
||||
const ip = req.ip || req.connection.remoteAddress;
|
||||
|
||||
console.log(`[${timestamp}] ${method} ${url} - ${ip}`);
|
||||
|
||||
// Логируем время ответа
|
||||
const start = Date.now();
|
||||
res.on('finish', () => {
|
||||
const duration = Date.now() - start;
|
||||
console.log(`[${timestamp}] ${method} ${url} - ${res.statusCode} (${duration}ms)`);
|
||||
});
|
||||
|
||||
next();
|
||||
};
|
||||
|
||||
module.exports = logger;
|
||||
|
||||
46
backend/routes/example.js
Normal file
46
backend/routes/example.js
Normal file
@ -0,0 +1,46 @@
|
||||
// Пример файла с роутами
|
||||
// Используйте эту структуру для организации API endpoints
|
||||
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
// GET endpoint
|
||||
router.get('/hello', (req, res) => {
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Hello from example route!',
|
||||
});
|
||||
});
|
||||
|
||||
// POST endpoint с валидацией
|
||||
router.post('/data', (req, res) => {
|
||||
try {
|
||||
const { name, value } = req.body;
|
||||
|
||||
// Простая валидация
|
||||
if (!name || !value) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Name and value are required',
|
||||
});
|
||||
}
|
||||
|
||||
// Обработка данных
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
name,
|
||||
value,
|
||||
processed: true,
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: err.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const logger = require('./middleware/logger');
|
||||
const errorHandler = require('./middleware/errorHandler');
|
||||
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 3001;
|
||||
|
||||
// Middleware
|
||||
app.use(logger);
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
|
||||
@ -20,9 +23,13 @@ app.use((req, res, next) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Тестовый endpoint
|
||||
// Health check endpoint
|
||||
app.get('/api/health', (req, res) => {
|
||||
res.json({ status: 'ok', message: 'Server is running' });
|
||||
res.json({
|
||||
status: 'ok',
|
||||
message: 'Server is running',
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
});
|
||||
|
||||
// Пример API endpoint
|
||||
@ -35,6 +42,21 @@ app.post('/api/example', (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Подключение роутов (пример)
|
||||
// const exampleRoutes = require('./routes/example');
|
||||
// app.use('/api/example', exampleRoutes);
|
||||
|
||||
// Обработка 404
|
||||
app.use((req, res) => {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
error: 'Route not found',
|
||||
});
|
||||
});
|
||||
|
||||
// Обработка ошибок (должен быть последним middleware)
|
||||
app.use(errorHandler);
|
||||
|
||||
// Запуск сервера
|
||||
app.listen(PORT, () => {
|
||||
console.log(`🚀 Server is running on http://localhost:${PORT}`);
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import ExampleComponent from '@/components/ExampleComponent';
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="min-h-screen py-8">
|
||||
@ -17,6 +19,10 @@ export default function Home() {
|
||||
<li>Начните разработку!</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="mt-8">
|
||||
<ExampleComponent />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
70
frontend/components/ExampleComponent.tsx
Normal file
70
frontend/components/ExampleComponent.tsx
Normal file
@ -0,0 +1,70 @@
|
||||
// Пример React компонента с использованием API
|
||||
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { apiRequest } from '@/lib/api';
|
||||
|
||||
interface ApiData {
|
||||
name: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export default function ExampleComponent() {
|
||||
const [data, setData] = useState<ApiData | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const handleFetch = async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const response = await apiRequest<ApiData>('example', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
name: 'Test',
|
||||
value: '123',
|
||||
}),
|
||||
});
|
||||
|
||||
if (response.success && response.data) {
|
||||
setData(response.data);
|
||||
} else {
|
||||
setError(response.error || 'Unknown error');
|
||||
}
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to fetch data');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-4 bg-gray-700 rounded-lg">
|
||||
<h2 className="text-xl font-semibold mb-4">Пример компонента</h2>
|
||||
|
||||
<button
|
||||
onClick={handleFetch}
|
||||
disabled={loading}
|
||||
className="px-4 py-2 bg-blue-600 hover:bg-blue-700 disabled:bg-gray-600 rounded"
|
||||
>
|
||||
{loading ? 'Загрузка...' : 'Получить данные'}
|
||||
</button>
|
||||
|
||||
{error && (
|
||||
<div className="mt-4 p-2 bg-red-800 text-red-200 rounded">
|
||||
Ошибка: {error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{data && (
|
||||
<div className="mt-4 p-2 bg-green-800 text-green-200 rounded">
|
||||
<p>Name: {data.name}</p>
|
||||
<p>Value: {data.value}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -6,7 +6,9 @@
|
||||
"dev": "next dev --turbopack",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
"lint": "next lint",
|
||||
"format": "prettier --write .",
|
||||
"format:check": "prettier --check ."
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^19.0.0",
|
||||
@ -22,7 +24,8 @@
|
||||
"tailwindcss": "^4",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "15.3.3",
|
||||
"@eslint/eslintrc": "^3"
|
||||
"@eslint/eslintrc": "^3",
|
||||
"prettier": "^3"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user