Можете ли вы экспортировать несколько классов из одного модуля Nodejs?

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

var Jack = require('./Jack.js');
var JackInstance = new Jack();
var Jones = require('./Jones.js');
var JonesInstance = new Jones();

Я хотел бы импортировать их как это

var People = require('./People.js');
var JackInstance = new People.Jack();

Или даже

var Jack = require('./People.js').Jack;
var JackInstance = new Jack();

Мои классы определены так

class Jack{
    //Memeber variables, functions, etc
}

module.exports = Jack;

Ответ 1

Вы можете экспортировать несколько классов следующим образом:

например People.js

class Jack{
   //Member variables, functions, etc
}

class John{
   //Member variables, functions, etc
}

module.exports = {
  Jack : Jack,
  John : John
}

И доступ к этим классам, как вы правильно упомянули:

var People = require('./People.js');
var JackInstance = new People.Jack();
var JohnInstance = new People.John();

Ответ 2

Вы также можете сделать это в более короткой форме, используя деструктурирующие назначения (которые поддерживаются изначально, начиная с Node.js v6.0.0):

// people.js

class Jack {
  // ...
}

class John {
  // ...
}

module.exports = { Jack, John }

Импорт:

// index.js

const { Jack, John } = require('./people.js');

Или даже так, если вы хотите, чтобы псевдонимы требовали назначения:

// index.js

const {
  Jack: personJack, John: personJohn,
} = require('./people.js');

В последнем случае personJack и personJohn будут ссылаться на ваши классы.

Слово предупреждения:

Разрушение может быть опасным в том смысле, что оно может привести к неожиданным ошибкам. Относительно легко забыть фигурные скобки в export или случайно включить их в require.


Обновление Node.js 12:

В последнее время ECMAScript Modules получил расширенную поддержку в Node.js 12. *, вводя удобное использование оператора import для выполнения той же задачи (в настоящее время Node должен быть запущен с флагом --experimental-modules, чтобы сделать их доступными).

// people.mjs

export class Jack {
  // ...
}

export class John {
  // ...
}

Обратите внимание, что файлы, соответствующие соглашениям модулей, должны иметь расширение .mjs.

// index.mjs

import {
  Jack as personJack, John as personJohn,
} from './people.mjs';

Это намного лучше с точки зрения надежности и стабильности, поскольку попытка import несуществующего export из модуля вызовет исключение, подобное:

SyntaxError: Запрошенный модуль 'x' не обеспечивает экспорт с именем "У"