템플릿 리터럴은 ES6의 핵심 스펙 중 하나입니다. 자칫 복잡해질 수 있는 문자열 처리를 몇 가지 구문만으로 간단하게 처리할 수 있습니다. 심지어 줄바꿈을 일반 텍스트로 넣어도 알아서 잘 처리해 줍니다.
const text = `집 가고 싶다.
집에보내줘\n제발`
위 상황은 text 변수에 템플릿 리터럴을 선언한 것입니다. 자바스크립트 파서는 이 템플릿 리터럴을 적절하게 해석하여
집 가고 싶다.
집에보내줘
제발
위와 같은 문자열로 변환합니다. 일반 줄바꿈을 인식하였음은 물론 이스케이프 문자(\n)를 만나 줄바꿈까지 된 모습입니다. 하지만 이스케이프 문자(escape sequence라고도 합니다)를 만나면 파서가 이도 같이 해석하기 때문에 순수한 문자열만을 전달해주어야 할 때 문제가 생기게 됩니다.
위와 같이 리터럴을 별도의 처리 없이 그대로 웹 브라우저에 보여주고 싶은 상황일 때, 템플릿 리터럴을 그냥 사용하면 줄바꿈 이스케이프 문자가 인식되어 아래와 같이 변환됩니다.
먼저 필자는 템플릿 리터럴로 처리되기 전 문자열을 이스케이프 문자로 인식할 수 없도록 변환하는 방법을 생각했습니다.
\n
을\\n
으로 변환하면 문제가 없지 않을까?
그러나 이 방법은 이스케이프 문자의 종류만큼의 replaceAll()을 사용해야 해 코드가 지저분해짐은 물론, 파서가 템플릿 리터럴을 처리한 후에는 이스케이프 문자가 모두 변환되어 있어 replaceAll() 변환 과정을 처리하는 함수의 인자로도 사용할 수 없다는 문제가 있었습니다.
생각을 조금 바꾸어 문자열을 그대로 사용할 수 있는 방법을 고민한 결과, 템플릿 리터럴의 태그 함수로 String.raw()
가 있음을 알았고, 적용해 보았습니다.
const code = String.raw`if (array[i])
builder.append(Integer.toString(i) + "\n");
`
console.log(code)
드디어 원하는 결과물을 얻었습니다.
몇 시간을 싸매고 고민하다 포기할 뻔한 문제가 MDN에서 찾은 자바스크립트 내장 함수로 허무하게 해결되니 시원섭섭한 기분을 지울 수 없었습니다. 번역이 잘 되어 있지 않다는 이유로 MDN을 잘 찾아보지 않는 습관이 있었는데, 이 습관을 고칠 동기가 하나 생겼습니다.