Lit 튜토리얼 (1/6)

2021-07-25
안녕하세요. 작년에 lit-html을 소개하는

https://velog.io/@jerrynim_/Lit-html-1-%EC%86%8C%EA%B0%9C

li-html 어떠세요??
을 올리고, 웹 컴포넌트 개발에 대한 관심만 가지고 있다가 그디어 lit-html을 사용하여 웹 컴포넌트 개발을 해보게 되었습니다.

웹 컴포넌트 왜 사용할까?

웹 컴포넌트는 웹 표준 기반을 준수하여 Html, Css, Javascript 로 만들어진 재사용 가능한 캡슐화 된 컴포넌트 입니다. 다음 링크는 웹 컴포넌트를 사용하는 이유를 알려주고 있습니다.

https://han41858.tistory.com/15

왜 Web Component가 중요한가
lit-project를 시작하기에 앞서 웹 컴포넌트의 특성 대해 알아 보도록 하겠습니다.

웹 컴포넌트 특성

https://developer.mozilla.org/ko/docs/Web/Web_Components

웹 컴포넌트 란
웹 컴포넌트란 재사용 할 수 있는 캡슐화된 컴포넌트를 만들며 다음 세 가지 주요 기술들로 구성되어 있습니다.

lit 프로젝트 설정하기

리액트를 시작하기 위해서는 처음 하는 것은 CRA(Create React App)을 설치 하기 일 것입니다. lit 프로젝트를 시작하기 위해 저희는 thepassle 가 만든

https://github.com/thepassle/create-lit-app-advanced

CLA(Create Lit App)
을 사용 할 수 있습니다. 하지만 저는 타입스크립트를 사용하길 원했고 다음

https://vaadin.com/learn/tutorials/lit-element/starting-a-lit-element-project

vaadin 강의
및 webpack 블로그 글을 참고하여 웹 컴포넌트 실행을 위한 webpack 및 프로젝트 설정을 직접 하였습니다. 간단한 웹 컴포넌트 실행이 되는 프로젝트를 깃허브에 올려 두었습니다.

https://github.com/jerrynim/jerrynim-lit-project

깃허브 : jerrynim-lit-project-starter
저는 Next.js를 사용하는 것을 좋아하기 때문에 폴더구조는 Next.js의 구조를 사용하였습니다.

프로젝트 실행해보기

jerrynim-lit-project-starter 프로젝트를 다운로드 받아 필요한 패키지를 설치후 실행해 보도록 하겠습니다. 설정해둔 포트는 3000으로, http://localhost:3000/ 로 접속하여확인 할 수 있습니다.
yarn yarn dev
hello tomato![hello tomato!]
'Hello Tomato!'라는 메세지가 출력 되었습니다. 개발자도구의 Elements를 확인하여보면$<lit-tomato>라는 생소한 태그가 보입니다. <lit-tomato>라는 태그를 찾아보도록 하겠습니다. 해당 태그를 'index.html'에서 찾아 볼 수 있습니다.

index.html

<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Lit project</title> <meta name="description" content="Lit project Start" /> <script> if (!window.customElements) { document.write("<!--"); } </script> <script src="/vendor/custom-elements-es5-adapter.js"></script> <!-- ! DO NOT REMOVE THIS COMMENT, WE NEED ITS CLOSING MARKER --> </head> <body> <main> <lit-tomato></lit-tomato> </main> <script src="/vendor/webcomponents-loader.js"></script> </body> </html>
<lit-tomato>를 찾아보니 해당 태그는 가지고 있는 값이 없습니다. 그렇다면 'Hello Tomato'는 어디로부터 출력 되는 걸까요?, 'Hello Tomato'를 찾아보니 'pages/lit-tomatoo.ts'에서 찾을수 있었습니다.

pages/lit-tomato

import { LitElement, html, customElement } from "lit-element"; @customElement("lit-tomato") class Tomato extends LitElement { render() { return html` <style></style> <h1>Hello Tomato!</h1> ` } } declare global { interface HTMLElementTagNameMap { "lit-tomato": Tomato; } }
생소한 코드이지만 'Hello Tomato' 텍스트를 찾을 수 있었습니다. Html을 리턴하는 익숙한 코드를 찾을 수 있습니다.
render() { return html` <style></style> <h1>Hello Tomato!</h1> `; }
lit-html을 사용하여 템플릿을 리턴 한다는 것을 짐작해 볼수 있었습니다. 코드를 하나씩 살펴보며 알아가보도록 하겠습니다. 코드의 첫줄 입니다.
import { LitElement, html, customElement } from "lit-element";
'lit-elemnt' 라이브러리를 사용하는 것을 볼 수 있습니다.

https://lit-element.polymer-project.org/guide

lit-element
는 홈페이지에 'A simple base class for creating fast, lightweight web components'라고 설명 되어 있습니다. 번역하면 '빠르고 가벼운 웹 컴포넌트를 위한 간단한 클래스'를 의미합니다. 그렇습니다.lit-element는 웹 컴포넌트를 만들기 위해 사용 됩니다. lit-element의 특징은 다음과 같습니다.

