Home » Как создать модуль в Node.js
Как создать модуль в Node.js

Как создать модуль в Node.js

Каждый Node.js разработчик рано или поздно сталкивается с необходимостью создать собственный модуль. Это может быть что-то простое для внутреннего использования или полноценный пакет для npm. Модули — это основа экосистемы Node.js, и понимание того, как их создавать, поможет тебе не только структурировать код, но и делиться решениями с сообществом. В этой статье разберём весь процесс от создания простого модуля до его публикации, плюс покажем несколько крутых трюков для продвинутых сценариев.

Как работает модульная система Node.js

В Node.js есть три типа модулей: встроенные (как fs или http), локальные (твои файлы) и внешние (из npm). Модульная система основана на CommonJS, но с версии 12 поддерживает и ES6 modules.

Каждый файл в Node.js — это отдельный модуль. Переменные и функции по умолчанию приватные, а чтобы сделать их доступными извне, используется module.exports или exports.

// math.js
const add = (a, b) => a + b;
const subtract = (a, b) => a - b;

module.exports = {
    add,
    subtract
};

// app.js
const math = require('./math');
console.log(math.add(5, 3)); // 8

Пошаговое создание модуля

Создадим простой модуль для работы с логами. Начнём с подготовки структуры:

mkdir my-logger
cd my-logger
npm init -y

Создаём основной файл модуля:

// index.js
const fs = require('fs');
const path = require('path');

class Logger {
    constructor(logFile = 'app.log') {
        this.logFile = path.resolve(logFile);
    }

    log(message, level = 'INFO') {
        const timestamp = new Date().toISOString();
        const logEntry = `[${timestamp}] ${level}: ${message}\n`;
        
        console.log(logEntry.trim());
        fs.appendFileSync(this.logFile, logEntry);
    }

    info(message) {
        this.log(message, 'INFO');
    }

    error(message) {
        this.log(message, 'ERROR');
    }

    warn(message) {
        this.log(message, 'WARN');
    }
}

module.exports = Logger;

Теперь создадим файл с примером использования:

// example.js
const Logger = require('./index');

const logger = new Logger('test.log');
logger.info('Приложение запущено');
logger.warn('Это предупреждение');
logger.error('Произошла ошибка');

Настройка package.json

Правильная настройка package.json — критически важна для модуля:

{
  "name": "my-awesome-logger",
  "version": "1.0.0",
  "description": "Простой логгер для Node.js",
  "main": "index.js",
  "scripts": {
    "test": "node test.js",
    "example": "node example.js"
  },
  "keywords": ["logger", "logging", "nodejs"],
  "author": "Your Name",
  "license": "MIT",
  "engines": {
    "node": ">=12.0.0"
  }
}

Ключевые поля:

  • main — точка входа в модуль
  • keywords — для поиска в npm
  • engines — минимальная версия Node.js
  • license — лицензия (MIT самая популярная)

ES6 модули vs CommonJS

Современный Node.js поддерживает ES6 modules. Для их использования добавь в package.json:

"type": "module"

Тогда код будет выглядеть так:

// logger.mjs
export class Logger {
    constructor(logFile = 'app.log') {
        this.logFile = logFile;
    }
    
    log(message) {
        console.log(`[${new Date().toISOString()}] ${message}`);
    }
}

export default Logger;

// app.mjs
import Logger from './logger.mjs';
const logger = new Logger();
logger.log('Hello World');
Аспект CommonJS ES6 Modules
Синтаксис require() / module.exports import / export
Загрузка Динамическая Статическая
Поддержка Все версии Node.js Node.js 12+
Производительность Медленнее Быстрее

Продвинутые возможности

Создание модуля с подмодулями

Для больших проектов создай структуру с подмодулями:

my-module/
├── index.js
├── lib/
│   ├── logger.js
│   ├── utils.js
│   └── config.js
└── package.json
// lib/logger.js
module.exports = class Logger {
    // твой код
};

// lib/utils.js
module.exports = {
    formatDate: (date) => date.toISOString(),
    sanitize: (str) => str.replace(/[^\w\s]/gi, '')
};

// index.js
const Logger = require('./lib/logger');
const utils = require('./lib/utils');

module.exports = {
    Logger,
    utils
};

Модуль с CLI интерфейсом

Добавь возможность использовать модуль как CLI утилиту:

// bin/cli.js
#!/usr/bin/env node
const Logger = require('../index');

const args = process.argv.slice(2);
const logger = new Logger();

if (args.length === 0) {
    console.log('Использование: my-logger "сообщение"');
    process.exit(1);
}

logger.info(args.join(' '));

