Nuxt 를 배워보자

Nuxt에서 <script setup>과 <script>의 차이점: 간결하고 효율적인 컴포넌트 개발을 위한 선택

_Blue_Sky_ 2025. 2. 15. 12:48
728x90
728x90

Nuxt.js는 Vue.js를 기반으로 서버 사이드 렌더링(SSR)과 정적 사이트 생성(SSG) 기능을 제공하는 프레임워크입니다. Nuxt에서 컴포넌트를 작성할 때, <script> 태그 안에 JavaScript 코드를 작성하는데, <script setup>과 <script> 두 가지 형태를 사용할 수 있습니다. 각각의 특징과 장단점을 이해하고, 프로젝트에 적합한 방식을 선택하는 것은 효율적인 개발을 위한 중요한 요소입니다.

<script setup>이란?

Vue 3에서 도입된 <script setup>은 Composition API를 더욱 간결하게 사용할 수 있도록 지원하는 문법입니다. 컴포넌트 내부에서 setup() 함수를 직접 작성하지 않고, <script setup> 블록 안에 변수, 메서드, 컴퓨티드 프로퍼티 등을 직접 선언할 수 있습니다. 이는 코드 가독성을 높이고, TypeScript와의 통합을 원활하게 해줍니다.

주요 특징:

  • 간결한 문법: setup() 함수를 생략하고, 변수와 메서드를 직접 선언
  • Composition API 활용: ref, reactive, computed 등 Composition API를 자유롭게 사용
  • TypeScript 지원: TypeScript와의 긴밀한 통합으로 강력한 타입 안전성 제공
  • SFC 컨텍스트: 템플릿 내에서 선언된 변수와 메서드에 직접 접근 가능
728x90

<script>와의 차이점

특징 script setup script
문법 간결하고 직관적 상대적으로 verbose
Composition API 기본 지원 별도의 setup() 함수 필요
TypeScript 지원 우수 상대적으로 제한적
SFC 컨텍스트 직접 접근 this 키워드 사용
Sheets로 내보내기

왜 <script setup>을 사용해야 할까요?

  • 더 짧고 간결한 코드: 불필요한 코드를 줄여 가독성 향상
  • 더 나은 타입 안전성: TypeScript와의 긴밀한 통합으로 오류 감소
  • 더 효율적인 개발: 빠른 개발 속도와 생산성 향상
  • 더 직관적인 API: Composition API를 더욱 자연스럽게 활용

예제

<template>
  <div>
    <p>현재 카운트: {{ count }}</p>
    <button @click="increment">증가</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const count = ref(0);

function increment() {
  count.value++;
}
</script>

위 예제에서 볼 수 있듯이, <script setup>을 사용하면 setup() 함수 없이 간결하게 카운터 기능을 구현할 수 있습니다.


1. <script setup>

  • Composition API를 위한 간결한 문법: <script setup>은 Vue 3에서 도입된 Composition API를 더욱 간결하게 사용할 수 있도록 제공하는 문법입니다.
  • 자동 컴포넌트 등록: 컴포넌트 내에서 사용되는 변수, 함수, 컴포넌트 등을 자동으로 템플릿에 등록하여 사용할 수 있습니다.
  • 명시적인 반환 불필요: setup() 함수에서 반환 값을 명시적으로 지정할 필요 없이, <script setup> 블록 내에서 선언된 변수나 함수는 템플릿에서 바로 사용할 수 있습니다.

장점:

  • 코드 간결성: Composition API 코드를 더욱 짧고 읽기 쉽게 작성할 수 있습니다.
  • 생산성 향상: 자동 컴포넌트 등록으로 인해 개발 생산성을 높일 수 있습니다.
  • 코드 유지보수 용이: 코드가 간결하고 직관적이어서 유지보수가 용이합니다.

단점:

  • Options API 사용 불가: <script setup> 블록 내에서는 Options API를 사용할 수 없습니다.
  • 호환성 문제: Vue 2에서는 <script setup> 문법을 사용할 수 없습니다.

2. <script>

  • Options API 및 Composition API 지원: Options API와 Composition API를 모두 사용할 수 있습니다.
  • 명시적인 반환 필요: setup() 함수를 사용하는 경우, 템플릿에서 사용할 변수나 함수를 명시적으로 반환해야 합니다.

장점:

  • 유연성: Options API와 Composition API를 모두 사용할 수 있어 다양한 개발 방식에 적용 가능합니다.
  • 호환성: Vue 2에서도 사용할 수 있습니다.