https://developers.google.com/web/fundamentals/web-components/shadowdom?hl=ko#:~:text=Shadow%20DOM%EC%9D%80%20%EA%B5%AC%EC%84%B1%20%EC%9A%94%EC%86%8C%EC%97%90%20%EB%A1%9C%EC%BB%AC%EC%9D%B4%EB%A9%B0%20%EB%82%B4%EB%B6%80%20%EA%B5%AC%EC%A1%B0,%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%84%20%EC%A0%95%EC%9D%98%ED%95%A9%EB%8B%88%EB%8B%A4.

Shoadow DOM(쉐도우 돔)
이라는 단어가 생소할 것입니다. 앞으로의 개발에 필요한 쉐도우 돔의 특징에 대해 알아보도록 하겠습니다. 참고 :

https://developers.google.com/web/fundamentals/web-components/shadowdom?hl=ko#:~:text=Shadow%20DOM%EC%9D%80%20%EA%B5%AC%EC%84%B1%20%EC%9A%94%EC%86%8C%EC%97%90%20%EB%A1%9C%EC%BB%AC%EC%9D%B4%EB%A9%B0%20%EB%82%B4%EB%B6%80%20%EA%B5%AC%EC%A1%B0,%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%84%20%EC%A0%95%EC%9D%98%ED%95%A9%EB%8B%88%EB%8B%A4.

구글 Shadow Dom 문서
쉐도우 돔은 1)외부 css의 영향을 받지 않고, 2)querySelector로 불러올 수 없고, 3)composed를 이용하여 이벤트 전달을 막을수도 있습니다. 3)의 의미를

https://dev.to/open-wc/composed-true-considered-harmful-5g59

composed?
글을 읽는다면 쉐도우 돔의 이벤트에 대해 이해하는 것에 도움이 될 것입니다. 다음 코드를 보도록 하겠습니다.

decorators

다음 코드를 보니 다음과 같은 코드가 있습니다.
@customElement("lit-tomato")
@로 시작하는 코드 이것은 데코레이터라 부르며, 데코레이터는 클래스, 클래스 메소드 및 클래스 필드 선언의 동작을 변경할 수있는 특수 표현식입니다. LitElement는 컴포넌트를 정의 할 때 작성해야하는 상용구 코드의 양을 줄이는 데코레이터 세트를 제공합니다.

https://lit-element.polymer-project.org/guide/decorators

lit-element 데코레이터 가이드
앞의 코드에서 사용된 데코레이터를 살펴보도록 하겠습니다.
@customElemenet("lit-tomato") 코드는 다음 코드와 동일합니다.
customElements.define('lit-tomato', Tomato);

https://developer.mozilla.org/en-US/docs/Web/API/Window/customElements

window.customElements MDN

Tomato라는 LitElement 를 <lit-tomato>처럼 사용할 수 있도록 정의해주는 역활을 합니다. 이때 엘리먼트의 이름을 지정할때 '-'는 필수로 들어가야합니다. 이름에 '-' 가 없다면 다음 그림과 같은 빨간 줄을 보게 될 것입니다.
웹 컴포넌트 이름 규칙[웹 컴포넌트 이름 규칙]
타입스크립와 데코레이터를 함께 사용하기 위해서 간단한 설정이 필요했습니다.
tsconfig에서 experimentalDecorators 값을 true로 변경해 주었고,

tsconfig.json

"experimentalDecorators": true,
.babelrc에서 데코레이터를 사용하기위한 바벨 플러그인들을 설치해 추가해 주었습니다.

.babelrc

const plugins = [ "@babel/plugin-proposal-optional-chaining", "@babel/plugin-proposal-class-properties", ["@babel/plugin-proposal-decorators", { decoratorsBeforeExport: true }], ];
@query 등 다른 데코레이터는 다음 포스팅에서 변수 사용과 함께 사용해보도록 하겠습니다.
마지막으로 다음과 같이 엘리먼트의 타입을 선언해 줌으로써 다른 파일에서 커스텀 웹 컴포넌트를 찾을 수 있게 되었습니다.
declare global { interface HTMLElementTagNameMap { "lit-tomato": Tomato; } }
'lit-potato'라는 이름만 다른 파일을 만들어 html안에서<lit-tomato>를 사용해 보도록 하겠습니다.
lit type 자동완성[lit type 자동완성]
타입 조회는 할 수 있지만 자동으로 import가 되지 않으니 만들어준 웹 컴포넌트를 다른 파일에서 사용하려면 import를 해주어야 합니다.
import "./lit-tomato";
마찬가지로 index.html에서<lit-tomato>를 사용 할 수 있도록 index.ts에서 import 해주어야 합니다.

index.ts

import "./pages/lit-tomato";
여기까지 간단한 lit-element의 구성을 살펴 보았습니다. 다시 보자면 LitElement 를 확장한 클래스는 html 템플릿을 리턴하는 웹 컴포넌트를 리턴합니다. 이 클래스를<lit-tomato>라는 커스텀 엘리먼트로 지정하였고 index.ts에서 lit-tomato를 import하여 index.html에서 사용한<lit-tomato> 커스텀 엘리먼트를 사용할 수 있게 되었습니다. 다음 포스팅에서는 본격적으로 property를 사용하여 변수 사용 및 뷰의 변화를 주는 것을 해보도록 하겠습니다.
buy me a coffeebuy-me-a-coffee