Я не могу создать архитектуру для 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 варианта
Через окно глобального объекта.
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-м модуле - мне нужно пройти через все эти модули. Это похоже на ад. Или нет?
Каков наилучший способ передачи часто используемых переменных в конкретном модуле?