Module.exports در مقابل exports در نودجی‌اس
ﺯﻣﺎﻥ ﻣﻄﺎﻟﻌﻪ: 3 دقیقه

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

در این مقاله قصد داریم که بگوییم 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 استفاده کنید.

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

منبع

چه امتیازی برای این مقاله میدهید؟

خیلی بد
بد
متوسط
خوب
عالی
در انتظار ثبت رای

/@arastoo
ارسطو عباسی
کارشناس تولید و بهینه‌سازی محتوا

کپی رایتر، یوایکس رایتر، متخصص سئو محتوا و… عناوینی هستن که می‌تونم حرفه‌ام رو باهاشون خلاصه کنم اما جدای از این موارد، کتاب نوشتم، پادکست ضبط کردم، مارکتینگ محتوا انجام دادم و خلاصه تجربیات تا بخوایید در زمینه کلمات کسب کردم.

دیدگاه و پرسش

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

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

ارسطو عباسی

کارشناس تولید و بهینه‌سازی محتوا

مقالات برگزیده

مقالات برگزیده را از این قسمت میتوانید ببینید

مشاهده همه مقالات