Какова цель Node.js module.exports и как вы ее используете?

Какова цель Node.js module.exports и как вы ее используете?

Я не могу найти никакой информации об этом, но, похоже, это довольно важная часть Node.js, как я часто вижу в исходном коде.

Согласно Node.js документации:

модуль

Ссылка на текущий module. В частности, module.exportsсовпадает с объектом экспорта. Видеть src/node.js для получения дополнительной информации.

Но это не помогает.

Что именно делает module.exports, и что может быть простым примером?

+1388
источник поделиться
13 ответов

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 (обычно) является простым объектом, свойства которого могут быть доступны.

NB. Если перезаписать 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
+1559
источник

Это уже ответили, но я хотел добавить некоторые пояснения...

Вы можете использовать как 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 объясняется лучше в этом ответе здесь.

+213
источник

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

Если ваш модуль не использует специальные функции или модуль node, я настоятельно рекомендую вам использовать export вместо module.exports , который не является частью Стандарт CommonJS, а затем в большинстве случаев не поддерживается другими реализациями.

Другая особенность NodeJS - это когда вы назначаете ссылку на новый объект на export вместо того, чтобы просто добавлять к нему свойства и методы, как в последнем примере, представленном Jed Watson в этом потоке. Я лично бы отказался от этой практики, так как эта нарушает круглую справочную поддержку механизма механизма модулей CommonJS. Затем он не поддерживается всеми реализациями, и пример Jed должен быть написан таким образом (или аналогичным) для обеспечения более универсального модуля:

(sayhello.js):

  export.run = function() {   console.log( "Hello World!" );
}
Код>

(app.js):

  var sayHello = require ('./sayhello');
sayHello.run();// "Привет мир!" 
Код>

Или используя функции ES6

(sayhello.js):

  Object.assign(экспорт, {   // Поместите весь свой публичный API здесь.   скажи привет() {       console.log( "Hello World!" );   }
});
Код>

(app.js):

  const {sayHello} = require ('./sayhello');
скажи привет();// "Привет мир!" 
Код>

PS: Похоже, что Appcelerator также реализует модули CommonJS, но без поддержки круглых ссылок (см. Модули Appcelerator и CommonJS (кеширование и циклические ссылки))

+60
источник

Несколько вещей, которые вы должны позаботиться, если назначить ссылку на новый объект на 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() {}; 
+34
источник

свойство module.exports или объект экспорта позволяет модулю выбирать, что должно быть совместно использовано с приложением

enter image description here

У меня есть видео на доступном module_export здесь

+29
источник

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

Помните при написании модулей

  • Загрузка модулей кэшируется, только исходный вызов оценивает JavaScript.
  • Можно использовать локальные переменные и функции внутри модуля, не все должно быть экспортировано.
  • Объект module.exports также доступен как стенограмма exports. Но при возврате единственной функции всегда используйте module.exports.

module exports diagram

В соответствии с: "Модули Часть 2 - Написание модулей" .

+18
источник

ссылка ссылается примерно так:

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();

этот модуль обнаруживает только одну функцию, а свойство имени является закрытым для внешнего.

+9
источник

В node.js есть определенные модули по умолчанию или существующие, когда вы загружаете и устанавливаете node.js, например http, sys и т.д.

Так как они уже находятся в node.js, когда мы хотим использовать эти модули, мы в основном используем модули импорта, но почему? потому что они уже присутствуют в node.js. Импорт - это как перенос их из node.js и включение их в вашу программу. И затем, используя их.

В то время как Экспорт в точности противоположный, вы создаете модуль, который вы хотите, скажем, module addition.js и помещая этот модуль в node.js, вы делаете это, экспортируя его.

Прежде чем писать что-нибудь здесь, помните, module.exports.additionTwo совпадает с export.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 не может быть добавлен. js, так как мы не упоминали путь. Таким образом, мы можем установить путь, используя NODE_PATH

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

Теперь это должно успешно работать без ошибок!

Кроме того, вы также можете запустить файл added.js, не установив NODE_PATH, обратно в командную строку nodejs:

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

Так как мы предоставляем путь сюда, указав его в текущем каталоге ./, это также должно успешно выполняться.

+6
источник

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

Предположим, что есть файл Hello.js, который включает в себя две функции

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

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

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

Вы можете просто экспортировать обе функции по приведенному ниже коду

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

Теперь вам просто нужно указать имя файла в World.js inorder для использования этих функций

var world= require("./hello.js");
+3
источник

Намерение:

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

Википедия

Я предполагаю, что становится трудно писать большие программы без модульного/многократно используемого кода. В 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

hello world!

Теперь попробуйте заменить ./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 разных файла, модуль должен быть загружен только один раз. Второй раз require() вызывается на том же модуле, который извлекается из кэша.
  2. Модули загружаются синхронно. Такое поведение необходимо, если оно было асинхронным, мы не могли бы сразу получить доступ к объекту, полученному из require().
+1
источник

Чтобы понять этот конкретный вопрос о том, какой экспорт или module.exports и как он работает, я хотел бы рекомендовать всем, кто ищет ответ, посетить эти сайты:

Надеюсь, это прояснит сомнения. Дайте мне знать, если это поможет!

0
источник
let test = function() {
    return "Hello world"
};
exports.test = test;
-1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос