@fattan
программист

Как архитектурно организовать js-проект?

Прочёл материалы, основанные на презентации Nicholas Zakas (создатель eslint).

Описывается следующая расширеяемая архитектура для js-кода:
nV3s1SH8.png

Модули - это 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 и ядра (как я описал выше про песочницу).

Давайте не будем брать в расчет реакты и ангуляры. Мне интересно понимание архитектуры, как её представлял Николас (его об этом спрашивал но ответа нет пока). Спасибо!
  • Вопрос задан
  • 272 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы