본문으로 건너뛰기
개발 머꼬
개발 노트Nuxt.js
hohyeon.dev16

컴포넌트를 만들었는데 템플릿에서 못 찾은 이유 — 이름은 경로가 정한다

  • #Common Pitfall
  • #Engineering Note
  • #Nuxt.js

문제 발생

components/base/foo/Button.vue를 만들고 템플릿에서 썼는데 렌더링되지 않았습니다.

<template>
  <Button>저장</Button>   <!-- 아무것도 안 나오거나 네이티브 button 으로 해석됨 -->
</template>

import를 안 써도 된다고 해서 그냥 파일명으로 부른 것이 문제였습니다.

원인 분석

자동 임포트는 "아무 이름으로나 쓸 수 있다"는 뜻이 아닙니다. Nuxt 문서는 규칙을 명확히 적습니다 — 컴포넌트 이름은 자신의 경로 디렉터리와 파일명을 기준으로 정해지며, 중복된 세그먼트는 제거됩니다.

그래서 components/base/foo/Button.vue의 이름은 <BaseFooButton />입니다. <Button />은 그 이름이 아니므로 매칭되지 않고, 브라우저는 그냥 알 수 없는 태그로 처리합니다.

이 규칙이 있는 이유는 이름 충돌입니다. components/post/Card.vuecomponents/user/Card.vue가 둘 다 <Card />가 되면 자동 임포트 자체가 성립하지 않습니다.

해결 방안

  1. 경로가 붙은 이름으로 씁니다.
<BaseFooButton>저장</BaseFooButton>
  1. 디렉터리 한 단계를 이름에서 빼려면 괄호로 감쌉니다. 문서가 제시하는 그룹핑 방법입니다 — components/base/(foo)/Button.vue<BaseButton />이 됩니다. 폴더로 정리는 하되 이름은 짧게 유지할 때 씁니다.

  2. 정말 파일명만 쓰고 싶으면 pathPrefix를 끕니다. 다만 그 순간 이름 충돌을 우리가 책임져야 합니다.

components: [{ path: "~/components", pathPrefix: false }]
  1. 실행 환경이 갈리는 컴포넌트는 접미사를 씁니다. 문서 설명대로 .client 접미사를 붙이면 클라이언트에서만 렌더되고, .server는 서버 전용입니다 — 브라우저 API에 의존하는 컴포넌트를 여기에 둡니다.

  2. 자동완성을 믿습니다. Nuxt가 만들어주는 타입 정의에 실제 이름이 들어 있습니다 — 이름을 추측하지 말고 에디터가 제안하는 것을 씁니다.

  3. HTML 표준 요소와 겹치는 이름을 피합니다. <Button />, <Header /> 같은 이름은 대소문자만 다른 네이티브 태그와 헷갈려 이번 같은 증상을 진단하기 어렵게 만듭니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.