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

1215

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

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

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

модуль

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

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

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

Теги:

10 ответов

1499
Лучший ответ

module.exports - это объект, который фактически возвращался в результате вызова require.

Первоначально переменная exports устанавливается на тот же объект (т.е. это сокращенный псевдоним), поэтому в коде модуля вы обычно пишете что-то вроде этого:

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

экспортировать (или "выставить" ) функции с внутренней областью myFunc1 и myFunc2.

В коде вызова вы должны использовать:

var m = require('mymodule');
m.myFunc1();

где последняя строка показывает, как результат require является (обычно) просто обычным объектом, свойства которого могут быть доступны.

Примечание: если вы перезаписываете exports, то он больше не будет ссылаться на module.exports. Поэтому, если вы хотите назначить новый объект (или ссылку на функцию) на exports, вы также должны назначить этот новый объект module.exports


Стоит отметить, что имя, добавленное к объекту exports, не обязательно должно совпадать с именем внутренней области модуля для добавляемого значения, чтобы вы могли:

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

а затем:

var m = require('mymodule');
m.shortName(); // invokes module.myVeryLongInternalName
  • 0
    Что если в этом модуле есть несколько функций, которые вы добавляете в экспорт? Тогда как бы вы определили, из какой функции вы хотите?
  • 106
    Хороший ответ - мне кажется, что «разоблачения» были бы лучшим выбором терминологии, чем «экспорт»
Показать ещё 25 комментариев
182

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

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

  • 0
    Как я могу позвонить Требовать некоторый модуль из другой папки, которая не имеет какой-либо корневой папки, как у меня?
  • 0
    @ user301639 вы можете использовать относительные пути для обхода иерархии файловой системы. require начинается относительно папки , которую вы выполнить node app.js . Я рекомендую вам добавить новый вопрос с явным кодом + структурой папок примерами , чтобы получить более четкий ответ.
Показать ещё 2 комментария
52

Обратите внимание, что механизм модуля 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 (кеширование и циклические ссылки))

30

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

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

Изображение 2168

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

17

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

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

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

Изображение 2169

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

8

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

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

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

4

В 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');

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

  • 1
    это экспорт или экспорт?
  • 0
    Спасибо за помощь :)
1

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

Предположим, что есть файл 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");
  • 0
    Спасибо Если это помогло вам, пожалуйста, примите мой ответ :)
  • 1
    Немного опоздал на вечеринку дружище :)
Показать ещё 3 комментария
0

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню