현재 스프링부트 프로젝트에서 프론트엔드 개발을 하고 있다. 프로젝트 특성상 JSP 파일 위에서 자바스크립트를 이용한 화면 구현을 할 수 밖에 없는데 예전부터 매우 불편하게 사용해 왔던 JSP 내에서 템플릿 리터럴을 사용하는 방법에 대해 글을 써보려고 한다.
이 글에서는 템플릿 리터럴에 대한 설명과 JSP의 EL, 구문 중첩 현상, JSP 동작 원리 내용까지 가볍게 포함하고 있습니다.
템플릿 리터럴(Template literals)이란?
템플릿 리터럴은 이중 따옴표나 작은 따옴표 대신 백틱(` `) (grave accent) 을 이용한 내장된 표현식을 허용하는 문자열 리터럴이다.
표현식을 넣을 때는 $와 중괄호( $ {expression} ) 로 표기할 수 있다. 자세히 알아보기
한마디로 문자열 안에서 표현식을 사용할 수 있다는 말이다.
표현식이란 값이 표현되는 모든 코드를 의미한다. (객체, 배열, 산술, 할당, 논리, 삼항연산, 함수 호출 등등...)
그럼 템플릿 리터럴을 한 번 사용해보자.
// 문자열 연결 연산
function introduce1(name) {
return "I'm " + name + ".";
}
// 쉼표 연산
function introduce2(name) {
return "I'm " , name , ".";
}
// 템플릿 리터럴
function introduce3(name) {
return `I'm ${name}.`;
}
console.log(introduce1("youngdev")); // I'm youngdev.
console.log(introduce2("youngdev")); // .
console.log(introduce3("youngdev")); // I'm youngdev.
기본적으로 문자열과 변수를 함께 출력하려고 한다.
1번 방법은 문자열 연결 연산을 사용해서 출력한다.
예시로 든 코드는 잘 작동하지만 사실 다양한 예외가 발생할 수 있으니 복잡한 코드에서는 적절하지 않다.
2번 방법은 쉼표 연산을 이용한다.
console.log("I'm", name); 이렇게 사용하면 로그에서는 원하는 결과를 확인할 수 있지만 위처럼 return 구문에 그냥 콤마를 나열해서 사용해버리면 마지막 값인 점(.)만 출력된다.
3번 방법은 글의 주제인 템플릿 리터럴을 이용한다. 간결한 문법으로 가독성이 높고 사용하기도 쉽다.
실제로 내 프로젝트에서는 DOM에 직접 element들을 추가하는 작업이 많이 이뤄지는데
실제 HTML 문법을 사용하는 것 같이 흉내낼 수 있어서 편하다.
하지만 템플릿 리터럴은 JSP의 구문과 겹친다.
JSP에서는 EL(Expressing Language, 표현 언어)라고 불리는 구문이 있는데 자바스크립트의 템플릿 리터럴과 같이 $와 중괄호를 이용한다. ( ${ ... } ) 이 문법은 HTML 코드 내에서 자바 코드를 대신해 간단하게 데이터를 표현하고 출력할 수 있게 도와주는데 자바스크립트와 만나면 굉장히 코드가 불편해진다.
잠깐 아래 코드를 보자.
options.map(option =>
optionElements += `
<option value="${option.value}">
${option.text}
</option>
`
);
select 박스 내의 option을 동적으로 구성해주는 내가 자주 사용하는 형태의 코드이다.
하지만 위 자바스크립트 코드가 있는 페이지에 접근하면 500 Server Error가 발생하는데 그 이유가 바로 이전에 설명한 구문 겹침 때문에 그렇다. 정확히는 JavaScript와 JSP가 서로 다르게 구문을 처리해서다.
JSP는 서버에서 JavaScript보다 우선적으로 실행되기에 ${option.value}라는 값을 출력하려고 하는데 당연히 알 수 없는 값이기 때문에 페이지 자체가 렌더링되지 않게 된다.
그럼 어떻게 해야할까?
세 가지 방법이 존재한다.
1. EL 구문 비활성화 (isELIgnored)
JSP 페이지에서 EL 구문을 비활성화 할 수 있는 방법이 있다. 페이지 상단에 아래 코드를 삽입하자.
<%@ page isELIgnored="true" %>
하지만 이 방법은 JSP 페이지 전체에 대한 EL을 비활성화 하기 때문에 JSP 문법을 전혀 사용하지 않고 오로지 순수 Html, Css, JavaScript만을 사용하여 페이지를 구성할 계획일 경우에만 사용 가능하다는 점을 알아두어야 한다.
2. EL 구문 안에 템플릿 리터럴 사용하기
options.map(option =>
optionElements += `<option value="${'${option.value}'}">`;
);
예전에 프로젝트에서 구문 오류때문에 에러 페이지가 자꾸 떴고 서치해본 결과 EL 구문으로 한 번 감싸면 해결된다고 해서 이렇게 자주 사용해왔다. ㅠㅠ 이 방법은 작동은 하지만 너무 불친절하다.
에디터에서는 위와 같이 코드를 작성하면 단순 문자열로 인식하게 되어 자동 완성이나 오탈자 체크 등의 기능도 전혀 작동하지 않았다. 메모장으로 코드 짜는 기분이 이런거겠지...? 싶은 날들의 연속이었다. 심지어 커스텀 태그 내부에서 백틱(` `) 사용하게 되면 렌더링 하는 과정에 페이지가 박살이 나는 경우도 있었고, 큰 따옴표와 작은 따옴표의 순서가 맞지 않으면 문자열이 중간에 잘리고... 아주 다양한 문제를 야기했다.
지금은 사실 이 방식으로 능숙하게 잘 사용하지만 문득 동작 원리가 궁금해졌다.
2.1 JSP의 중첩 EL 구문 처리 동작 원리
options.map(option =>
optionElements += `<option value="${'${option.value}'}">`;
);
찾아보니 원리는 간단했다. JSP가 서버에서 '${option.value}'에 대해 처리한다. 이 부분은 보는 것과 같이 문자열이기 때문에 단순한 문자열 '${option.value}'가 된다. 그 다음 클라이언트에서 자바스크립트가 ${option.value}에 대해 처리를 하게 되면 (예시 코드에는 없지만) option 객체의 value 값이 치환되어 삽입되게 된다.
결국은 서버와 클라이언트에서 처리되는 시점 차이로 문제 없이 중첩 구문을 사용할 수가 있는 것이다.
하지만 이렇게 사용할 수 있다고 하더라도 위에서 말한 여러가지 문제가 너무나도 많이 발생한다. 에디터는 불친절하고, JSP에서 구문 오류로 인해 페이지가 렌더링되지 않으면 디버깅하기도 쉽지 않다.
3. 이스케이프 문자 사용하기
이 글을 쓴 목적이다. 오늘 함께 일하는 퍼블리싱 프리랜서 분께서 쉽게 사용하는 방법에 대해서 알려주셨다.
내가 예전에 찾아 봤을 때는 이스케이프를 사용하는 방법에 대해서는 나와 있지 않았다. 그래서 이게 유일한 방법인 줄 알고 사용해왔는데 솔직히 억울한 감이 없지 않아 있었다... :) 애초에 JSP 환경에서 프론트엔드 개발을 하는 것 자체가 쉬운 길은 아니니까... 더 좋은 방법을 계속 고민했어야 하는데 많이 아쉽다.
options.map(option =>
optionElements += `<option value="\${option.value}">`;
);
1번 방법인 EL 구문을 비활성화하지 않고 이스케이프 문자 \를 $ 앞에 추가하면 JSP가 구문으로 인식하지 않아 자바스크립트 단에서 바로 처리된다. 이스케이프 문자는 HTML이나 자바스크립트에서도 많이 사용 했었는데 JSP에서도 사용 가능하다는 점을 미리 알았으면 더 좋았을 것 같다.
지금이라도 알게돼서 차라리 얼마나 다행인가 싶다. JSP의 수많은 불편함 중 한 가지는 해결했다... ㅠㅠ
'Frontend' 카테고리의 다른 글
Styled Component: attr 속성 추가하기, hover, 커스텀 css 추가 등 (0) | 2024.11.27 |
---|---|
MIME Type과 Content Type 그리고 application/octet-stream (2) | 2024.11.15 |