단점:

  • 코드 복잡성: Composition API를 사용하는 경우, <script setup>에 비해 코드가 길어지고 복잡해질 수 있습니다.
  • 수동 등록 필요: 템플릿에서 사용할 변수나 함수를 setup() 함수에서 명시적으로 반환해야 합니다.

3. 왜 이런 옵션이 있을까요?

Vue.js는 다양한 개발 방식을 지원하기 위해 <script setup>과 <script> 두 가지 옵션을 제공합니다.

  • Composition API의 효율성: <script setup>은 Composition API를 더욱 효율적으로 사용할 수 있도록 설계되었습니다.
  • Options API의 익숙함: Options API에 익숙한 개발자들을 위해 <script>를 통한 개발 방식을 지원합니다.
  • 하위 호환성: Vue 2 사용자를 위해 <script>를 통한 Options API 사용을 지원합니다.

4. 어떤 것을 선택해야 할까요?

  • Vue 3를 사용하고 Composition API에 익숙하다면: <script setup>을 사용하는 것이 좋습니다. 코드를 간결하게 작성하고 생산성을 높일 수 있습니다.
  • Options API에 익숙하거나 Vue 2를 사용해야 한다면: <script>를 사용해야 합니다.
  • 상황에 따라 혼용 가능: <script setup>과 <script>를 함께 사용하여 필요한 기능을 구현할 수 있습니다.

결론

Nuxt에서 컴포넌트를 개발할 때, <script setup>은 더욱 효율적이고 생산적인 개발 환경을 제공합니다. 특히 대규모 프로젝트나 복잡한 로직을 구현할 때, <script setup>의 장점을 극대화할 수 있습니다. 하지만 기존 프로젝트나 간단한 컴포넌트의 경우, <script>를 사용하는 것이 더 적합할 수도 있습니다.


Nuxt.js <script setup>의 한계점 및 주의사항

Nuxt.js 3에서 도입된 <script setup>은 Composition API를 더욱 간결하게 사용할 수 있도록 도와주는 강력한 문법입니다. 하지만 완벽한 것은 아니며, 몇 가지 한계점과 주의사항을 가지고 있습니다.

1. Options API 사용 불가

  • <script setup> 블록 내에서는 Options API를 사용할 수 없습니다. 즉, data(), methods(), computed 등의 옵션을 사용할 수 없습니다.
  • Options API를 사용해야 하는 경우에는 <script> 블록을 별도로 사용해야 합니다.

2. 호이스팅 문제

  • <script setup> 블록 내에서 선언된 변수나 함수는 템플릿에서 바로 사용할 수 있지만, 호이스팅(hoisting)으로 인해 예상치 않은 동작이 발생할 수 있습니다.
  • 특히, 컴포넌트의 속성(props)을 사용하는 경우, 호이스팅 순서에 따라 오류가 발생할 수 있으므로 주의해야 합니다.

3. 모듈 실행 의미 체계

  • <script setup> 내부의 코드는 SFC(Single File Component)의 컨텍스트에 의존합니다.
  • 이를 외부 .js 또는 .ts 파일로 옮기면 개발자와 도구 모두에게 혼란을 초래할 수 있습니다.
  • 따라서 <script setup>은 src 속성과 함께 사용할 수 없습니다.

4. In-DOM Root Component Template 미지원

  • <script setup>은 In-DOM Root Component Template을 지원하지 않습니다.

5. 타입 선언 시 기본값 설정 문제

  • 타입 전용 defineProps 선언 시 props에 대한 기본값을 제공하는 방법이 없습니다.
  • 이 문제를 해결하기 위해 withDefaults 컴파일러 매크로를 사용해야 합니다.

6. 서버 사이드 렌더링 (SSR) 시 주의사항

  • <script setup>은 클라이언트 사이드에서 실행되는 코드이므로, 서버 사이드 렌더링 시 데이터를 미리 가져오는 데에는 적합하지 않습니다.
  • 서버 사이드 렌더링 시 데이터를 가져오려면 useAsyncData 또는 fetch 훅을 사용하는 것이 좋습니다.

7. 기타

  • 일부 Nuxt 모듈 또는 라이브러리에서 <script setup>과 호환되지 않는 경우가 있을 수 있습니다.
  • <script setup>은 Vue 3에서만 사용할 수 있으며, Vue 2에서는 사용할 수 없습니다.

