Module.exports در مقابل exports در نودجی‌اس

گردآوری و تالیف : ارسطو عباسی
تاریخ انتشار : 26 تیر 1397
دسته بندی ها : جاوا اسکریپت

در این مقاله قصد داریم که بگوییم module.exports و exports چه هستند، چگونه از آن‌ها استفاده کنید و در چه جاهایی از آن‌ها دست بکشید!

TL;DR

  • به module.exports مانند یک متغیر فکر کنید که مقداری را از require() دریافت کرده و در خود ذخیره می‌کند. به صورت پیشفرض این مورد یک شئ خالی است و قابلیت تغییر به هر چیزی را دارد.
  • Exports چیست؟! خب، exports هیچوقت برگشت داده نمی‌شود! این مورد تنها یک رفرنس به module.exports است؛ در حقیقت می‌شود گفت که یک متغیر است، بنابراین نویسندگان ماژول‌ها مجبور به نوشتن‌ کدهای زیادی نخواهند بود. کار کردن با این خصوصیات کاملا امن و پیشنهاد شده است.
exports.method = function() {…} 
vs.
module.exports.method = function() {…}

یک مثال ساده از ماژول

ابتدا نیاز است که یک مثال از کدهای اصلی داشته باشیم. بیایید با یک ماشین حساب ساده کارمان را شروع کنیم:

// calculator.js

module.exports.add = (a,b) => a+b

روش استفاده:

// app-use-calculator.js

const calculator = require('./calculator.js')
console.log(calculator.add(2,2)) // prints 4

بسته‌بندی ماژول‌ها

نودجی‌اس به صورت داخلی تمام ماژول‌هایی که require() شده‌اند را در یک تابع بسته‌بندی می‌کند:

(function (exports, require, module, __filename, __dirname) {
  
  // calculator.js is actually executed here
  module.exports.add = (a,b) => a+b
  
});

شئ ماژول

متغیر ماژول یک شئ است که ماژول کنونی را نمایش می‌دهد. این مورد برای هر ماژولی محلی است و دسترسی خصوصی دارد.

// calculator-printed.js

module.exports.add = (a,b) => a+b

console.log(module)

/*
When this module is called by require('./calculator-printed.js') log prints:
Module {
  id: '/Users/laz/repos/module-exports/calculator-printed.js',
  exports: { add: [Function] },
  parent: 
    Module { ... }
  filename: '/Users/laz/repos/module-exports/calculator-printed.js',
  loaded: false,
  children: [],
  paths: [ ... ]
}
*/

Module.exports

این مورد:

  • یک شئ منبع است که از require() فراخوانی می‌شود.
  • به صورت خودکار توسط نودجی‌اس ایجاد می‌شود.
  • یک رفرنس شئ جاوااسکریپتی ساده است.
  • به صورت پیشفرض خالی است.

دو راه برای اینکه از module.exports استفاده کنیم وجود دارد:

۱. اتصال متدهای عمومی به آن. (کاری که ما در مثال ماشین حساب انجام دادیم)

۲. جایگزین کردن آن با یک شئ یا تابع سفارشی

چرا باید عمل جایگزین کردن را انجام دهیم؟ وقتی از روش جایگزین کردن استفاده کنیم، می‌توانیم هر نمونه‌ای را از کلاس‌های دیگر برداریم. در این رابطه می‌توانید مثالی با استفاده از ES2015 را مشاهده کنید:

// calculator-base.js

module.exports = class Calculator {
  add(a,b) { return a + b }
  substract(a,b) { return a - b }
}

در بالا، calculator-base یک کلاس را export می‌کند.

حال بیایید کلاس Calculator را با توسعه داده و همزمان از یک نمونه export بگیریم:

// calculator-advanced.js

const Calculator = require('./calculator-base.js')

class AdvancedCalculator extends Calculator {
  multiply(a,b) { return a * b }
  divide(a,b) { return a / b }
}

module.exports = new AdvancedCalculator()

برای استفاده از این کلاس به صورت زیر عمل می‌کنیم:

// app-use-advanced-calculator.js

const calculator = require('./calculator-advanced.js')

console.log(calculator.add(2,2)) // prints 4
console.log(calculator.multiply(3,3)) // prints 9

Exports alias

  • exports تنها یک متغیر است، بنابراین نویسندگان ماژول‌ها می‌توانند کدهای کمتری بنویسند.
  • کار کردن با خصوصیات این مورد امن و پیشنهاد شده است. (مثلا: exports.add=function...)
  • Exports توسط require() برگشت داده نمی‌شود.

در اینجا می‌توانید چند مثال خوب و بد را مشاهده کنید:

// calculator-exports-examples.js

// good
module.exports = {
  add(a,b) { return a+b }
}

// good
module.exports.subtract = (a,b) => a-b

// valid
exports = module.exports

// good and simply a shorter version of the code above
exports.multiply = (a,b) => a*b

// bad, exports is never exported
exports = {
  divide(a,b) { return a/b }
}

نکته: این موضوع که بتوانیم module.exports را با یک تابع یا شئ سفارشی جایگزین کنیم، رویکردی محبوب و عادی است. اگر بخواهیم از این حالت استفاده کنیم و همزمان exports را در اختیار داشته باشیم بنابراین exports را باید به شئ سفارشی متصل کنیم:

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

در پایان

یک متغیر با نام exports که به صورت کامل export نشده است ممکن است کمی گنگ باشد، این موضوع مخصوصا برای تازه‌کاران دنیای نودجی‌اس بسیار صدق می‌کند. حتی مستندات رسمی نگاهی عجیب و کمی گنگ به این مسئله دارند. 

اگر ارتباط بین exports و module.exports برای شما سخت و عجیب است، پس exoports را ول کرده و تنها از module.exports استفاده کنید.

به نظر من که برای یک برنامه‌نویس هیچ چیزی نباید سخت و عجیب باشد، توسعه‌دهندگان همیشه باید نگاهی عمیق و دقیق از پلتفرم و زبانی که استفاده می‌کنند داشته باشند. با انجام چنین کاری برنامه‌نویس می‌تواند ادعا کند که دانش کافی برای نوشتن کدهایی با کیفیت بالا را دارد.

منبع

مقالات پیشنهادی

بهترین سیستم عامل سرور : لینوکس یا ویندوز

اگر مشغول توسعه وب باشید و به صورت کامل راجع به این مسئله اطلاعاتی داشته باشید می دانید که همیشه دو سیستم عامل سرور محبوب و مرسوم وجود دارد. این دو سی...

۵ مورد از دلایلی که باعث می‌شود نودجی‌اس جایگزین جاوا شود

بدون شک جاوا برای مدت طولانی یکی از محبوب‌ترین زبان‌های برنامه‌نویسی بوده است. اما حال نودجی‌اس به کمک جاوااسکریپت توانسته است که میزان محبوبیت خود را...

چگونه یک اپلیکیشن بلادرنگ ورزشی را با نودجی‌اس بنویسیم؟

در این آموزش قصد دارم شیوه ساخت اپلیکیشن ورزشی که می‌تواند نتایج بازی‌ها را به صورت بلاردنگ از NHL دریافت می‌کند و به کاربر نمایش دهد را توضیح دهم. ام...

هوش مصنوعی - پردازش زبان طبیعی با استفاده از نودجی‌اس

در چند سال اخیر هوش مصنوعی و یادگیری ماشین بیشتر شکل و قالب وب را به خود گرفته‌اند. بخشی از این قضیه مربوط به توسعه‌دهندگانی می‌شود که شور و اشتیاق زی...