Прочёл
материалы, основанные на
презентации Nicholas Zakas (создатель eslint).
Описывается следующая расширеяемая архитектура для js-кода:
Модули - это js+css+html наборы файлов. Песочница - по сути, паттерн посредник (mediator), который позволяет общаться модулям путем публикации-подписки и не зависеть друг от друга. Ядро - контролирует управления модулями. К нему песочницы (sandboxes) обращаются за методами. Base library: jQuery, Django и т.д.
Я разобрался там с взаимодействием sandboxes и modules:
function Sandbox (core) {
return {
notify: function(data) {
core.getListeners(data.type)
.forEach(item => {
item.notifyCb(data);
});
},
listen: function(eventTypes, notifyCb, moduleInstance) {
eventTypes.forEach(type => {
core.addListener({type, notifyCb, moduleInstance});
});
}
}
}
Core = function(){
var moduleData = {};
var listeners = [];
return {
getListeners: function(type){
return listeners
.filter(item => item.type === type);
},
addListener: function(data){
listeners.push(data);
},
register: function(moduleId, creator){
moduleData[moduleId] = {
creator: creator,
instance: null
}
},
start: function(moduleId){
moduleData[moduleId].instance =
moduleData[moduleId].creator(new Sandbox(this));
moduleData[moduleId].instance.init();
},
stop: function(moduleId){
var data = moduleData[moduleId];
if (data.instance){
data.instance.destroy();
data.instance = null;
}
},
startAll: function(){
for (var moduleId in moduleData){
if (moduleData.hasOwnProperty(moduleId)){
this.start(moduleId);
}
}
},
stopAll: function(){
for (var moduleId in moduleData){
if (moduleData.hasOwnProperty(moduleId)){
this.stop(moduleId);
}
}
}
//другие методы не показаны
}
}();
// Чтобы запустить приложение, следует вначале зарегистрировать требуемые модули и запустить их:
Core.register("module.search", function(sandbox){
return {
init: function(){
//initialization
sandbox.notify({
type: "new-status",
data: '123'
});
}
};
});
// модуль рекламы по результатам запроса
Core.register("module.direct", function(sandbox){
let $container;
return {
init: function(){
//initialization
sandbox.listen(["new-error", "new-status"], this.handleNotification, this);
},
handleNotification: function(note){
switch(note.type){
case "new-error":
// ...
break;
case "new-status":
console.log(note.type, note.data);
break;
}
}
};
});
Core.startAll();
А вот про Base library мне не понятно. Автор утверждает, что модули не должны зависеть от базовой либы (совсем?!). И api базовой либы должно прокидываться через ядро и песочницу в модули для работы с DOM. Тогда выходит, что если у меня есть jQuery, я в ядре должен сделать адаптер-паттерн который обернёт ВСЕ методы jQuery?.. Как-то не слишком красиво выходит...
Вопрос в том, как правильно по схеме приведенной выше организовать код? Если кто знает и разобрался в своё время (презентация древняя) - покажите мне пожалуйста код взаимодействия Base library и ядра (как я описал выше про песочницу).
Давайте не будем брать в расчет реакты и ангуляры. Мне интересно понимание архитектуры, как её представлял Николас (его об этом спрашивал но ответа нет пока). Спасибо!