Яке призначення Node.js module.exports і як ви його використовуєте?


1432

Яке призначення Node.js module.exports і як ви його використовуєте?

Я не можу знайти будь-яку інформацію про це, але це, здається, є досить важливою частиною Node.js, оскільки я часто бачу її у вихідному коді.

Відповідно до документації Node.js :

модуль

Посилання на струм module. Зокрема, module.exports це те саме, що й об’єкт експорту. Див. Для src/node.jsотримання додаткової інформації.

Але це насправді не допомагає.

Що саме робить module.exports, і що може бути простим прикладом?

Відповіді:


1590

module.exports- це об'єкт, який фактично повертається в результаті requireдзвінка.

exportsМінлива спочатку встановлюється на той же об'єкт (тобто це скорочені «псевдонім»), так що в коді модуля, зазвичай пишуть що - щось на зразок цього:

let myFunc1 = function() { ... };
let myFunc2 = function() { ... };
exports.myFunc1 = myFunc1;
exports.myFunc2 = myFunc2;

експортувати (або "експонувати") внутрішньообласні функції myFunc1та myFunc2.

І в коді виклику, який ви використовуєте:

const m = require('./mymodule');
m.myFunc1();

де останній рядок показує, як результат requireє (як правило) просто простим об'єктом, до властивостей якого можна отримати доступ.

Примітка: якщо ви перезапишете, exportsце більше не посилатиметься module.exports. Отже, якщо ви хочете призначити новий об'єкт (або посилання на функцію), exportsви також повинні призначити цьому новому об'єктуmodule.exports


Варто відзначити, що ім'я, додане до exportsоб'єкта, не повинно бути таким самим, як внутрішнє ім'я модуля для значення, яке ви додаєте, щоб ви могли:

let myVeryLongInternalName = function() { ... };
exports.shortName = myVeryLongInternalName;
// add other objects, functions, as required

далі:

const m = require('./mymodule');
m.shortName(); // invokes module.myVeryLongInternalName

119
Хороша відповідь - мені здається, що "експозиція" була б кращим вибором термінології, ніж "експорт"
UpTheCreek

2
@ApopheniaOverload - ви можете зробити "export.func1, export.func2 тощо", щоб мати кілька відкритих методів з одного файлу.
Геллатан

73
Модуль вимагає повинен бути var m = requ ('./ mymodule'); , з крапкою та косою рисою. Таким чином Node.js знає, що ми використовуємо локальний модуль.
Gui Premonsa

7
Обов’язково використовуйте синтаксис вимагати ('./ module_name'), тому що, можливо, існують інші модулі node.js з деяким іменем, і замість вибору власного модуля він підбере той, який встановлено з node.js
Сазид

3
@UpTheCreek існує багаторічна традиція згадувати публічні символи, викриті модулем, як "експортовані", що датується багатьма системами програмування і десятиліттями. Це був не новий термін, придуманий розробниками Node.
Марк Рід

218

На це вже відповіли, але я хотів додати трохи уточнень ...

Ви можете використовувати і те, exportsі module.exportsімпортувати код у свою програму так:

var mycode = require('./path/to/mycode');

Основний випадок використання, який ви побачите (наприклад, у прикладі коду ExpressJS), це те, що ви встановлюєте властивості exportsоб’єкта у файлі .js, який ви імпортуєте за допомогоюrequire()

Отже, у простому прикладі підрахунку ви можете:

(counter.js):

var count = 1;

exports.increment = function() {
    count++;
};

exports.getCount = function() {
    return count;
};

... тоді у вашій програмі (web.js або справді будь-який інший файл .js):

var counting = require('./counter.js');

console.log(counting.getCount()); // 1
counting.increment();
console.log(counting.getCount()); // 2

Простіше кажучи, ви можете вважати потрібні файли функціями, які повертають один об'єкт, і ви можете додати властивості (рядки, числа, масиви, функції, будь-що) до об'єкта, який повертається, встановивши їх exports.

Іноді ви хочете, щоб об'єкт, повернутий з require()виклику, був функцією, яку ви можете викликати, а не просто об'єктом із властивостями. У такому випадку вам також потрібно встановити module.exports, як це:

(sayhello.js):

module.exports = exports = function() {
    console.log("Hello World!");
};

(app.js):

var sayHello = require('./sayhello.js');
sayHello(); // "Hello World!"

Різниця між експортом та module.exports пояснюється краще в цій відповіді тут .


як я можу викликати потрібний модуль з іншої папки, який не має кореневої папки як моєї?
Ігал

@ user301639 ви можете використовувати відносні шляхи для проходження ієрархії файлової системи. requireпочинається відносно папки, в якій ви виконуєте node app.js. Рекомендую вам опублікувати нове запитання із явними кодами + приклади структури папки, щоб отримати чіткішу відповідь.
Джед Уотсон

1
Мені довелося налаштувати ваш приклад module.exports, щоб він працював. Файл: var sayHello = require('./ex6_module.js'); console.log(sayHello());та модуль:module.exports = exports = function() { return "Hello World!"; }
Джейсон Лідон

1
Приклад збільшення природи виявився дійсно хорошим, і я використовував це для того, щоб освіжати свою думку щоразу, коли я перевантажувався тим, що роблю з експортом.
munkee

module.exports = exports = function(){...}2-е exports- це просто змінна правда? Іншими словами, це може бутиmodule.exports = abc = function()
Jeb50

60

Слід зазначити , що механізм модуля NodeJS заснований на CommonJS модулів , які підтримуються в багатьох інших реалізаціях , як RequireJS , але і SproutCore , CouchDB , Wakanda , OrientDB , ArangoDB , RingoJS , TeaJS , SilkJS , curl.js або навіть Adobe Photoshop (через PSLib ). Повний список відомих реалізацій можна знайти тут .

Якщо ваш модуль не використовує особливості вузла або модуля, я настійно рекомендую вам використовувати його, exportsзамість module.exports якого не входить до стандарту CommonJS , а потім переважно не підтримується іншими реалізаціями.

Ще одна особливість NodeJS - це коли ви присвоюєте посилання новому об'єкту exportsзамість того, щоб просто додавати до нього властивості та методи, як в останньому прикладі, наданому Джедом Уотсоном у цій темі. Я особисто заважаю цій практиці, оскільки це порушує циркулярну підтримку механізму модулів CommonJS. Тоді він не підтримується всіма реалізаціями, і приклад Jed повинен бути написаний таким чином (або подібний), щоб забезпечити більш універсальний модуль:

(sayhello.js):

exports.run = function() {
    console.log("Hello World!");
}

(app.js):

var sayHello = require('./sayhello');
sayHello.run(); // "Hello World!"

Або за допомогою функцій ES6

(sayhello.js):

Object.assign(exports, {
    // Put all your public API here
    sayhello() {
        console.log("Hello World!");
    }
});

(app.js):

const { sayHello } = require('./sayhello');
sayHello(); // "Hello World!"

PS: Схоже, Appcelerator також реалізує модулі CommonJS, але без кругової опорної підтримки (див.: Модулі Appcelerator та CommonJS (кешування та циркулярні посилання) )


35

Кілька речей, про які потрібно подбати, якщо ви призначите посилання на новий об’єкт exportsта / або modules.exports:

1. Усі властивості / методи, раніше приєднані до оригіналу, exportsабо module.exports, звичайно, втрачаються, оскільки експортований об'єкт тепер посилається на інший новий

Це очевидно, але якщо ви додали експортований метод на початку наявного модуля, переконайтеся, що нативний експортований об'єкт не посилається на інший об’єкт в кінці

exports.method1 = function () {}; // exposed to the original exported object
exports.method2 = function () {}; // exposed to the original exported object

module.exports.method3 = function () {}; // exposed with method1 & method2

var otherAPI = {
    // some properties and/or methods
}

exports = otherAPI; // replace the original API (works also with module.exports)

2. Якщо одне exportsабо module.exportsпосилається на нове значення, вони більше не посилаються на один і той же об'єкт

exports = function AConstructor() {}; // override the original exported object
exports.method2 = function () {}; // exposed to the new exported object

// method added to the original exports object which not exposed any more
module.exports.method3 = function () {}; 

