Node.js module.exports проти експорту

Що вони собою являють, як ними користуватися і як ними не користуватися

(Зверніть увагу, що ця стаття була написана після випуску Node.js 6.1.0)

TL; DR

  • Подумайте про module.exports як про змінну, яка повертається з require (). За замовчуванням це порожній об’єкт, і його можна змінити на що завгодно.
  • Експорт? Ну, а сам "експорт" ніколи не повертається!Це просто посилання на module.exports; зручна змінна, яка допомагає авторам модулів писати менше коду. Робота з його властивостями безпечна і рекомендована.
exports.method = function() {…} 
vs.
module.exports.method = function() {…}

Простий приклад модуля

По-перше, нам потрібен приклад кодової бази. Почнемо з простого калькулятора:

Використання:

Обгортка модуля

Node.js внутрішньо обгортає всі модулі, що вимагають (), у оболонку функції:

Об'єкт модуля

Змінна “ модуль ” - це об’єкт, що представляє поточний модуль. Він є локальним для кожного модуля , і це також приватні (доступно тільки з модуля коду):

Module.exports

  • Це посилання на об’єкт, яке повертається із викликів require ().
  • Він автоматично створюється Node.js.
  • Це просто посилання на звичайний об’єкт JavaScript.
  • Він також порожній за замовчуванням (наш код додає до нього метод “add ()”)

Існує два способи використання модуля.exports:

  1. Додавання до нього загальнодоступних методів (як це було зроблено в прикладі калькулятора).
  2. Заміна його на наш власний об’єкт або функцію.

Навіщо його замінювати? При заміні ми можемо повернути будь-який довільний екземпляр якогось іншого класу. Ось приклад, написаний у ES2015:

Вище, “калькулятор-база” експортує клас.

Давайте розширимо клас «Калькулятор» та експортуємо екземпляр цього разу:

Використання:

Експортує псевдонім

  • "Export" - це лише зручна змінна, тому автори модулів можуть писати менше коду
  • Робота з його властивостями безпечна і рекомендована.

    (наприклад: export.add = функція…)

  • Експорт НЕ повертається за допомогою require () (module.exports є!)

Ось декілька хороших і поганих прикладів:

Примітка: Загальноприйнятою практикою є заміна module.exports користувацькими функціями або об’єктами. Якщо ми зробимо це, але все одно хотіли б продовжувати використовувати скорочення “експорту”; тоді "експорт" потрібно перенаправити на наш новий спеціальний об'єкт (також виконаний у коді вище в рядку 12):

exports = module.exports = {}
exports.method = function() {...}

Висновок

Змінна з ім'ям export, яка експортується не повністю, бентежить, особливо для новачків у Node.js. Навіть офіційна документація теж має трохи дивний погляд:

В якості орієнтиру, якщо зв’язок між export і module.exports здається вам магічним, ігноруйте експортування та використовуйте лише module.exports.

Я вважаю, що код - це не магія. Розробники завжди повинні шукати глибшого розуміння платформ та мов, якими вони користуються. Роблячи це; програмісти отримують цінну впевненість і знання, що в свою чергу позитивно впливає на якість коду, архітектуру системи та продуктивність.

Дякую, що прочитали мій пост. Відгуки та думки завжди вітаються в розділі коментарів.

лазлоюли

Пов’язані статті:

  • Чи є модулі Node.js одиночними?

Джерела:

  • Документація Node.js щодо модулів

Ознайомтесь із моєю новою серією блогу щодо модульного модульного тестування:

Як розпочати роботу з модульним тестуванням? Частина 1

Думаю, багато хто з нас може мати відношення до ситуації, зображеної вище.

Місце, де одиничне тестування вважається рутинною роботою. medium.com