Как импортировать модуль в es6, который сам должен вызывать/инициализировать свою функцию/класс перед импортом

Мне было интересно, как лучше всего импортировать функцию/класс модуля в другой модуль, который сам модуль должен вызывать/инициализировать свою собственную функцию/класс перед импортом в другой модуль? Я не знаю, смогу ли я задать свой вопрос достаточно ясно! Итак, давайте поместим это в пример.

Это мой модуль:

// myModule.js
class MyModule {
  constructor() {
    // do sth
  }
}

let myModule = new MyModule();

И вот как мне нравится импортировать его в другой модуль:

import MyModule from './myModule';

Это на самом деле отлично работает! Но, как вы можете видеть, в файле myModule.js я не export default свой класс MyModule, потому что это не единственное, что происходит в файле myModule.js! Я также инициализирую класс после его определения... (я знаю, что даже если я установил свой класс как export default, инициализация все равно будет работать нормально, пока модуль импортируется в другое место...)

Таким образом, не устанавливая что-либо как экспортируемое внутри нашего модуля или не устанавливая класс как export default, все работает нормально, когда модуль был импортирован куда-то еще... Пока все хорошо! Но я ищу лучшую практику, если она есть!

Итак, вот мои вопросы относительно таких случаев:

  1. Можно ли импортировать модуль, в котором нет ничего для экспорта?
  2. Должны ли мы установить класс как export default, хотя мы делаем еще некоторые работы вне класса в модуле (задание инициализации, которое происходит после определения класса)?
  3. Или, может быть, хорошо выполнить задание инициализации в другой функции, а затем экспортировать и класс, и функцию, а затем вызвать функцию для выполнения задания инициализации в импортированном модуле?

Большое спасибо всем! Я очень ценю любую помощь по этому поводу :)


person Ali    schedule 16.08.2016    source источник
comment
потому что это не единственное, что происходит, не должно мешать вам (по умолчанию) экспортировать что-либо.   -  person Bergi    schedule 17.08.2016
comment
Вам нужно несколько экземпляров класса?   -  person Bergi    schedule 17.08.2016
comment
Мне интересно, что, если у меня есть фабричная функция (внутри нее я не только создаю экземпляр класса, но и выполняю некоторые другие работы), мне нравится, чтобы она вызывалась самостоятельно. Как я могу экспортировать эту функцию с автоматическим вызовом?   -  person Ali    schedule 17.08.2016
comment
Вообще мне интересно, как мы можем экспортировать функцию с автоматическим вызовом?   -  person Ali    schedule 17.08.2016
comment
Отбросьте самовызов, модули ES6 в любом случае автономны. Просто выполните свои действия в области уровня модуля, экспортируйте результаты.   -  person Bergi    schedule 17.08.2016


Ответы (2)


Как насчет того, чтобы предложить импортировать класс или его экземпляр? Нравиться:

// export class itself
export class MyModule {
  constructor() {
    // do sth
  }
}

// export instance of MyModule directly
export default new MyModule();

// export a factory function if you need more work to be done
// before the instance is created
export function myModuleFactory(...args) { // define e.g. arguments to be passed to constructor
  // ... do stuff
  const myModule = new MyModule(...args);
  // ... do more stuff
  return myModule;
}

Итак, вы можете сделать:

// import instance
import instance from './myModule';
// or class
import { MyModule } from './myModule';
// or import factory
import { myModuleFactory } from './myModule';

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

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

Обновить

Чтобы ответить на ваш первый вопрос: вы можете import модули, которые не имеют export определенных. Модуль будет загружен, и его логика будет выполнена. Дело в том, что пока он не изменит глобальные переменные (например, window в веб-разработке), он не будет иметь никакого эффекта, поскольку все внутри модуля происходит в изолированной области. Как вы могли догадаться, изменение глобальных переменных модулями далеко не лучшая практика.

person Oliver    schedule 16.08.2016
comment
Ваше решение может работать, когда нам нужно импортировать экземпляр класса... Но что, если нам нужно вызвать фабричную функцию, а затем экспортировать ее? Есть ли какой-нибудь предложенный способ, о котором я не знаю? - person Ali; 17.08.2016
comment
Вы имеете в виду вызов фабричной функции в модуле, из которого мы импортируем и экспортируем созданный экземпляр? Тогда вам не понадобилась бы фабрика, так как вы могли бы написать все, что нужно сделать, прямо в самом модуле, и вам не нужно было бы инкапсулировать это в другую функцию (например, //export instance of MyModule directly с некоторыми вещами, сделанными ранее). Однако вы не сможете передать какие-либо аргументы. - person Oliver; 17.08.2016
comment
Нет, конечно, мы можем легко и без проблем экспортировать экземпляр класса... Не беспокойтесь об этом! Давайте забудем об установке... Вот мой вопрос: как я могу экспортировать функцию с автоматическим вызовом? - person Ali; 17.08.2016
comment
export default function() { ... }(); Но какой в ​​этом смысл? Он будет выполняться во время импорта модуля, как и весь остальной код в модуле. Так что не имеет значения, находится ваш код внутри функции или снаружи. Если вам действительно нужна изолированная область, возможно, это намек на то, что вы должны выделить код в отдельный модуль. - person Oliver; 17.08.2016

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

Но в любом случае, я пишу свои ответы на свои вопросы, может быть, кому-то они пригодятся:

  1. Всегда полезно иметь export default или export для модуля, который мы собираемся написать. Потому что каждый фрагмент кода имеет тенденцию иметь какие-то результаты, верно? Таким образом, в модуле мы должны рассмотреть, чего мы собираемся достичь в конце, а затем экспортировать это. Экспортируйте свои выходные данные, то, что вы ожидаете от своего модуля, когда он будет импортирован куда-то еще.

  2. Если ваш модуль представляет собой один класс, хорошо export default его. В противном случае, как я сказал в первом ответе, все зависит от того, чего вы собираетесь достичь в своем модуле и каковы ваши результаты. Экспортируйте все результаты, служебные функции и т. д.

  3. Вы можете сделать это тоже! Но сначала подумайте о своем сценарии использования. Как только модуль будет импортирован куда-то еще, все коды внутри него будут выполнены. Так что делайте все, что вам нравится, а затем экспортируйте конечные результаты.

person Ali    schedule 18.08.2016