express-modular-loader
v1.0.0
Published
Модульный загрузчик для структурирования Express-приложений
Downloads
8
Maintainers
Readme
Express Modular Loader
Элегантная система автоматической загрузки модулей для Express.js приложений
Обзор
Express Modular Loader помогает организовать код вашего Express приложения в модули, автоматически загружая роуты по заданной структуре каталогов. Этот подход упрощает масштабирование и поддержку больших приложений Express.
Особенности
- 🔀 Автоматическая загрузка роутов из модульной структуры
- 📁 Конвенции для организации проекта
- 🔄 Рекурсивная загрузка вложенных модулей с сохранением структуры URL
- 🔢 Настраиваемый порядок загрузки (файловая система, алфавитный, приоритетный)
- ⚙️ Гибкие настройки для фильтрации модулей
- 📊 Детальная информация о зарегистрированных маршрутах
Установка
npm install express-modular-loader --saveБыстрый старт
Базовое использование библиотеки:
const express = require('express');
const loadModules = require('express-modular-loader');
const app = express();
// Базовая настройка Express
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Загрузка модулей
(async () => {
try {
// Путь к директории с модулями
const modulesPath = './modules';
const result = await loadModules(app, modulesPath);
console.log('Загружено маршрутов:', result.summary.addedRoutes);
// Запускаем сервер
app.listen(3000, () => {
console.log('Сервер запущен на порту 3000');
});
} catch (error) {
console.error('Ошибка при загрузке модулей:', error);
}
})();Структура проекта
Рекомендуемая структура модулей для Express-приложения:
project/
├── app.js # Главный файл приложения
├── modules/ # Корневая директория модулей
│ ├── auth/ # Модуль авторизации
│ │ ├── controllers/ # Контроллеры
│ │ ├── middlewares/ # Middleware
│ │ ├── models/ # Модели данных
│ │ ├── services/ # Сервисы
│ │ └── routes/ # Директория с маршрутами
│ │ └── index.js # Основной файл маршрутов модуля (КЛЮЧЕВОЙ)
│ │
│ ├── users/ # Модуль пользователей
│ │ ├── controllers/
│ │ ├── models/
│ │ ├── services/
│ │ └── routes/
│ │ ├── index.js # Основной файл маршрутов
│ │ └── admin.js # Дополнительные маршруты для админов
│ │
│ └── products/ # Модуль продуктов
│ ├── controllers/
│ ├── models/
│ ├── services/
│ ├── routes/
│ │ └── index.js # Основной файл маршрутов
│ │
│ └── categories/ # Подмодуль категорий
│ ├── controllers/
│ ├── models/
│ └── routes/
│ └── index.js # Маршруты подмодуляФормирование URL-адресов
URL-пути формируются автоматически на основе структуры каталогов:
| Структура файлов | Итоговый URL маршрута |
|------------------------------------------|----------------------------------|
| /modules/users/routes/index.js | /users/** |
| /modules/users/routes/admin.js | /users/** (из того же роутера) |
| /modules/products/routes/index.js | /products/** |
| /modules/products/categories/routes/index.js | /products/categories/** |
Детальное руководство
Структура модуля
Ключевой файл: routes/index.js в каждом модуле
Пример структуры модуля:
users/
├── controllers/
│ ├── userController.js # Бизнес-логика пользователей
│ └── profileController.js # Логика профилей
├── models/
│ └── userModel.js # Модель данных
├── services/
│ └── userService.js # Сервисы для работы с данными
└── routes/
├── index.js # Основной файл маршрутов (КЛЮЧЕВОЙ)
└── admin.js # Дополнительные маршруты для админовПример файла маршрутов (routes/index.js)
Роутеры должны экспортироваться как модули:
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');
// Маршруты для пользователей
router.get('/', userController.listUsers);
router.get('/:id', userController.getUserById);
router.post('/', userController.createUser);
router.put('/:id', userController.updateUser);
router.delete('/:id', userController.deleteUser);
// Подключение дополнительных маршрутов или middleware
const adminRoutes = require('./admin');
router.use('/admin', adminRoutes);
module.exports = router;Параметры загрузчика
Функция loadModules принимает следующие параметры:
const result = await loadModules(app, modulesPath, {
// Настройки (все опциональны)
routesDirName: 'routes', // Имя папки с роутами
fileExtension: '.js', // Расширение файлов роутов
silent: false, // Подавлять логирование?
logger: console.log, // Функция логирования
include: ['users', 'products'], // Включать только эти модули (если [], то все)
exclude: ['deprecated'], // Исключать эти модули
loadOrder: 'priority', // Порядок загрузки модулей
priorityModules: ['auth', 'core'],// Приоритетные модули (для loadOrder='priority')
identifyMiddleware: true, // Пытаться определять имена middleware
});Варианты порядка загрузки (loadOrder)
Настройка loadOrder поддерживает следующие значения:
'filesystem'(по умолчанию) - в порядке чтения из файловой системы'alphabetical'- в алфавитном порядке (по имени модуля)'priority'- сначала загружаются модули из спискаpriorityModules, затем остальные- Функция сравнения - пользовательская функция сортировки
(a, b) => {...}
Пример с пользовательской сортировкой:
await loadModules(app, modulesPath, {
loadOrder: (a, b) => {
// Пользовательская логика сортировки модулей
// a и b - объекты с информацией о модулях
if (a.name === 'auth') return -1;
if (b.name === 'auth') return 1;
return a.name.length - b.name.length;
}
});Результат выполнения
Функция loadModules возвращает объект с информацией о загруженных маршрутах:
{
summary: {
initialRouteCount: 5, // Количество маршрутов до загрузки
finalRouteCount: 28, // Количество маршрутов после загрузки
addedRoutes: 23, // Количество добавленных маршрутов
modulesProcessed: 4 // Количество обработанных модулей
},
registeredRoutes: [ // Информация о загруженных маршрутах
{
prefix: "/users", // URL-префикс
file: "/path/to/modules/users/routes/index.js", // Файл
mountedAt: "2023-04-09T12:34:56.789Z", // Время загрузки
routesCount: 5, // Количество маршрутов в файле
routes: [ // Детальная информация о маршрутах
{
path: "/users", // Полный путь маршрута
methods: ["GET", "POST"], // HTTP-методы
middleware: ["listUsers", "createUser"] // Middleware
},
{
path: "/users/:id",
methods: ["GET", "PUT", "DELETE"],
middleware: ["getUserById", "updateUser", "deleteUser"]
}
]
},
// ...другие загруженные маршруты
]
}Примеры использования
Пример 1: Базовое использование
const express = require('express');
const loadModules = require('express-modular-loader');
const path = require('path');
const app = express();
app.use(express.json());
(async () => {
const modulesPath = path.join(__dirname, 'modules');
await loadModules(app, modulesPath);
app.listen(3000);
})();Пример 2: Настройка порядка загрузки
const express = require('express');
const loadModules = require('express-modular-loader');
const { LOAD_ORDER_PRIORITY } = require('express-modular-loader').constants;
const app = express();
(async () => {
await loadModules(app, './modules', {
loadOrder: LOAD_ORDER_PRIORITY,
priorityModules: ['auth', 'core'],
silent: true // Отключаем логирование
});
app.listen(3000);
})();Пример 3: Фильтрация модулей
const express = require('express');
const loadModules = require('express-modular-loader');
const app = express();
(async () => {
// Подключаем только определенные модули
await loadModules(app, './modules', {
include: ['users', 'products'], // Только эти модули будут загружены
exclude: ['deprecated'] // Эти модули будут исключены
});
app.listen(3000);
})();Пример 4: Использование нестандартной структуры
const express = require('express');
const loadModules = require('express-modular-loader');
const app = express();
(async () => {
await loadModules(app, './features', {
routesDirName: 'api', // Папка с роутами называется 'api'
fileExtension: '.route.js' // Файлы роутов имеют расширение '.route.js'
});
app.listen(3000);
})();Пример 5: Пользовательское логирование
const express = require('express');
const loadModules = require('express-modular-loader');
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [new winston.transports.Console()]
});
const app = express();
(async () => {
await loadModules(app, './modules', {
logger: logger.info.bind(logger)
});
app.listen(3000);
})();Советы и рекомендации
Организация модуля - старайтесь структурировать каждый модуль по принципу MVC:
controllers/- бизнес-логикаmodels/- модели данныхservices/(опционально) - сервисный слойroutes/- маршруты с минимумом логики
index.js как точка входа - используйте
routes/index.jsкак главный файл для маршрутов модуля. Из него можно подключать дополнительные роутеры.Вложенность модулей - создавайте подмодули при необходимости, их URL-пути будут формироваться автоматически.
Приоритеты загрузки - используйте настройку
loadOrderиpriorityModulesдля контроля порядка загрузки модулей (например, сначала модуль аутентификации).
Лицензия
MIT
