Что делать "модуль.экспорт" и "экспорт.методы " означают в NodeJS / Express?


глядя на случайную исходный файл на express рамки NodeJS, есть две строки кода, которые я не понимаю (эти строки кода типичны почти для всех файлов NodeJS).

/**
 * Expose `Router` constructor.
 */

exports = module.exports = Router;

и

/**
 * Expose HTTP methods.
 */

var methods = exports.methods = require('./methods');

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

Что делать exports и module.exports на самом деле означает?

Я считаю, что 2-й кусок кода позволяет функции в файле для доступа methods, но опять же, как именно это сделать.

в принципе, что это за волшебные слова:module и exports?

4 52

4 ответа:

чтобы быть более конкретным:

module - это глобальная переменная области внутри файла.

так что если вы называете require("foo") затем :

// foo.js
console.log(this === module); // true

он действует таким же образом, что window действует в браузере.

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

exports - это переменная, которая живет на module.exports. Это в основном то, что вы экспорт когда требуется файл.

// foo.js
module.exports = 42;

// main.js
console.log(require("foo") === 42); // true

есть небольшая проблема с exports сам по себе. Контекст _global scope + и module are не то же самое. (В браузере глобальный контекст области и window то же самое).

// foo.js
var exports = {}; // creates a new local variable called exports, and conflicts with

// living on module.exports
exports = {}; // does the same as above
module.exports = {}; // just works because its the "correct" exports

// bar.js
exports.foo = 42; // this does not create a new exports variable so it just works

подробнее об экспорте

чтобы расширить ответ Райноса...

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

//file 'module1.js'
module.exports.foo = function () { return 'bar' }
module.exports.baz = 5

тогда вы получите доступ к нему в своем коде:

var module1 = require('module1')
console.log(module1.foo())
console.log(module1.baz)

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

//glorp.js
module.exports = function () {
  this.foo = function () { return 'bar' }
  this.baz = 5
  return this // need to return `this` object here
}

теперь у вас есть хороший прототип:

var g1 = new require('glorp')()
console.log(g1.foo())
console.log(g1.baz)

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

Примечание

для следующего, чтобы работать,

var g1 = new require('glorp')()
console.log(g1.foo())
console.log(g1.baz) 

this должен быть возвращен в функции, которая назначена module.exports. В противном случае, вы получите TypeError:

console.log(g1.foo())
          ^
TypeError: Cannot read property 'foo' of undefined

вы можете найти лучший ответ в узел.исходный код JS. Если кому-то требуется ваш модуль js, ваш скрипт превращается в функцию по узлу следующим образом (см. src/node.js).

// require function does this..
(function (exports, require, module, __filename, __dirname) {
    ... your javascript contents...
});

узел обернет ваш скрипт. Тогда выше скрипт будет выполнен следующим образом:

//module.js
var args = [self.exports, require, self, filename, dirname];
return compiledWrapper.apply(self.exports, args);

Так в вашем скрипте,

exports is just module.exports.

в вашем скрипте вы можете добавить что-то к этому объекту экспорта (функции..). требуется функция возвращает этот объект. Это узел.модуль на JS по система (спецификация commonJS).

но будьте осторожны, чтобы не изменить модуль.поставляемый. В противном случае ваш текущий экспорт будет бессмысленным.

модуль-это объект, который представляет собой конкретный исходный файл хотел бы публично разоблачить. Вместо того, чтобы иметь что-то похожее на заголовочные файлы в мире c/c++, вы описываете, что модуль экспорт путем определения этого объекта. затем среда выполнения узла использует этот объект, чтобы определить, что в вашем модуле является "общедоступным".-

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