컴포넌트 생각해보기

Daniel Woo·2023년 6월 8일
0
post-thumbnail

들어가며

온라인 구인구직 플랫폼 서비스인 원티드에서는 매달 다른 주제로 진행하는 개발자 챌린지가 있다. 6월 프론트엔드 챌린지 주제가 평소 고민하고 있는 컴포넌트 기반 개발에 대한 것이고 알고 있는 네임드 프론트엔드 개발자가 리딩을 하여 관심을 갖고 참여하게 되었다.

이번 챌린지의 리딩을 맡으신 장현석님은 이전에 들었던 유데미 강의때문에 조금 알고 있는 프론트엔드 개발자였다.(그 강의가 처음에 어려워서 듣다가 환불했다는 것은 안 비밀…)

1회차의 주제는 크게 두 가지였다. 그 중 컴포넌트에 대해 오고 갔던 이야기와 내 경험을 말해보려고 한다.

  • 컴포넌트란?
  • 2016년에 프론트엔드를 배우는 기분, 2023년에 프론트엔드를 배우는 기분

컴포넌트란?

현석님은 컴포넌트가 무엇이라고 생각하세요? 라는 질문을 던지며 강의를 시작하였다. ‘컴포넌트를 뭐라고 정의내리는 것이 좋을까…’ 컴포넌트 개발 경험을 더듬으며 떠올릴 수 있었던 속성은 다음과 같다. 재사용, 모듈, UI, 로직(기능), 커스텀, HTML, 스타일. 문장으로 예쁘게 정리해보면 내가 정의한 컴포넌트란 다음과 같을 것이다.

커스텀이 가능 하고 HTML을 생성하는 재사용 가능한 기능, 스타일 UI의 모듈 집합

컴포넌트 분류

실제 컴포넌트의 정의와 맞는 지는 이후에 확인해보고, 현석님은 컴포넌트를 3가지 종류로 구분해보자고 하였다.

  • 컴포넌트
  • Web 컴포넌트
  • FrameWork(React, Vue, Angular 등) 컴포넌트

이러한 분류로 컴포넌트를 세분화 한 것은 추상적인 의미에서 모두 다 컴포넌트이지만 세부적으로는 구분점이 명확하기 때문이다.

Web Component

가장 일반적인 컴포넌트에 대한 고민은 앞서 해봤으니, 그 다음으로 Web 컴포넌트에 대해 생각해보자. MDN문서에 따르면 Web 컴포넌트의 정의는 다음과 같다.

웹 컴포넌트는 그 기능을 나머지 코드로부터 캡슐화하여 재사용 가능한 커스텀 엘리먼트를 생성하고 웹 앱에서 활용할 수 있도록 해주는 다양한 기술들의 모음
- MDN -

웹상에서 설치 없이 바로 사용할 수 있고, 재사용 가능하며 커스텀 엘리먼트를 생성할 수 있는 것이 특징인 API이다. 설치가 불필요한 것이 중요한 특징인데, React와 같은 라이브러리는 NPM 또는 CDN을 통해 설치를 외부 패키지를 설치해야한다. 하지만 웹 컴포넌트는 웹 표준에 포함되었기 때문에 설치가 필요 없다. 또, 웹 개발에 있어서 모두가 접근 가능한 자원이고, deprecated 되거나 웹 표준에서 없어질 가능성이 적다.

즉, 개발 이후에 지원에 대한 안정성이 높다. 또한 웹 표준에 명시되어 있는 API이기 때문에 결함이 적다. 이는 비즈니스 관점에서는 큰 이점이 되는데, 큰 변화가 잦은 기술일 수록 그 다음 기술에 대한 마이그레이션에 대한 리소스가 들어가기 때문에 수익보다 지출이 많은 것은 큰 단점이 되기 때문이다. JavaScript는 항상 논란이 있었던 언어였지만 웹 그리고 브라우저가 크게 다른 노선을 선택하지 않는 한 웹 소프트웨어에 가장 중요한 언어로 남아있는 것 처럼 웹 표준은 현재로서는 가능 안전하고 가치있는 기준일 것이다.

FrameWork Component

웹 개발 입문과 동시에 React를 가장 먼저 접한 나에게는 사실 컴포넌트하면 가장 먼저 그려지는 이미지가 이거다. React팀이 자기들의 도구를 “UI를 생성하기 위한 자바스크립트 라이브러리” 라고 정의했던 것 처럼, FrameWork Component는 일반적인 컴포넌트의 의미를 이어가면서도 UI에 조금 더 중점을 둔 것처럼 느껴진다. React로 화면에 쓰일 컴포넌트를 개발하는 나의 경험을 바탕으로는 HTML와 흡사한 JSX문법을 반환하는 방식이 기능을 시각적으로 HTML과 연결될 수 있도록 하는 것 같다.

리액트의 컴포넌트는 크게 데이터(data), 기능(JavaScript), 스타일(CSS), HTML(JSX)로 이루어졌다고 생각한다. 함수형 컴포넌트 스타일로 작성한 다음 간단한 컴포넌트를 보자.

import styles from './artist.module.css';

const ARTIST_DATA = [
{
	id: 1,
	name: '검정치마',
	thumbnailSrc: 'black_skirt_thumb.png',
	members: [],
	albums: [],
},
{
	id: 2,
	name: 'RedHotChiliPeppers',
	thumbnailSrc: 'RHCP_thumb.png',
	members: [],
	albums: [],
},
{
	id: 3,
	name: 'Nirvana',
	thumbnailSrc: 'nirvana_thumb.png',
	members: [],
	albums: [],
},
];

