gulpwebpack 등을 이용해 여러 파일로 만들어진 자바스크립트를 하나로 모으는 대신, 처음부터 자바스크립트를 1개만 만들고, 여러 페이지에서 그 자바스크립트 1개만 호출하는 방식으로 관리한다면 어떨까.

돔 기반 라우팅(DOM-based Routing) 이 적절할 수 있다. 2009년에 작성된 글이지만 이제 여러 곳에서 유사한 방식이 쓰이고 있다.

링크는 영어이니, 내 식대로 간단하게 써보면 아래와 같다.


일단 body 태그에 콘트롤러와 액션이 정의됐다고 하자.

<body data-controller="forum" data-action="list">

그리고 액션이 실행되는 순서가 이렇다고 해보자.

- 공통 모듈의 init()
- 해당 콘트롤러의 init()
- 해당 콘트롤러의 action()
- 공통 모듈의 finalize()

그럼, 그에 맞게 이런 오브젝트를 작성할 수 있다.

MyNS = {
  common: {
    init: function(){
      console.log('in common/init');
    },
    finalize: function(){
      console.log('in common/finalize');
    }
  },
  forum: {
    init: function(){
      console.log('in forum/init');
    },
    list: function(){
      console.log('in forum/list');
    }
  }
}

이제 body에 선언한 콘트롤러와 액션을 오브젝트로 구현을 했는데, 이걸 자동으로 실행하는 코드가 필요하다.

UTIL = {
  fire: function(func,func_name, args){
    var namespace = MyNS;  // indicate your obj literal namespace here

    func_name = (func_name === undefined) ? 'init' : func_name;
    if (func !== '' && namespace[func] && typeof namespace[func][func_name] == 'function'){
      namespace[func][func_name](args);
    }
  }, 

  loadEvents: function(){
    // hit up common first.
    UTIL.fire('common');

    // run controller's action
    let controller = document.body.dataset.controller;
    let action = document.body.dataset.action;

    UTIL.fire(controller); // controller's init()
    UTIL.fire(controller, action); // controller's action()

    // hit up common's finalize.
    UTIL.fire('common','finalize');
  }
};

// kick it all off here 
$(document).ready(UTIL.loadEvents);

페이지를 실행하면 다음과 같이 찍힐 것이다.

in common/init
in forum/init
in forum/list
in common/finalize

페이지 수에 따라 코드가 엄청나게 길어질 수도 있지만, 해당 콘트롤러와 액션에 찾아가는 방법도 비교적 쉽고, 명확하기 때문에, 크지 않은 프로젝트라면 처음부터 이런 구조로 작성하면 괜찮을 수도 있을 듯.