module.exports против экспорта в Node.js - PullRequest
671 голосов
/ 21 августа 2011

Я нашел следующий контракт в модуле Node.js:

module.exports = exports = nano = function database_module(cfg) {...}

Интересно, в чем разница между module.exports и exports и почему оба используются здесь.

Ответы [ 21 ]

3 голосов
/ 18 октября 2016
var a = {},md={};

// Во-первых, export и module.exports указывают на один и тот же пустой объект

exp = a;//exports =a;
md.exp = a;//module.exports = a;

exp.attr = "change";

console.log(md.exp);//{attr:"change"}

// Если вы указываете exp на другой объект, а не указываете его свойство на другой объект.Md.exp будет пустым объектом {}

var a ={},md={};
exp =a;
md.exp =a;

exp = function(){ console.log('Do nothing...'); };

console.log(md.exp); //{}
3 голосов
/ 27 октября 2015

Вот результат

console.log("module:");
console.log(module);

console.log("exports:");
console.log(exports);

console.log("module.exports:");
console.log(module.exports);

enter image description here

Также:

if(module.exports === exports){
    console.log("YES");
}else{
    console.log("NO");
}

//YES

Примечание: Спецификация CommonJS позволяет использовать переменную export только для предоставления открытых членов. Следовательно, именованный шаблон экспорта является единственным, который действительно совместим со спецификацией CommonJS. Использование module.exports - это расширение, предоставляемое Node.js для поддержки более широкого диапазона шаблонов определения модулей.

3 голосов
/ 10 сентября 2015

Это показывает, как require() работает в простейшем виде, взято из Eloquent JavaScript

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

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

function require(name) {
  if (name in require.cache)
    return require.cache[name];
  var code = new Function("exports, module", readFile(name));
  var exports = {}, module = {exports: exports};
  code(exports, module);
  require.cache[name] = module.exports;
  return module.exports;
}
require.cache = Object.create(null);
3 голосов
/ 02 июля 2013

Я нашел эту ссылку полезной для ответа на поставленный выше вопрос.

http://timnew.me/blog/2012/04/20/exports-vs-module-exports-in-node-js/

Для добавления к другим сообщениям Система модулей в узле делает

var exports = module.exports 

перед выполнением вашего кода.Поэтому, когда вы хотите экспортировать = foo, вы, вероятно, захотите сделать module.exports = exports = foo, но с помощью export.foo = foo все будет в порядке

2 голосов
/ 05 марта 2014

"Если вы хотите, чтобы корнем экспорта вашего модуля была функция (например, конструктор), или если вы хотите экспортировать полный объект в одном назначении, а не создавать его по одному свойству за раз, назначьте его модулю.экспорт вместо экспорта ".- http://nodejs.org/api/modules.html

1 голос
/ 18 июня 2019

enter image description here

Каждый создаваемый вами файл является модулем.Модуль является объектом.У него есть свойство с именем exports : {}, которое по умолчанию является пустым объектом.

Вы можете создавать функции / промежуточное программное обеспечение и добавлять к этому пустому объекту экспорта, например exports.findById() => { ... } затем require, в любом месте вашего приложения и использовать его..

controllers / user.js

exports.findById = () => {
    //  do something
}

требуется в rout.js для использования:

const {findyId} = './controllers/user'
1 голос
/ 03 мая 2018

почему оба здесь используются

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

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

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


module.exports против exports

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

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

Установка exports для необъекта не имеет особого смысла, так как вам нужно будет установить module.exports = exports в конце, чтобы иметь возможность использовать его в других файлах.

let module = { exports: {} };
let exports = module.exports;

exports.msg = 'hi';
console.log(module.exports === exports); // true

exports = 'yo';
console.log(module.exports === exports); // false

exports = module.exports;
console.log(module.exports === exports); // true

module.exports = 'hello';
console.log(module.exports === exports); // false

module.exports = exports;
console.log(module.exports === exports); // true

Зачем назначать module.exports функции?

Более кратко!Сравните, насколько короче второй пример:

helloWorld1.js: module.exports.hello = () => console.log('hello world');

app1.js: let sayHello = require('./helloWorld1'); sayHello.hello; // hello world

helloWorld2.js: module.exports = () => console.log('hello world');

app2.js: let sayHello = require('./helloWorld2'); sayHello; // hello world

1 голос
/ 14 июня 2017

Давайте создадим один модуль двумя способами:

В одну сторону

var aa = {
    a: () => {return 'a'},
    b: () => {return 'b'}
}

module.exports = aa;

Второй способ

exports.a = () => {return 'a';}
exports.b = () => {return 'b';}

И вот как require () интегрирует модуль.

Первый способ:

function require(){
    module.exports = {};
    var exports = module.exports;

    var aa = {
        a: () => {return 'a'},
        b: () => {return 'b'}
    }
    module.exports = aa;

    return module.exports;
}

Второй способ

function require(){
    module.exports = {};
    var exports = module.exports;

    exports.a = () => {return 'a';}
    exports.b = () => {return 'b';}

    return module.exports;
}
1 голос
/ 26 февраля 2016

1.exports -> использовать в качестве утилиты-одиночки2. модуль-экспорт -> использовать в качестве логических объектов, таких как сервис, модель и т. Д.

0 голосов
  1. И module.exports, и exports указывают на одно и то же function database_module(cfg) {...}.

    1| var a, b;
    2| a = b = function() { console.log("Old"); };
    3|     b = function() { console.log("New"); };
    4|
    5| a(); // "Old"
    6| b(); // "New"
    

    Вы можете изменить b в строке 3 на a, вывод обратный. Вывод:

    a и b независимы.

  2. То есть module.exports = exports = nano = function database_module(cfg) {...} эквивалентно:

    var f = function database_module(cfg) {...};
    module.exports = f;
    exports = f;
    

    Предполагается, что выше указано module.js, что требуется для foo.js. Преимущества module.exports = exports = nano = function database_module(cfg) {...} теперь очевидны:

    • В foo.js, поскольку module.exports равно require('./module.js'):

      var output = require('./modules.js')();
      
    • В moduls.js: Вы можете использовать exports вместо module.exports.

Итак, вы будете счастливы, если оба exports и module.exports указывают на одно и то же.

...