주의사항

  • <script setup>을 사용할 때는 위에서 언급한 한계점을 충분히 이해하고 주의해야 합니다.
  • 필요한 경우 <script> 블록을 함께 사용하여 Options API를 사용하거나, 호이스팅 문제를 해결해야 합니다.
  • 서버 사이드 렌더링 시에는 useAsyncData 또는 fetch 훅을 사용하는 것을 잊지 마세요.

결론

<script setup>은 Composition API를 더욱 간결하게 사용할 수 있도록 도와주는 유용한 문법이지만, 몇 가지 한계점과 주의사항을 가지고 있습니다. 이러한 한계점을 이해하고 주의사항을 지키면서 <script setup>을 사용하면 더욱 효율적인 개발이 가능합니다.


 

Nuxt.js <script setup>과 TypeScript 심층 활용 가이드

Nuxt.js 3에서 <script setup>은 Composition API를 더욱 간결하고 효율적으로 사용할 수 있게 해주는 강력한 문법입니다. 여기에 TypeScript를 더하면 코드의 안정성과 가독성을 높여 개발 생산성을 극대화할 수 있습니다. 본 가이드에서는 <script setup>과 TypeScript를 함께 사용하는 심층적인 활용 방법을 소개합니다.

1. 컴포넌트 속성(Props) 타입 정의

defineProps를 사용하여 컴포넌트 속성의 타입을 명확하게 정의할 수 있습니다.

<script setup lang="ts">
import { defineProps } from 'vue';

const props = defineProps<{
  name: string;
  age?: number; // optional
  address: {
    street: string;
    city: string;
  };
}>();

console.log(props.name);
</script>

인터페이스를 사용하여 복잡한 타입 정의를 간소화할 수 있습니다.

<script setup lang="ts">
import { defineProps } from 'vue';

interface Address {
  street: string;
  city: string;
}

const props = defineProps<{
  name: string;
  age?: number;
  address: Address;
}>();
</script>
  • withDefaults를 사용하여 속성 기본값을 설정할 수 있습니다.
<script setup lang="ts">
import { defineProps, withDefaults } from 'vue';

const props = withDefaults(defineProps<{
  name: string;
  age?: number;
}>(), {
  age: 20,
});
</script>

2. 컴포넌트 내 데이터 타입 정의

ref 또는 reactive를 사용하여 컴포넌트 내 데이터를 정의할 때 타입을 명시하여 데이터의 안정성을 확보할 수 있습니다.

<script setup lang="ts">
import { ref } from 'vue';

const count = ref<number>(0);
const message = ref<string | null>(null);

const user = ref<{ name: string; age: number }>({
  name: 'John',
  age: 30,
});
</script>

3. 함수 타입 정의

함수의 매개변수와 반환 값 타입을 명시하여 함수의 동작을 예측 가능하게 만들고 오류를 방지할 수 있습니다.

<script setup lang="ts">
const add = (a: number, b: number): number => {
  return a + b;
};

const greet = (name: string): string => {
  return `Hello, ${name}!`;
};
</script>

4. 이벤트 핸들러 타입 정의

이벤트 핸들러 함수의 매개변수 타입을 명시하여 이벤트 객체의 속성에 안전하게 접근할 수 있습니다.

<script setup lang="ts">
const handleClick = (event: MouseEvent): void => {
  console.log(event.clientX);
};
</script>

5. 컴포넌트 타입 추론 활용

TypeScript는 컴포넌트 속성, 데이터, 함수 등의 타입을 자동으로 추론할 수 있습니다. 이를 활용하여 코드 작성 시간을 단축하고 오류를 줄일 수 있습니다.

<script setup lang="ts">
const name = ref('John'); // string으로 추론
const age = ref(30); // number로 추론

const user = reactive({
  name: 'John',
  age: 30,
}); // { name: string; age: number }로 추론
</script>

6. 유틸리티 타입 활용

TypeScript에서 제공하는 다양한 유틸리티 타입을 활용하여 복잡한 타입 정의를 간소화하고 재사용성을 높일 수 있습니다.

<script setup lang="ts">
import { PropType } from 'vue';

interface User {
  name: string;
  age: number;
}

const props = defineProps({
  user: {
    type: Object as PropType<User>,
    required: true,
  },
});
</script>

7. 제네릭 활용

제네릭을 사용하여 컴포넌트의 재사용성을 높이고 다양한 타입에 대응할 수 있도록 만들 수 있습니다.

<script setup lang="ts">
import { ref } from 'vue';

