JavaScript 코드 안 HTML 문자열

내 이 세상 도처에서 쉴 곳을 찾아보았으나, 마침내 찾아낸, 컴퓨터가 있는 구석방보다 나은 곳은 없더라.

JavaScript 코드 안 HTML 문자열

JavaScript 코드에 HTML 문자열을 써야 하는 경우가 종종 있다. 문자열이 짧을 때는 그냥 한 줄로 써도 크게 상관 없다. 복잡한 계층 구조를 가지는 긴 HTML 문자열을 써야 할 경우에는 한 줄로 작성하지 않는다. 작성하기도 어렵고 알아보기도 어렵기 때문이다. 보통 다음과 같이 여러 줄로 문자열을 만들고 +로 연결해 변수에 저장한다.

var html = '<div class="xxx">' +
              '<div class="yyy">' +
                 '<span class="zzz"></span>' +
              '</div>' +
           '</div>';

들여쓰기도 되어 있어 알아보기가 쉬워졌지만, 나는 이 스타일을 좋아하지 않는다. Emacs에서 자동으로 위와 같이 들여쓰기가 되지 않고 각 행 뒤에 +가 붙어 있는 게 너저분해 보이기 때문이다.

함께 일하는 신입사원이 몇 가지 대안을 제시했다.

1. \를 이용한 다중 행 문자열 표현

var html = '<div class="xxx"> \
              <div class="yyy"> \
                <span class="zzz"></span> \
              </div> \
            </div>';

매 행마다 '로 감싸지 않아도 되어 나름 간결해지기는 하지만, 이렇게 해도 Emacs에서 자동 들여쓰기가 되지 않는다. 또한 jshint에서 경고 메시지를 표시한다. \ 뒤에 실수로 공백을 추가하면 문제가 생길 수 있기 때문에 JavaScript에서 \를 써서 다중행 문자열을 표시하는 것은 좋지 않다고 한다. 파일 저장 시 불필요한 공백 문자를 모두 제거해 저장하도록 하고 있어 특별히 문제될 것은 없겠지만, 나 혼자 작업하는 것도 아니므로 경고를 무시하거나 옵션을 조정하면서까지 사용하고 싶지는 않다.

2. 각 행 앞에 공백 추가

var html = '<div class="xxx">' +
           '  <div class="yyy">' +
           '    <span class="zzz"></span>' +
           '  </div>' +
           '</div>';

이렇게 하면 Emacs에서 들여쓰기 문제는 해결된다. 그러나 각 행 뒤에 너저분하게 +가 붙어 있는 문제는 여전하다. 또 다른 문제 하나는 보기 좋게 하려고 문자열에 공백을 추가했는데 실제 DOM에서도 텍스트 노드가 추가된다는 것이다.

3. 각 행을 배열에 담기

var html = [
  '<div class="xxx">',
  '  <span>Hello</span>',
  '</div>'
].join('\n');

마지막 방법은 각 행을 배열에 저장하고 join()을 이용해 연결하는 것이다. 나는 이 방법이 가장 마음에 들었다. 앞서 언급했던 불필요한 텍스트 노드가 추가되는 문제는 다음과 같이 해결할 수 있다.

var html = [
  ...
].map(function (s) { return s.trim(); }).join('');

이 방법이 +로 문자열을 연결하는 방법과 다른 점이 뭘까? trim()을 적용해 쉽게 불필요한 공백을 제거할 수 있는 것은 분명 장점이지만, 내가 이 방법을 선호하는 강력한 이유로 내세우기에는 조금 부족한 듯 하다. 왜 각 행 뒤에 +가 붙는 것은 싫어하면서 ,가 붙는 것은 괜찮은가? 글쎄, 그냥 취향이라고 할 수밖에 없을 듯 하다.

사족

  • 최적화 관점에서 본다면 불필요한 작업(trim 처리)이 추가되므로 비효율적이라 할 수 있다. 문자열이 충분히 크지 않다면 대세에 영향을 미치지 않으리라 기대한다.
  • JavaScript와 HTML을 별도 파일로 분리하고 Ajax로 HTML을 로딩해 사용하는 방법도 고려할 수 있다. 웹 페이지를 만드는 경우라면 충분히 가능한 대안이지만, 웹 에디터와 같이 라이브러리로 제공할 모듈이라면 이런 방식은 좋아 보이지 않는다.