Добавь в package.json:

"bin": {
    "my-logger": "./bin/cli.js"
}

Тестирование модуля

Создай простые тесты для проверки функциональности:

// test.js
const Logger = require('./index');
const fs = require('fs');

// Тест базовой функциональности
const logger = new Logger('test.log');
logger.info('Тестовое сообщение');

// Проверяем, что файл создался
if (fs.existsSync('test.log')) {
    console.log('✓ Лог файл создан');
} else {
    console.log('✗ Лог файл не создан');
}

// Очистка
fs.unlinkSync('test.log');
console.log('Тесты пройдены');

Публикация в npm

Если хочешь поделиться модулем с миром:

# Создай аккаунт на npmjs.com
npm login

# Проверь, что имя свободно
npm search my-awesome-logger

# Опубликуй
npm publish

Для обновления версии:

npm version patch  # 1.0.0 → 1.0.1
npm version minor  # 1.0.1 → 1.1.0
npm version major  # 1.1.0 → 2.0.0
npm publish

Интеграция с другими инструментами

Твой модуль может отлично работать с популярными инструментами:

С Express.js

const express = require('express');
const Logger = require('my-awesome-logger');

const app = express();
const logger = new Logger('server.log');

app.use((req, res, next) => {
    logger.info(`${req.method} ${req.url}`);
    next();
});

С PM2

// ecosystem.config.js
module.exports = {
    apps: [{
        name: 'my-app',
        script: 'app.js',
        env: {
            LOG_FILE: '/var/log/my-app.log'
        }
    }]
};

Оптимизация и производительность

Несколько советов для повышения производительности:

  • Асинхронные операции — используй fs.appendFile вместо fs.appendFileSync
  • Буферизация — накапливай логи в памяти и записывай пачками
  • Ротация файлов — ограничивай размер лог-файлов
// Асинхронная версия
const util = require('util');
const appendFile = util.promisify(fs.appendFile);

async log(message) {
    const logEntry = `[${new Date().toISOString()}] ${message}\n`;
    console.log(logEntry.trim());
    await appendFile(this.logFile, logEntry);
}

Деплой и использование на сервере

Для развёртывания на продакшен сервере понадобится надёжный VPS или выделенный сервер. Настройка окружения:

# Установка Node.js на Ubuntu/Debian
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

# Установка твоего модуля
npm install -g my-awesome-logger

# Использование в системных скриптах
echo "my-logger 'Система запущена'" >> /etc/rc.local

Интересные факты и нестандартные применения

Знаешь ли ты, что Node.js модули можно использовать не только в веб-приложениях?

  • Системная автоматизация — создавай модули для мониторинга сервера
  • IoT устройства — Node.js отлично работает на Raspberry Pi
  • Десктопные приложения — через Electron
  • Чат-боты — модули для Telegram, Discord, Slack

Например, модуль для мониторинга системы:

// system-monitor.js
const os = require('os');
const Logger = require('./index');

class SystemMonitor {
    constructor() {
        this.logger = new Logger('system.log');
    }

    monitor() {
        const stats = {
            cpu: os.loadavg(),
            memory: (os.freemem() / os.totalmem() * 100).toFixed(2),
            uptime: os.uptime()
        };
        
        this.logger.info(`CPU: ${stats.cpu[0]}, Memory: ${stats.memory}%, Uptime: ${stats.uptime}s`);
    }
}

module.exports = SystemMonitor;

Альтернативные решения

Если нужен более функциональный логгер, обрати внимание на готовые решения:

  • Winston — самый популярный логгер для Node.js
  • Bunyan — структурированные JSON логи
  • Pino — самый быстрый логгер
  • Log4js — портированный из Java

Ссылки на официальные проекты:

Заключение и рекомендации

Создание собственных модулей в Node.js — это не только способ структурировать код, но и отличная возможность поделиться решениями с сообществом. Начинай с простых модулей для внутренних нужд, изучай лучшие практики и постепенно переходи к более сложным решениям.

Основные рекомендации:

  • Используй семантическое версионирование — это поможет другим разработчикам
  • Пиши документацию — хотя бы README.md с примерами
  • Добавляй тесты — даже простые проверки лучше, чем ничего
  • Следи за зависимостями — минимизируй внешние пакеты
  • Используй TypeScript — для больших проектов это упростит поддержку

Модули особенно полезны для автоматизации рутинных задач на сервере: мониторинг, обработка логов, бэкапы, уведомления. Создавай библиотеки для повторяющихся операций и экономь время на будущих проектах.


В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.

Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.

Leave a reply

Your email address will not be published. Required fields are marked