const Artists = (data) => {
		const [artists, setArtists] = useState([]); 

		const downloadArtistDetails = () => {
			...	
		};
	
		useEffect(()=>{
			(async()=>{
					const fetchedData = await fetch();
					setArtists(fetchedData);
				})()
		},[])
	
		return (
			<ul>
				{data.map((artist)=> 
					<li 
						key={artist.id} 
						className={styles.item} 
						onClick={downloadArtistDetails}>
							<div className={styles.imageWrapper}>
								<img 
									src={artist.thumbnailSrc} 
									alt={`artist image ${artist.name}`}
								/>
							</div>
							<div className={styles.descriptions}>
								<p>Name: {artist.name}</p>
								<div>
									members: <ul>{members.map((member)=> <li>...</li> )}</ul>
								</div>
								<div>
									albums: <ul>{albums.map((album)=> <li>...</li> )}</ul>
								</div>
							</div>
					</li>
				)}
			</ul>
		)
}

위의 컴포넌트는 동기, 비동기로 데이터를 받아와 아티스트를 리스트 형태의 HTML으로 반환하는 동작을 한다. HTML을 더욱 시각적으로 돋보이게 하기 위해 CSS를 적용하였고, 리스트의 아이템을 클릭하면 바인딩된 함수가 실행되어 유저와 상호작용을 할수 있도록 한다. 연관된 데이터(상태), 메서드(행동)을 같이 관리하는 모듈과도 비슷한거 같기도 하다.

좋은 컴포넌트 만들기

위와 같이 어떤 특정 기능을 수행하는 컴포넌트를 만드는 것은 배우는데 그리 어렵지 않고, 실무에서 많이 쓰이는 패턴이다. 특정 케이스에 대해서만 생각하면 되기 때문에 설계가 쉽지만, 요구 사항이 변할 때 변경에 취약할 수 있으며, ‘차라리 새로 만들까?’ 라는 생각이 들게 할 정도로 유연하지 않고 딱딱하다.

현석님은 좋은 컴포넌트를 만들기 위해서는 ‘내가 아닌 누군가가 사용할 컴포넌트’를 떠올려 보라고 한다. 현재 케이스 말고 비슷한 유형의 케이스라면 모두 적용되는 형태로 말이다. 하지만 말이 쉽지, 유연하고 재사용 가능하며, 커스텀할 수 있는 컴포넌트를 만드는 것은 어렵다. 내가 당장 업무를 수행하는 것에 있어서는 사실 재사용성이 없었어도 되고, 유연하지 않더라고 어떻게든 누덕누덕 기능은 동작하게 할 수 있기 때문이다.

하지만, 경험상 그 누군가가 내가 되어 후회할 확률이 99.9%였다. 또한, 생산성을 높이기 위한 공통 컴포넌트 제작에 시간을 투자하는 것이 그 이후 업무에서 효율을 비약적으로 높여주기 때문에 단기적으로는 쓸데 없는 투자처럼 보이지만 아주 큰 도움이 되었다.

물론 요구사항을 기한 안에 끝내기 위해서는 어느정도 타협점이 필요하다. 어느정도까지 유연하고 장기적인 관점에서 컴포넌트를 설계할 것인지 판단하기란 쉽지 않은 일이다. 나 같은 경우는 좋지 않은 컴포넌트로 서비스를 개발하고 그것에 대한 부채를 경험한 이후로 좋은 컴포넌트를 만들기 위한 관심과 노력을 기울였다. 스스로 다양한 시도를 해보기도 했고 그 한계를 느끼고 유명한 개발자들이 공유한 좋은 유스케이스에 대해 레퍼런스를 답습하기도 하였다. 실패와 부족함을 경험해보고 개선하는 것과 공부를 철저히 하고 실패를 최소화 하는 것 둘 중 어느 것이 더 좋은가에 대한 답은 없는 것 같다. 각자의 상황에 따라 선택하고 그 결과에 따른 다음 최선을 고르는 것이 가장 좋지 않을까 생각한다.

다시 컴포넌트로 돌아가서

React를 필두로한 SPA가 트랜드가 되면서 SPA로 컴포넌트를 설계하거나 구현할 수는 있어도 vanilla JavaScript로 간단한 기능을 만드는 것에도 머리를 싸매는 경우가 많다. 위에서 말했듯이 웹 표준은 한 회사나 작은 트렌드에 의존하지 않기 때문에 지속가능하고 안정성이 높다. 반면, React와 같은 라이브러리는 한 때 반짝하는 트렌드가 될 수도 있고 너무 많은 변화로 혼란만 줄 수 있다. 우리가 사용하는 기술의 본질을 생각해보는 것은 아주 좋은 습관인 거 같다. 마블 시리즈에서 아이언 맨인 토니 스타크가 스파이더 맨 역할의 피터에게 말했던 것처럼 우리는 리액트가 없더라도 웹 서비스, 웹 소프트웨어를 만들 수 있는 역량을 키워야하는 것이 웹 개발자의 본질이지 않을까 생각이 들었다.

슈트 없이는 아무것도 아니라면, 슈트를 가져선 더더욱 안 돼.
- Tony Stark -


3줄 요약

  • React를 포함한 컴포넌트 기반의 웹 개발에서, 좋은 컴포넌트를 만들기 위해서는 재사용성과 유연성을 고려해야 한다.
  • 웹 표준은 안정성이 높고 지속 가능하지만, 라이브러리와 프레임워크는 변화가 많아 혼란을 줄 수 있다.
  • 개발자는 기술의 본질을 생각하고, 웹 서비스를 만들 수 있는 역량을 키워야 한다.
profile
모두가행복한세상을만들고싶은사람

0개의 댓글