Я нашел следующий контракт в модуле Node.js:
module.exports = exports = nano = function database_module(cfg) {...}
Интересно , Что между различными module.exports
и exports
почему используются оба здесь.
javascript
node.js
commonjs
Андреас Кёберле
источник
источник
exports
иmodule.exports
указывают на один и тот же объект, если вы не переназначите один. И в концеmodule.exports
возвращается. Поэтому, если вы переназначеныexports
на функцию, то не ожидайте функцию, поскольку она не будет возвращена. Однако, если бы вы назначили функцию, подобную этой,exports.func = function...
то получившаяся вещь имела бы свойство func со значением функции. Потому что вы добавили свойство к объекту, которыйexports
указывает на ..Ответы:
Настройка
module.exports
позволяетdatabase_module
вызывать функцию как функцию, когдаrequired
. Простая настройкаexports
не позволит экспортировать функцию, потому что узел экспортируетmodule.exports
ссылки на объекты . Следующий код не позволит пользователю вызвать функцию.module.js
Следующее не сработает.
Следующее будет работать, если
module.exports
установлено.приставка
По сути, node.js не экспортирует объект, на который в
exports
данный момент ссылается, а экспортирует свойства того, на чтоexports
изначально ссылается. Хотя Node.js экспортируетmodule.exports
ссылки на объекты , позволяя вам вызывать их как функции.2-я наименее важная причина
Они устанавливают оба параметра
module.exports
иexports
гарантируют,exports
что они не ссылаются на ранее экспортированный объект. Установив оба, вы будете использовать ихexports
как условное обозначение, чтобы избежать возможных ошибок в будущем.Использование
exports.prop = true
вместоmodule.exports.prop = true
сохранения персонажей и позволяет избежать путаницы.источник
nano.version = '3.3'
вместоmodule.exports.version = '3.3'
, что читается немного яснее. (Обратите внимание, чтоnano
это локальная переменная, объявленнаяmodule.exports
но нетexports
, мой код все еще работал бы? Спасибо за любую помощь!module.exports
Несмотря на то, что на вопрос был дан ответ и принят давно, я просто хочу поделиться своими 2 центами:
Вы можете представить, что в самом начале вашего файла есть что-то вроде (просто для объяснения):
Поэтому, что бы вы ни делали, просто имейте в виду, что
module.exports
НЕexports
будет возвращено из вашего модуля, когда вам потребуется этот модуль откуда-то еще.Поэтому, когда вы делаете что-то вроде:
Вы добавляете 2 функции
a
иb
к объекту, на которыйmodule.exports
тоже указывает, поэтомуtypeof
возвращаемый результат будетobject
:{ a: [Function], b: [Function] }
Конечно, это тот же результат, который вы получите, если будете использовать
module.exports
в этом примере вместоexports
.Это тот случай, когда вы хотите, чтобы вы
module.exports
вели себя как контейнер экспортируемых значений. Принимая во внимание, что если вы хотите экспортировать только функцию конструктора, вам нужно знать об использованииmodule.exports
илиexports
; (помните, чтоmodule.exports
это будет возвращено, когда вам что-то понадобится, а неexport
).Теперь
typeof
возвращаемый результат есть,'function'
и вы можете потребовать его и немедленно вызвать как:var x = require('./file1.js')();
потому что вы перезаписываете возвращаемый результат как функцию.Тем не менее, использование
exports
вы не можете использовать что-то вроде:Потому что с помощью
exports
, ссылка больше не указывает на объект, на которыйmodule.exports
указывает, так что нет никакой связи междуexports
иmodule.exports
больше. В этом случаеmodule.exports
все еще указывает на пустой объект,{}
который будет возвращен.Должен также помочь принятый ответ из другой темы: Javascript передается по ссылке?
источник
module.exports
модуль, например, в этомnpm
пакете: github.com/tj/consolidate.js/blob/master/lib/consolidate.jsexports.a = function(){}; works, exports = function(){} doesn't work
exports
? Почему бы просто не использовать всегда,module.exports
если это просто переназначение переменной? Кажется, смущает меня.exports.something
вместоmodule.exports.something
В основном ответ заключается в том, что действительно происходит, когда требуется модуль через
require
оператор. Предполагая, что это первый раз, когда модуль требуется.Например:
содержимое file1.js:
Когда приведенный выше оператор выполняется,
Module
объект создается. Его функция конструктора:Как видите, у каждого объекта модуля есть свойство с именем
exports
. Это то, что в конечном итоге возвращается как частьrequire
.Следующий шаг require - заключить содержимое файла file1.js в анонимную функцию, как показано ниже:
И эта анонимная функция вызывается следующим образом,
module
здесь ссылается наModule
Объект, созданный ранее.Как мы можем видеть внутри функции,
exports
формальный аргумент относится кmodule.exports
. По сути, это удобство, предоставляемое программисту модуля.Однако к этому удобству нужно относиться с осторожностью. В любом случае, если вы пытаетесь назначить новый объект для экспорта, убедитесь, что мы делаем это таким образом.
Если мы поступим неправильно ,
module.exports
все равно будем указывать на объект, созданный как часть экземпляра модуля.В результате добавление чего-либо к указанному выше объекту экспорта не повлияет на объект module.exports, и ничего не будет экспортировано или возвращено как часть require.
источник
exports = module.exports = {};
func()
не в ответе @ Уильяма!exports = module.exports = app;
в последней строке кода. Похоже, чтоmodule.exports
будет экспортировано, и мы никогда не будем использоватьexports
, потому что опять-таки это в последней строке кода. Итак, почему бы нам просто не добавитьmodule.exports = app;
Первоначально,
module.exports=exports
иrequire
функция возвращает объект, на которыйmodule.exports
ссылается.скажем , если мы добавим свойство к объекту,
exports.a=1
то module.exports и export по- прежнему ссылаются на тот же объект. Поэтому, если мы вызываем require и присваиваем модуль переменной, тогда переменная имеет свойство a и ее значение равно 1;Но если мы переопределим , например, один из них,
exports=function(){}
тогда они будут другими : export ссылается на новый объект, а module.exports ссылается на исходный объект. И если нам потребуется файл, он не вернет новый объект, поскольку module.exports не ссылается на новый объект.Для меня я буду продолжать добавлять новое свойство или переопределять их оба для нового объекта. Просто переопределить не правильно. И имейте в виду, что
module.exports
это настоящий босс.источник
exports
иmodule.exports
то же самое, если вы не переназначеныexports
в вашем модуле.Самый простой способ думать об этом, это думать, что эта строка неявно находится в верхней части каждого модуля.
Если в вашем модуле вы переназначаете
exports
, то вы переназначаете его в своем модуле, и он больше не равенmodule.exports
. Вот почему, если вы хотите экспортировать функцию, вы должны сделать:Если вы просто назначены ваш
function() { ... }
Toexports
, вы бы переназначениеexports
больше не указывают наmodule.exports
.Если вы не хотите обращаться к своей функции
module.exports
каждый раз, вы можете сделать:Обратите внимание, что
module.exports
это самый левый аргумент.Прикрепление свойств к
exports
не то же самое, поскольку вы не переназначаете его. Вот почему это работаетисточник
JavaScript передает объекты путем копирования ссылки
Это небольшая разница с тем, как объекты передаются по ссылке в JavaScript.
exports
иmodule.exports
оба указывают на один и тот же объект.exports
является переменной иmodule.exports
является атрибутом объекта модуля.Скажем, я пишу что-то вроде этого:
exports
иmodule.exports
теперь указывают на разные объекты. Изменение экспорта больше не изменяет module.exports.Когда функция импорта проверяет,
module.exports
она получает{b:12}
источник
Я просто провожу некоторый тест, и получается, что внутри кода модуля nodejs он должен выглядеть примерно так:
так:
1:
2:
3: но пока в этом случае
источник
module.exports
является своего рода «реального дела» , что узел уходит из , но в какой - то момент вам нужно добавить все ,exports
чтобы ,module.exports
если вы не будете использоватьexports.namespace
(случай 2 выше), в этом случае , кажется, как Узел пробежалextends(module.exports, exports);
добавление всех «пространств имен» изexports
кmodule.exports
объекту? Другими словами, если вы используете,exports
то вы, вероятно, хотите установить свойства для него?Вот хорошее описание, написанное о модулях узла в node.js в книге действий из публикации Мэннинга .
То, что в конечном итоге экспортируется в ваше приложение, это module.exports.
экспорт устанавливаются просто как глобальная ссылка на module.exports , который первоначально определяются как пустой объект , который можно добавить свойства. Так exports.myFunc просто сокращение для module.exports.myFunc .
В результате, если экспорт установлен на что - либо другое, он ломает ссылку между module.exports и экспорта . Потому что module.exportsэто то, что действительно экспортируется, экспорт больше не будет работать, как ожидалось - он больше не ссылается на модуль .exports . Если вы хотите сохранить эту ссылку, вы можете сделать module.exports ссылкой экспорта снова следующим образом :
источник
Я прошел некоторые тесты, и я думаю, что это может пролить свет на эту тему ...
app.js
:версии
/routes/index.js
:Я даже добавил новые файлы:
./routes/index.js
:./routes/not-index.js
:./routes/user.js
:Мы получаем вывод "@routes {}"
./routes/index.js
:./routes/not-index.js
:./routes/user.js
:Мы получаем вывод "@routes {fn: {}, user: {}}"
./routes/index.js
:./routes/not-index.js
:./routes/user.js
:Мы получаем вывод "@routes {user: [Function: user]}" Если мы изменим
user.js
на{ ThisLoadedLast: [Function: ThisLoadedLast] }
, мы получим вывод "@routes {ThisLoadedLast: [Function: ThisLoadedLast]}".Но если мы изменим
./routes/index.js
..../routes/index.js
:./routes/not-index.js
:./routes/user.js
:... мы получаем "@routes {fn: {fn: [Function: fn]}, ThisLoadedLast: {ThisLoadedLast: [Function: ThisLoadedLast]}}"
Поэтому я бы предложил всегда использовать
module.exports
в вашем модуле определения.Я не совсем понимаю, что происходит внутри с Node, но, пожалуйста, прокомментируйте, если вы можете понять это, так как я уверен, что это помогает.
- Счастливое кодирование
источник
Это показывает, как
require()
работает в простейшем виде, взято из Eloquent JavaScriptПроблема Модуль не может напрямую экспортировать значение, отличное от объекта экспорта, например функции. Например, модуль может захотеть экспортировать только конструктор типа объекта, который он определяет. Прямо сейчас это не может быть сделано, потому что require всегда использует
exports
объект, который создает, в качестве экспортируемого значения.Решение Предоставьте модулям другую переменную,
module
которая является объектом со свойствомexports
. Это свойство изначально указывает на пустой объект, созданный require, но может быть перезаписано другим значением для экспорта чего-то другого.источник
Вот результат
Также:
Примечание. Спецификация CommonJS позволяет использовать переменную export только для предоставления открытых членов. Следовательно, именованный шаблон экспорта является единственным, который действительно совместим со спецификацией CommonJS. Использование module.exports - это расширение, предоставляемое Node.js для поддержки более широкого диапазона шаблонов определения модулей.
источник
// Во-первых, export и module.exports указывают на один и тот же пустой объект
// Если вы указываете exp на другой объект, а не указывает на его свойство на другой объект. Md.exp будет пустым Object {}
источник
Из документов
Это просто переменная, указывающая на module.exports.
источник
Я нашел эту ссылку полезной, чтобы ответить на поставленный выше вопрос.
http://timnew.me/blog/2012/04/20/exports-vs-module-exports-in-node-js/
Добавить к другим сообщениям Система модулей в узле делает
перед выполнением вашего кода. Поэтому, когда вы хотите экспортировать = foo, вы, вероятно, захотите сделать module.exports = exports = foo, но использование export.foo = foo должно быть хорошо
источник
«Если вы хотите, чтобы корнем экспорта вашего модуля была функция (например, конструктор), или если вы хотите экспортировать полный объект за одно присваивание, а не создавать его по одному свойству за раз, назначьте его для module.exports вместо экспорт «. - http://nodejs.org/api/modules.html
источник
module.exports
а такжеexports
оба указывают на один и тот же объект до оценки модуля.Любое свойство, которое вы добавляете к
module.exports
объекту, будет доступно, когда ваш модуль используется в другом модуле usingrequire
.exports
это ярлык, доступный для той же вещи. Например:эквивалентно написанию:
Так что все в порядке, если вы не назначаете новое значение
exports
переменной. Когда вы делаете что-то вроде этого:как вы назначаете новое значение
exports
оно больше не имеет ссылки на экспортируемый объект и, таким образом, останется локальным для вашего модуля.Если вы планируете назначить новое значение,
module.exports
а не добавлять новые свойства к исходному объекту, доступному, вам, вероятно, следует рассмотреть возможность сделать это, как указано ниже:Сайт Node.js имеет очень хорошее объяснение этого.
источник
1.exports -> использовать в качестве единой утилиты
2. module-exports -> использовать в качестве логических объектов, таких как сервис, модель и т. Д.
источник
Давайте создадим один модуль двумя способами:
В одну сторону
Второй способ
И вот как require () будет интегрировать модуль.
Первый способ:
Второй способ
источник
Я считаю , что они просто хотят , чтобы быть ясно , что
module.exports
,exports
иnano
указывают на ту же функцию - позволяет использовать любую переменную для вызова функции в файле.nano
обеспечивает некоторый контекст для того, что делает функция.exports
не будет экспортироваться (толькоmodule.exports
будет), так зачем перезаписывать это?Компромисс между подробностями ограничивает риск будущих ошибок, таких как использование
exports
вместоmodule.exports
файла. Это также дает пояснение, чтоmodule.exports
иexports
фактически указывает на то же значение.module.exports
противexports
Пока вы не переназначаете
module.exports
илиexports
(и вместо этого добавляете значения к объекту, на который они оба ссылаются), у вас не возникнет никаких проблем, и вы можете смело использовать его,exports
чтобы быть более лаконичным.При назначении какому-либо не объекту, они теперь указывают на разные места, которые могут сбивать с толку, если вы намеренно не хотите
module.exports
быть чем-то конкретным (например, функцией).Установка
exports
не-объекта не имеет особого смысла, так как вам придется установитьmodule.exports = exports
в конце, чтобы иметь возможность использовать его в других файлах.Зачем назначать
module.exports
функции?Более лаконично! Сравните, насколько короче второй пример:
helloWorld1.js:module.exports.hello = () => console.log('hello world');
app1.js:
helloWorld2.js:let sayHello = require('./helloWorld1'); sayHello.hello; // hello world
module.exports = () => console.log('hello world');
app2.js:
let sayHello = require('./helloWorld2'); sayHello; // hello world
источник
Каждый созданный вами файл является модулем. Модуль является объектом. У него есть свойство,
exports : {}
которое называется пустым объектом по умолчанию.Вы можете создать функции / и промежуточное программное к этому добавить пустой объект экспорта , такие , как
exports.findById() => { ... }
то вrequire
любом месте вашего приложения и использования ...Контроллеры / user.js
требуется в route.js использовать:
источник
Чтобы понять различия, вы должны сначала понять, что Node.js делает с каждым модулем во время выполнения. Node.js создает функцию-обертку для каждого модуля:
Обратите внимание, что первый параметр
exports
- это пустой объект, а третий параметрmodule
- это объект со многими свойствами, и одно из свойств называетсяexports
. Это то, чтоexports
исходит и чтоmodule.exports
исходит. Первый является переменным объектом, а второй является свойствомmodule
объекта.Внутри модуля Node.js автоматически делает это в начале:
module.exports = exports
и в конечном итоге возвращаетmodule.exports
.Таким образом, вы можете видеть, что если вы переназначите какое-то значение
exports
, это не будет иметь никакого эффектаmodule.exports
. (Просто потому, чтоexports
указывает на другой новый объект, ноmodule.exports
все еще содержит старыйexports
)Но если вы обновите свойства
exports
, это, безусловно, повлияет наmodule.exports
. Потому что они оба указывают на один и тот же объект.Также обратите внимание, что если вы переназначаете другое значение на
module.exports
, то оно кажется бессмысленным дляexports
обновлений. Каждое обновлениеexports
игнорируется, посколькуmodule.exports
указывает на другой объект.источник
в узле js файл module.js используется для запуска module.load system.every, каждый раз, когда узел выполняет файл, он переносит содержимое файла js следующим образом
Из-за этого переноса в исходный код ur js вы можете получить доступ к export, require, module и т. д., этот подход используется, потому что нет другого способа передать функции, записанные в js-файле, в другой.
затем узел выполняет эту упакованную функцию, используя c ++. в этот момент объект экспорта, переданный в эту функцию, будет заполнен.
Вы можете увидеть внутри этой функции параметры экспорта и модуля. на самом деле export является открытым членом функции конструктора модуля.
посмотрите на следующий код
скопируйте этот код в b.js
скопируйте этот код в a.js
Теперь запустить с использованием узла
это выход
экспорт является [объект объекта]
object.keys из foo: name is function () {console.log ('функция для экспорта в модуль')} функция для экспорта в модуль
Теперь удалите закомментированную строку в a.js и закомментируйте строку над этой строкой, удалите последнюю строку b.js и запустите.
в мире javascript вы не можете переназначить объект, переданный в качестве параметра, но вы можете изменить открытый член функции, когда объект этой функции задан в качестве параметра другой функции
помнишь
Используйте module.exports и только в том случае, если вы хотите получить функцию при использовании ключевого слова require. в приведенном выше примере мы var foo = require (a.js); вы можете видеть, что мы можем вызвать foo как функцию;
Вот как это объясняется в документации узла: «Объект экспорта создается системой Module. Иногда это неприемлемо, многие хотят, чтобы их модуль был экземпляром некоторого класса. Для этого назначьте нужный объект экспорта для module.exports.»
источник
Вы можете изменить
b
в строке 3 наa
, выход обратный. Вывод:Так
module.exports = exports = nano = function database_module(cfg) {...}
что эквивалентно:Предполагается, что выше
module.js
, что требуетсяfoo.js
. Преимуществаmodule.exports = exports = nano = function database_module(cfg) {...}
очевидны сейчас:В
foo.js
, так какmodule.exports
этоrequire('./module.js')
:В
moduls.js
: Вы можете использоватьexports
вместоmodule.exports
.Итак, вы будете счастливы, если оба
exports
иmodule.exports
указываете на одно и то же.источник