ejs 사용기

beans·2023년 3월 9일
0

회사의 사내 시스템 관리 목적으로 ejs와 nodejs Express로 개발된 프로젝트가 있었다. 몇 가지 기능이 추가될 예정이라 잠시 이 프로젝트를 담당하게 되었다.

Ejs란

일반적으로 html 파일 내에서 javascript를 사용하려면 <script> 태그 내에 작성해야 한다. 하지만 ejs를 사용하게 되면 html 코드 내 <% %> 태그를 사용해서 javascript 코드를 자유로운 위치에서 하나의 요소처럼 사용 가능하다.

Ejs의 장점

위에서 이야기 했던 것처럼 <% %> 태그를 사용해서 javascript 코드를 자유로운 위치에서 하나의 요소처럼 사용 가능하다.
또 하나의 장점이 있다. express 서버에 request를 보내고 express routing을 통해 다른 html로 이동할 때 res.render(html, data) 함수의 2번째 인자에 {itemA: "아이템1", itemB: "아이템2"} 처럼 데이터를 객체로 넣어주면 이동된 html에서 바로 itemA와 itemB를 변수처럼 접근이 가능하다.

코드 분석

사실 코드를 보자마자 불길한 예감이 들었다. ejs가 사용된 프로젝트가 규모가 커졌을 때 가독성이나 유지보수가 어려울 것 같은 느낌이 강하게 들었다. 코드가 적은 상태라 다행이었다. html 파일에 태그를 이용하여 직접적으로 코드를 작성하는 방식이기 때문에 위에서 부터 차례대로 읽으면 며칠 걸리지 않고 분석해낼 수 있었다.
분석할 때는 사용된 패키지들의 버전에 맞는 공식 문서 또는 타 블로그에 포스팅 되어 있는 사용법과 프로젝트 폴더에서 볼 수 있는 js 파일들과 html 파일들을 기능 단위로 코드를 쪼개서 주석을 달아 나중에도 도움이 될 수 있도록 notion에 정리했다.

기능 추가

간단한 기능 부터 하나 추가하기로 했다. 짧게 말하자면 외부 API에 사용될 데이터가 html의 몇 개의 <input> 태그에 값이 입력되면 onchange 이벤트를 활용해서 변수나 객체에 저장하고, 특정 버튼을 눌렀을 때 미리 저장해놨던 데이터를 파라미터나 쿼리로 서버에 넘겨준다. 이후 서버에서 외부 API에 접근하여 받아온 데이터를 정제하여 새 html을 클라이언트에 렌더링 시킴과 동시에 데이터를 넘겨줘서 보여주는 기능이었다.

사용하면서 느낀 ejs의 단점

ejs로 미리 정의한 함수나 변수를 자유로운 위치에서 <% functionName() %> 또는 <%= variableName %>로 데이터를 보여줄 수 있다거나 <a href="https://site_url?itemA=<%= variableName %>"> 버튼 </a>의 결과로 <a href="https://site_url?itemA=아이템1"> 버튼 </a>의 효과를 낼 수 있는 것은 큰 장점이다.
하지만 작게는 자동 완성 기능을 사용할 수 없고, 함수나 변수를 선언할 때 엔터를 사용하면 문법 오류가 발생했다.
큰 문제로는 <script> 태그에서 선언한 함수나 변수는 ejs를 통해 사용할 수 없었다. 정의되지 않았다는 오류 메세지가 표출되었기 때문이다. 때문이다. <script> 태그와 <% %> 태그를 함께 사용하는 것은 작성은 하나의 html 파일에 했지만 실제 동작은 마지 전혀 다른 파일에서 각자 실행되는 것처럼 보였다. 아래와 같은 것들이 불가능했다.

onchange 이벤트에 ejs를 통한 함수 연결 불가

<% function OnChangeEvent() { console.log(`테스트`); } %>
<input onchange="<% OnChangeEvent %>" />

=> onchange 이벤트에 Object 타입이 들어오지 않았다는 문법 오류 (다른 어떤 방법을 써도 제대로 동작하지 않는다. 함수의 이름이 와야 하는데 함수의 내용이 와버린다.)

ejs에서 선언한 변수에 값을 할당 불가

최종적으로 <a> 태그의 href prop으로 url과 합쳐질 변수같은 데이터는 ejs의 <%= %> 태그를 사용해야 편하다. 하지만 <script> 태그 내에서 선언한 함수나 변수에는 ejs로 선언한 함수나 변수를 "<%= %>"를 통해 할당할 수 있지만, 반대로 다음과 같이 ejs에서 선언한 변수에 <script> 태그에서 선언하고 미리 데이터를 설정한 변수를 할당하는 것은 불가능했다.

<script>
  let newString = '문자열 테스트';
  let newStringA = '문자열1';
  let newStringB = '문자열2';
</script>

<% let data = {itemA: null, itemB: null} %>
  
<script>
  "<% data %>" = newString;
  "<% data %>".itemA = newStringA;
  "<% data %>".itemB = newStringB;
</script>

=> <% data %>는 빈 문자열이 오고 <%= data %>는 data의 내용이 문자열로 와버린다. 따라서 "문자열" = "문자열"은 오류다. 참고로 <script> 태그 내에서 ejs 태그를 사용하려면 따옴표나 쌍따옴표로 감싸야만 ejs 태그로 인식되기 때문에 필수적으로 ""를 써줘야 한다.

실제 html이 랜더링 될 때 for문을 사용할 경우 html이 상당히 길어지고 로딩이 느림

ejs의 장점으로 javascript의 for문을 <table> 태그 내 <td> 등의 태그 내에서 데이터 길이 만큼 반복적으로 내용을 생성하는 것이 가능하다. 하지만 말 그대로 하나의 템플릿 처럼 작성된 태그를 데이터 길이만큼 반복하는 것으로, 실제 html 코드가 엄청나게 길어진다. 하나의 페이지에 엄청나게 길은 목록을 나타내지 않으려면 추가적으로 템플릿을 찾거나 예외 처리하는 데에 시간을 그만큼 쏟아야 할 것이다.

결론

조금 우회하는 방법으로, <script> 태그에서 작성한 함수를 onchange나 onclick 이벤트에 연결시켜주고, 함수 내에서 location.hrefwindow.open()을 사용해서 해결했다.

며칠 동안만 ejs를 써본 것이지만, 짧은 기간에 엄청난 삽질을 한 결과 최종적으로 드는 생각은 ejs에서 <% %>, <%= %> 태그를 하나의 html 요소로써 사용하는 것은 값을 텍스트 자체로 보여주는 것으로만 사용이 가능하고 장점이라고 할 수 있는 것은 express로부터 res.render() 함수의 2번째 인자를 통해 클라이언트에게 데이터를 쉽게 전달해주고 사용할 수 있다는 장점 외에는 오히려 자유도가 제한되는 느낌이 들어 기업에도, 개인에도 도움이 되는 프레임워크인지는 잘 모르겠다.

ejs 같은 html 템플릿을 사용하는 것보다 React 같은 프레임워크를 사용하는 것이 데이터를 가져오고 정제하는 시간이 더 단축되고 장기간으로 봤을 때 더 도움이 될것 같다는 생각이 들었고, 실제 서비스에 이용하기는 어려울 것으로 생각이들었다. 한번 쉽게 사용한 여러 프레임워크(ejs 등)는 개인이라면 갈아 엎는게 가능하겠지만 보통의 기업들은 비용 절약을 위해 계속 사용하게 될 것이고 프로젝트가 커진다면 결국 그동안 쉽게 해왔던 만큼 큰 비용을 들이게 될 것이기 때문이다.

0개의 댓글