3. Хитрий наслідок. Якщо ви зміните посилання на обидва exportsі module.exportsважко сказати, який API піддається (це схоже на module.exportsперемогу)

// override the original exported object
module.exports = function AConstructor() {};

// try to override the original exported object
// but module.exports will be exposed instead
exports = function AnotherConstructor() {}; 

29

властивість module.exports або об'єкт експорту дозволяє модулю вибрати те, що слід спільно використовувати додатку

введіть тут опис зображення

У мене тут доступне відео про module_export


18

При поділі програмного коду на кілька файлів module.exportsвикористовується для публікації змінних та функцій для споживача модуля. require()Виклик в вихідному файлі замінюється відповідним module.exportsзавантажений з модуля.

Пам'ятайте, коли пишете модулі

  • Навантаження модуля кешується, лише початковий виклик оцінює JavaScript.
  • Можна використовувати локальні змінні та функції всередині модуля, не все потрібно експортувати.
  • module.exportsОб'єкт також доступний в якості exportsстенографії. Але повертаючи єдину функцію, завжди використовуйте module.exports.

схема експорту модуля

Відповідно до: "Модулі, частина 2 - Написання модулів" .


9

посилання на посилання виглядає так:

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

властивості exportsабо module.exports, такі як функції чи змінні, будуть викриті назовні

Ви повинні звернути більше уваги: ​​не overrideекспортуйте.

чому?

оскільки експортується лише посилання на module.exports, ви можете додати властивості до експорту, але якщо ви перекриєте експорт, посилання буде порушено.

хороший приклад:

exports.name = 'william';

exports.getName = function(){
   console.log(this.name);
}

поганий приклад:

exports = 'william';

exports = function(){
     //...
}

Якщо ви хочете відкрити лише одну функцію або змінну, наприклад:

// test.js
var name = 'william';

module.exports = function(){
    console.log(name);
}   

// index.js
var test = require('./test');
test();

цей модуль відкрив лише одну функцію, а властивість імені зовні приватне.


6

У node.js є декілька модулів за замовчуванням або під час завантаження та встановлення node.js, таких як http, sys тощо.

Оскільки вони вже є у node.js, коли ми хочемо використовувати ці модулі, ми в основному робимо, як модулі імпорту , але чому? оскільки вони вже присутні в node.js. Імпорт - це як взяти їх з node.js та помістити їх у свою програму. А потім використовуючи їх.

Тоді як Експорт - якраз навпаки, ви створюєте потрібний модуль, скажімо, модуль add.js і вкладаєте цей модуль у node.js, ви це робите, експортуючи його.

Перш ніж я нічого писати тут, пам'ятайте, module.exports.additionTwo таке ж , як exports.additionTwo

Так, це причина, яку ми любимо

exports.additionTwo = function(x)
{return x+2;};

Будьте обережні з доріжкою

Скажімо, ви створили модуль add.js,

exports.additionTwo = function(x){
return x + 2;
};

При запуску цього в командному рядку NODE.JS:

node
var run = require('addition.js');

Це скаже помилку

Помилка. Неможливо знайти модуль add.js

Це тому, що процес node.js не в змозі add.js, оскільки ми не згадували шлях. Отже, ми можемо встановити шлях за допомогою NODE_PATH

set NODE_PATH = path/to/your/additon.js

Тепер це має працювати успішно без помилок !!

Ще одне, ви також можете запустити файл add.js, не встановивши NODE_PATH, повернутися до командного рядка nodejs:

node
var run = require('./addition.js');

Оскільки ми тут надаємо шлях, кажучи, що він знаходиться в поточному каталозі, ./це також має бути успішно виконаним .


1
це експорт чи експорт?
rudrasiva86

Дякую за допомогу :)
JumpMan

3

Модуль інкапсулює відповідний код в єдину одиницю коду. Під час створення модуля це можна інтерпретувати як переміщення всіх пов'язаних функцій у файл.

Припустимо, є файл Hello.js, який включає дві функції

sayHelloInEnglish = function() {
  return "Hello";
};
sayHelloInSpanish = function() {
  return "Hola";
};

