Как передать часто используемые («глобальные») переменные в модули ES-6? - PullRequest
0 голосов
/ 17 октября 2019

Я не могу создать архитектуру для js-кода для сайта.

Существует 2 версии сайта: мобильная и настольная. Я хочу создать отдельный js-bundle для каждой версии: mobile.js и desktop.js . Каждый пакет может включать в себя общие js-модули, например form.js (форма существует в каждой версии сайта). Но есть некоторые уникальные элементы: на рабочем столе есть заголовок и ему нужен header.js , на мобильном телефоне нет заголовка, но есть Topbar и ему нужен topbar.js . Пакет для мобильного (mobile.js) включает в себя form.js + header.js Пакет для мобильного (desktop.js) включает form.js + topbar.js

Представьте, что нам нужно показать форму при нажатии на заголовок (или верхняя панель).

Our folder structure:
--common/
----form.js
--desktop/
----header.js
--mobile/
----topbar.js
--entryDesktop.js
--entryMobile.js

.

//--- entryDesktop.js
import Form from './common/form.js';
import Header from './desktop/header.js';

new Form(document.querySelector('.form'));
new Header(document.querySelector('.header'));

.

//--- entryMobile.js
import Form from './common/form.js';
import Header from './mobile/topbar.js';

new Form(document.querySelector('.form'));
new Header(document.querySelector('.header'));

.

//--- form.js
export default class Form{
  constructor(elem) {
    this.elem = elem;
  }

  show() {
    this.elem.classList.remove('form_hidden');
  }
}

На самом деле, модули header.js иtopbar.js очень разные, имеют разные свойства и методы, НО у них есть одно общее действие - они могут открывать форму при нажатии на заголовок (или верхнюю панель)

export default class Header{
  constructor(elem) {
    this.elem = elem;
    ...
    this.elem.addEventListener('click', () => {
      form.show(); 
    })
  }
}

.

export default class Topbar{
  constructor(elem) {
    this.elem = elem;
    ...
    this.elem.addEventListener('click', () => {
      form.show(); 
    })
  }
}

Главный вопрос - как передать «форму» в Header-модуле (и Topbar-модуле)?

Я могу представить 2 варианта

  1. Через окно глобального объекта.

    window.form = new Form(document.querySelector('.form'));```
    
    ```//---topbar.js:
    this.elem.addEventListener('click', () => {
      window.form.show(); 
    })```
    

НО тогда наши переменные не изолированы, мы или сторонние скрипты можем время от времени изменять их.

Передайте "форму" как параметр в классе

const form = new Form(document.querySelector('.form'))
new Header(document.querySelector('.topbar'), form);```

```//---header.js:
export default class Header{
  constructor(elem, form) {
    this.elem = elem;
    this.form = form;
    this.elem.addEventListener('click', () => {
      this.form.show(); 
    })
  }
}```

НО, если мне нужна форма в 20 модулях - я должен передать ее в каждом. Если 1-й модуль импортирует 2-й модуль, который импортирует 3-й модуль, и мне нужна форма в 3-м модуле - мне нужно пройти через все эти модули. Это похоже на ад. Или нет?

Каков наилучший способ передачи часто используемых переменных в конкретном модуле?

...