const list = ref<Array<number | string>>([]);

const addItem = <T>(item: T) => {
  list.value.push(item);
};
</script>

8. Nuxt.js 관련 타입 활용

Nuxt.js에서 제공하는 useFetch, useAsyncData 등의 함수와 관련된 타입을 활용하여 데이터를 더욱 안전하게 다룰 수 있습니다.

<script setup lang="ts">
import { useFetch } from '#imports';

const { data } = useFetch<{ message: string }>('/api/hello');

if (data.value) {
  console.log(data.value.message);
}
</script>

결론

<script setup>과 TypeScript를 함께 사용하면 Nuxt.js 컴포넌트 개발을 더욱 효율적이고 안정적으로 수행할 수 있습니다. 위에서 소개한 심층 활용 방법을 참고하여 프로젝트에 적용해 보세요.


실제 프로젝트에서 Nuxt.js <script setup> 적용 가이드

Nuxt.js 3에서 <script setup>은 Composition API를 더욱 간결하고 효율적으로 사용할 수 있게 해주는 강력한 문법입니다. 실제 프로젝트에서 <script setup>을 적용하는 방법을 단계별로 안내해 드립니다.

1. 프로젝트 설정 확인

  • Nuxt.js 3 버전 이상을 사용하고 있는지 확인합니다.
  • TypeScript를 사용하는 경우, TypeScript 설정이 올바르게 되어 있는지 확인합니다.

2. 컴포넌트 분석 및 전환 계획 수립

  • 프로젝트 내 컴포넌트들을 분석하여 <script setup>으로 전환할 컴포넌트를 선정합니다.
  • Options API를 사용하는 컴포넌트는 Composition API로 전환하는 계획을 세웁니다.
  • 컴포넌트 의존 관계를 파악하여 전환 순서를 결정합니다.

3. <script setup> 기본 사용법 익히기

  • <script setup> 블록 내에서 Composition API 함수 (ref, reactive, computed, watch, onMounted 등)를 사용하는 방법을 익힙니다.
  • defineProps를 사용하여 컴포넌트 속성 타입을 정의하고, defineEmits를 사용하여 이벤트를 정의하는 방법을 익힙니다.

4. 컴포넌트 전환

  • 선정된 컴포넌트들을 하나씩 <script setup> 방식으로 전환합니다.
  • Options API를 사용하는 컴포넌트는 Composition API로 코드를 변경합니다.
  • 필요한 경우, 기존 컴포넌트 로직을 재사용하거나 새로운 로직을 추가합니다.

5. 타입스크립트 적용 (선택 사항)

  • TypeScript를 사용하는 경우, 컴포넌트 속성, 데이터, 함수 등의 타입을 명시하여 코드 안정성을 높입니다.
  • 타입 추론을 활용하여 코드 작성 시간을 단축하고 오류를 줄입니다.

6. 컴포넌트 테스트

  • 전환된 컴포넌트들을 테스트하여 정상적으로 동작하는지 확인합니다.
  • 필요한 경우, 테스트 코드를 작성하여 컴포넌트의 기능을 검증합니다.

7. 프로젝트 적용 및 배포

  • 모든 컴포넌트 전환이 완료되면 프로젝트에 적용하고 배포합니다.
  • 지속적인 코드 개선 및 유지보수를 통해 프로젝트를 관리합니다.

실제 적용 예시

<template>
  <div>
    <h1>{{ message }}</h1>
    <button @click="increment">Count is: {{ count }}</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const message = 'Hello, Nuxt.js with script setup!';
const count = ref(0);

const increment = () => {
  count.value++;
};
</script>

추가 팁

  • 컴포넌트 전환 시, 작은 단위부터 시작하여 점진적으로 확대하는 것이 좋습니다.
  • <script setup>과 함께 TypeScript를 사용하면 코드 안정성을 더욱 높일 수 있습니다.
  • 필요한 경우, Composition API 관련 자료나 Nuxt.js 공식 문서를 참고하세요.

주의사항

  • <script setup>은 Vue 3에서만 사용할 수 있습니다.
  • Options API와 함께 사용할 수 없습니다.
  • 서버 사이드 렌더링 시에는 useAsyncData 또는 fetch 훅을 사용하는 것이 좋습니다.

결론

<script setup>은 Nuxt.js 개발 생산성을 높여주는 강력한 도구입니다. 실제 프로젝트에 적용하여 더욱 효율적인 개발 경험을 느껴보세요.

728x90
728x90