컴포넌트 구조 리뷰
components/index.js는 모든 컴포넌트를 불러오는 진입점입니다.
import './PortfolioCard/PortfolioCard.js';
import './BackToTop/BackToTop.js';
import './SiteHeader/SiteHeader.js';
import './HeroSection/HeroSection.js';
import './WorksSection/WorksSection.js';
import './SiteFooter/SiteFooter.js';
이 파일이 실행되면 각 컴포넌트 파일 안에서 customElements.define()이 실행됩니다.
SiteHeader
태그:
<site-header></site-header>
역할:
- 로고 표시
- Design / Dev 모드 토글 버튼
- Docs, Works, Contact 링크
- 모바일 메뉴 모달 렌더링
중요한 부분:
<div class="mode-toggle" role="tablist" aria-label="모드 전환">
<button class="mode-btn" data-mode="design">Design</button>
<button class="mode-btn active" data-mode="dev">Dev</button>
<span class="mode-indicator" aria-hidden="true"></span>
</div>
모드 토글은 main.js의 ModeToggle 객체가 이벤트를 붙입니다.
HeroSection
태그:
<hero-section></hero-section>
역할:
- 첫 화면 문구 표시
- 현재 모드에 따라 핵심 문장 변경
<span class="line line-2" data-design="Designer who codes." data-dev="Developer who designs.">
<span class="mode-text">Developer who designs.</span>
</span>
data-design, data-dev는 ModeToggle이 읽어서 텍스트를 바꿉니다.
WorksSection
태그:
<works-section></works-section>
역할:
- 포트폴리오 데이터 배열 관리
- 필터 버튼 렌더링
- 기술 태그 필터 영역 렌더링
portfolio-card목록 생성- empty state, loader, sentinel 생성
핵심 데이터:
const portfolioItems = [
{
category: 'site',
tech: 'Web Components,JavaScript,CSS,Railway',
href: 'https://zenoblog-production.up.railway.app/',
title: 'zenoBlog'
}
];
PortfolioCard
태그:
<portfolio-card></portfolio-card>
역할:
- 작업물 카드 하나 렌더링
- attribute를 읽어 카드 이미지, 제목, 설명, 링크 구성
- 필터링에 필요한
dataset설정
this.dataset.category = category;
this.dataset.tech = tech;
this.dataset.order = order;
이 값은 main.js의 Filter와 InfiniteScroll에서 사용합니다.
SiteFooter
태그:
<site-footer></site-footer>
역할:
- 하단 브랜드/사이트맵/채널/연락처 표시
<back-to-top>컴포넌트 포함
<back-to-top></back-to-top>
BackToTop
태그:
<back-to-top></back-to-top>
역할:
- 상단 이동 버튼 렌더링
스크롤 이벤트와 클릭 이벤트는 main.js의 BackToTop 객체가 처리합니다.
구조적으로 좋은 점
- 컴포넌트별 폴더가 명확함
- JS와 CSS가 같은 폴더에 있어 찾기 쉬움
- 카드 UI는 재사용 가능하게 분리됨
- 데이터 배열만 수정하면 카드 목록이 바뀜
아쉬운 점
- 모든 카드 데이터가
WorksSection.js에 길게 들어 있음 main.js가 여러 기능을 한 파일에서 모두 담당함innerHTML로 attribute 값을 바로 넣기 때문에 외부 입력을 받을 경우 XSS 주의가 필요함
현재처럼 본인이 관리하는 정적 데이터라면 큰 문제는 아니지만, 외부 사용자 입력이 들어오면 문자열 정제가 필요합니다.