const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`
혹시 이러한 코드를 본 적이 있는가? 뭐 물론 styled-component를 사용해 본 사람이라면, 이런 코드를 본 적이 많을 것이다.
하지만, 처음본 사람의 입장에서는 저런 문법이 자바스크립트에 있었나? 이 생각만 있을 것 같다. 뭐 물론, 나도 처음 저런 코드를 보았을 때, 왜 오류가 안나지? 이 생각 뿐이었으니까, 말이다.
일단 대부분이 Template literal(String template)은 많이 들어보았을 것이다. 일단 간단하게 소개 해주자면,
const a = 1
const b = 2
const text = 'a: ' + a +' \n' +
'b: ' + b +' \n' +
'합: ' + ( a + b)
const template = `a: ${a}
b: ${b}
합: ${a + b}`
console.log(text)
console.log(template)
위처럼 문자열을 여러줄로 표현하거나, 중간에 삽입해야 하는 값을 편하게 만들어주는 기능을 갖는다.
보면 알겠지만, ', "대신 `을 이용 하고 있다. Template literal에서 편의성을 더 제공한 것이, tagged literal이다.
간단한 사용 예제를 보여주자면,
const name = 'sejiwork'
const email = 'sejinjja@gmail.com'
console.log(`이름: ${name}
email: ${email}`)
위의 정보에서 이메일 정보는 노출하고 싶지 않을 때가 있지 않나? 그러면 이러한 함수를 만들 수도 있을 것이다.
const name = 'sejiwork'
const email = 'sejinjja@gmail.com'
function introduce(name, email) {
const [_, domain] = email.split('@')
return `이름: ${name}
email: *****@${domain}`
}
console.log(introduce(name, email))
하지만, 이는 간단한 문제가 있다, 이름이 아니라 닉네임이라는 필드로 바꾸어야 한다면? 또 다른 함수를 정의하거나, 함수를 수정해야 하는 문제가 있다.
Tagged template이럴때 사용 할 수 있는 방법이 tagged template다. 일단 간단하게 구조를 설명 하기 위해서 console.log를 이용하여 출력해보자.
위의 내용을 보면, 첫번째 인자로 ['이름', '\nemail', '']가 들어오고,
이후로 ${name}의 값, ${email}의 값이 출력 되는 것을 볼 수 있다. 일단 구조는 알았으니, 변경해보자.
const name = 'sejiwork'
const email = 'sejinjja@gmail.com'
function taggedIntroduce(strings, name, email) {
const [_, domain] = email.split('@')
email = `*****@${domain}`
return String.raw(strings, name, email)
}
console.log(taggedIntroduce`닉네임: ${name}
email: ${email}`)
console.log(taggedIntroduce`이름: ${name}
email: ${email}`)
위와 같이 함수를 구성하면, 닉네임으로 필드가 바뀌던, 이름으로 바뀌던, 호출하는 부분에서 변경한 대로 사용 할 수 있다.
String.raw
String.raw함수는 처음 본 사람이 많을 것이다.
간단하게 사용법을 소개하자면,
const text1 = `이름: ${name}`
const text2 = String.raw`이름: ${name}`
위의 결과는 똑같다. 뭐 간단하게 문자열을 ""이렇게 만들수 있고, String("")이렇게도 만들 수 있는 것의 차이쯤으로 생각하면 된다.
String.raw()는 좀 다르다. 아까 console.log로 tagged template 인자를 보았을 것이다. 결국 사용하려면, 조립을 해야하는데, String.raw() 없이 조립한다고 생각해보자.
function mergeTaggedTemplate(strings, ...values) {
const res = []
for(let i = 0; i < strings.length; i++) {
res.push(strings[i])
res.push(values[i])
}
return res.join('')
}
mergeTaggedTemplate(['닉네임: ', '\nemail: ', ''], 'sejiwork', 'sejinjja@gmail.com')
조립을 하기위해서는 위와 같은 함수를 매번 정의하거나, 함수에 추가해야하는 불상사가 생긴다. 위와 같은 함수의 역할을 해준다고 보면 된다.
Styled tagged
이정도 가지 되었으면 처음에 소개한. styled.h1 함수도 만들어 볼 수 있을 것이다. 뭐 물론 styled components처럼 html에 삽입 된 상태에서 태그에 달려있는 속성을 읽어 와서 처리하는 것까지 하려면, 커스텀 엘리먼트로 정의하는 코드까지 작성해야 하지만, 일단 그건 제외하자.
const styled = {}
styled.h1 = (style, ...values) => {
const elm = document.createElement('h1')
elm.style = String.raw(style, ...values)
return elm
}
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`
간단하게 정의 하면, 위처럼 만들 수 있을 것이다. 그래도 이정도 까지만 해도, 변수에 따라서 변경하여, 적용 해야 하는 것들은 처리가 가능할 것으로 본다 아래처럼 말이다.
const highlight = {
'fontSize': '2.5em',
'color': 'red'
}
const HighlightTitle = styled.h1`
font-size: ${highlight.fontSize};
text-align: center;
color: ${highlight.color};
`
뭐 물론 함수로 전부 가능하데, 이런 애매한 문법을 사용 하는 것이 불편하다고 느낄 수 있다. 나의 경우에도 처음에는 눈에 익숙지 않아 별로였지만...
댓글
댓글 쓰기