Ми пишемо функцію лише тоді, коли корисність коду становить більше одного дзвінка.

Припустимо, ми хочемо збільшити корисність функції до іншого файлу, скажімо World.js, в цьому випадку експорт файлу приходить в картинку, яку можна отримати модулем.exports.

Ви можете просто експортувати обидві функції за допомогою наведеного нижче коду

var anyVariable={
 sayHelloInEnglish = function() {
      return "Hello";
    };
  sayHelloInSpanish = function() {
      return "Hola";
    }; 
}
module.export=anyVariable;

Тепер вам просто потрібно зажадати ім'я файлу в порядку вибору World.js, щоб використовувати ці функції

var world= require("./hello.js");

Дякую Якщо це допомогло вам прийняти мою відповідь :)
Shantanu Madane

1
Трохи запізнюємось на вечірку :)
Бен Таліадорос

@BenTaliadoros Я теж думаю, що він запізнюється, і я також думаю, що його об’єкт anyVariable має багато помилок. рядок над методом sayHelloInSpanish не повинен закінчуватися крапкою з комою (;), а sayHelloInSpanish = функція неправильна. З цим об’єктом все не так. я відредагую його відповідь
божественне

1
редагування вимкнено. Що ще редагував альфадогг у цій відповіді ??
божественне

Просто форматування. Якщо тільки на якусь божевільну річ es6 я не натрапив, і я впевнений, що це не так, тоді це взагалі не дійсний JS
Ben Taliadoros

2

Наміром є:

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

Вікіпедія

Я думаю, що важко писати великі програми без модульного / багаторазового коду. У nodejs ми можемо створювати модульні програми, використовуючи module.exportsвизначення того, що ми виставляємо та складати нашу програму require.

Спробуйте цей приклад:

fileLog.js

function log(string) { require('fs').appendFileSync('log.txt',string); }

module.exports = log;

stdoutLog.js

function log(string) { console.log(string); }

module.exports = log;

program.js

const log = require('./stdoutLog.js')

log('hello world!');

виконати

$ node program.js

Привіт Світ!

Тепер спробуйте поміняти ./stdoutLog.js на ./fileLog.js .


1

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

Він виконує такі речі:

  1. Зберігає наші файли від здуття живота до дійсно великих розмірів. Маючи файли з, наприклад, 5000 рядками коду в ньому, як правило, важко впоратися під час розробки.
  2. Забезпечує розділення проблем. Розбиття нашого коду на кілька файлів дозволяє нам мати відповідні імена файлів для кожного файлу. Таким чином ми можемо легко визначити, що робить кожен модуль і де його знайти (якщо припустити, що ми створили логічну структуру каталогів, яка все ще є вашою відповідальністю).

Наявність модулів полегшує пошук певних частин коду, що робить наш код більш доступним.

Як це працює?

NodejS використовує модульну систему CommomJS, яка працює наступним чином:

  1. Якщо файл хоче експортувати щось, він повинен оголосити його за допомогою module.exportсинтаксису
  2. Якщо файл хоче імпортувати щось, він повинен оголосити його за допомогою require('file')синтаксису

Приклад:

test1.js

const test2 = require('./test2');    // returns the module.exports object of a file

test2.Func1(); // logs func1
test2.Func2(); // logs func2

test2.js

module.exports.Func1 = () => {console.log('func1')};

exports.Func2 = () => {console.log('func2')};

Інші корисні речі, які потрібно знати:

  1. Модулі отримують кешування . Коли ви завантажуєте один і той же модуль у 2 різних файлах, модуль повинен бути завантажений лише один раз. Другий раз, коли a require()викликається на тому ж модулі, витягується з кеша.
  2. Модулі завантажуються синхронно . Така поведінка необхідна, якби вона була асинхронною, ми не могли отримати доступ до об'єкта, отриманого require()відразу.

-3
let test = function() {
    return "Hello world"
};
exports.test = test;

4
Це подібний приклад, як у першому фрагменті у прийнятій відповіді ( return "Hello world"не має значення), але без жодних пояснень. Перш ніж відповісти, переконайтесь, що ваша відповідь щось додасть до теми.
барбасан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.