“ 당신은 소프트웨어 품질을 추구할 수도 있고, 포인터 연산을 할 수도 있다. 그러나 두 개를 동시에 할 수는 없다. ”
안녕하세요. 한 주간 잘 지내셨나요?
22년 11월 Nuxt3 3.0 버전을 발표했는데요
그에 따라 nuxt2에서 nuxt3로 마이그레이션 하는 개발자 분들도 많아졌다고 생각합니다.
물론 아직 Nuxt3에서 지원되는 부분이 Nuxt2에 비해서 부족하다고 하지만
새로운 기능과 여러 요건들에 따라서 새로운 프로젝트를 시작하거나, nuxt3 기능을 맛볼 수 있는 nuxt Bridge 버전으로
마이그레이션 하시는 분들 또한 있을 겁니다.
이번 포스팅에서는 Nuxt Bridge를 제외하고 Vue 3.0에서 새롭게 도입된
Composition API 모듈을 사용가능하게 설정하는 방법과
Pinia라는 Vue 애플리케이션에서 상태 관리를 위한 라이브러리 또한 설정해 볼 겁니다.
컴포지션 API와 Typescript와 함께 하기 적합한 설계를 가지고 있어서 기대가 됩니다.
아!
여기서 제가 Nuxt Bridge로 안 하고 Nuxt2에서 환경을 구축하려는 이유는
23년 5월 기준으로 도저히 현재 나온 버전에서 pinia와 컴포지션 api를 Nuxt Bridge에서
사용하기 힘들더라고요.. 온갖 오류난무에 호환성 안 맞고 하나를 고치면 하나가 에러 나고..
Nuxt Bridge 깃허브 repo 보시면 아직도 계속 뭔가 업데이트되는 거 같아서
추후에 Nuxt3로 넘어가던지 Nuxt Bridge로 갈지 고민해봐야겠습니다.
Nuxt Bridge란 무엇인가?
Nuxt Bridge는 Nuxt.js v3에서 도입된 새로운 기능으로, Nuxt.js v2에서 사용되던 라우팅 및 상태 관리 라이브러리 (Vue Router, Vuex 등)를 Nuxt.js v3에서도 계속 사용할 수 있도록 지원하는 기능입니다
즉 Nuxt Bridge를 사용하면 Nuxt.js v2에서 사용하던 Vue Router와 Vuex를 그대로 유지하면서, Nuxt.js v3의 새로운 기능을 사용할 수 있습니다. 이를 통해 기존 코드를 변경하지 않고도 새로운 기능을 사용하면서도 유연하게 전환할 수 있습니다. 또한 Nuxt Bridge를 사용하면 이전 버전과 동일한 방식으로 작업할 수 있으므로, 이전 버전에서 작성한 코드를 Nuxt.js v3로 이전할 때 유용합니다.
Pinia란 무엇인가?
Pinia는 Vue.js 애플리케이션에서 상태 관리를 위한 간단하고 직관적인 상태 관리 라이브러리입니다. Vuex와 같은 다른 상태 관리 라이브러리와는 다르게, Pinia는 Vue.js 3 Composition API를 기반으로 하며, TypeScript와 함께 사용하기 적합한 설계를 가지고 있습니다.
Pinia의 주요 특징은 다음과 같습니다.
1. 직관적인 API: Pinia는 직관적인 API를 제공하여 간단하고 쉬운 사용성을 제공합니다. Vuex와 같은 다른 상태 관리 라이브러리보다 적은 코드로 상태를 관리할 수 있습니다.
2. TypeScript 지원: Pinia는 TypeScript를 완전히 지원합니다. 이를 통해 코드의 안정성과 가독성을 높일 수 있습니다.
3. 모듈러 디자인: Pinia는 상태와 로직을 모듈화 하여 코드의 재사용성과 유지보수성을 높일 수 있도록 설계되었습니다.
4. SSR 지원: Pinia는 서버 사이드 렌더링 (SSR)을 지원하며, Vue.js 3 Composition API를 사용하여 코드를 구성할 수 있습니다.
5. Devtools 지원: Pinia는 Vue.js Devtools와 통합되어 디버깅이 용이합니다.
사용 환경
- node : v16.14.0
- Nuxt : v2.15.8
- vue : 2.7.10
- package Manager : npm
Nuxt 2.15.8 버전으로 맞춰서 진행해 주시면 됩니다.
아래 명령어로 프로젝트 설치 후 위에 환경 버전을 맞춰주셔도 됩니다.
전체 설정된 프로젝트 파일은 맨 아래에 깃허브 URL 남길 테니 여기서 받으셔도 됩니다.
npx create-nuxt-app my-project
Composition API 설치 및 설정
npm install @nuxtjs/composition-api@0.33.1
nuxt.config.js에 buildModules에 작성합니다.
// nuxt.config.js
buildModules: [
'@nuxtjs/composition-api/module',
],
pages/index.vue 파일에서 컴포지션 API가 사용되는지 확인하시면 됩니다.
<template>
<div>
<v-btn @click="handleClickEvent">Click Me</v-btn>
<div>{{ state.name }}</div>
</div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue'
const state = reactive({
test: 'test',
name: ''
})
const handleClickEvent = () => {
console.log(state.test)
}
</script>
Pinia 설치
@pinia/nuxt는 0.2.1 버전을 꼭 맞춰주셔야 합니다. 또한 컴포지션 API도 같이 설치해야 합니다.
npm install pinia @pinia/nuxt@0.2.1
혹시 위에 설치만 했는데 vue-demi 에러가 나온다면, node_modules 삭제하고 package.json에 vue-demi 추가해서
npm install 합니다.
// package.json
"vue-demi": "^0.14.1",
nuxt.config.js에 buildModules에 추가해 줍니다.
disableVuex 옵션을 false로 설정하면 Pinia와 함께 Vuex도 활성화됩니다. 반대로 disableVuex 옵션을 true로 설정하면 Pinia만 활성화되며, 내부적으로 Vuex가 생성되지 않습니다. 이 경우 앱의 번들 사이즈가 줄어들고, 상태 관리 라이브러리가 중복으로 적용되지 않습니다. 하지만 Vuex를 사용하는 라이브러리와의 호환성 문제가 발생할 수 있으므로, 이 경우에는 주의해야 합니다.
// nuxt.config.js
buildModules: [
'@nuxtjs/composition-api/module',
['@pinia/nuxt', { disableVuex: false }]
],
vuex도 사용할 경우나, 또는 혹시를 대비해서 pinia는 'stores'라는 폴더를 새로 만들겠습니다.
Pinia는 Vuex에서 Mutations가 빠진 State, Getters, Actions로 구성되었다고 생각하시면 됩니다.
import { defineStore } from 'pinia'
interface State {
userName: string
}
export const useGlobalStore = defineStore('global', {
state: (): State => {
return { userName: 'aa' }
},
getters: {
getUserName: (state) => state.userName
},
actions: {
setUserName(name: string) {
this.userName = name
}
}
})
pinia를 사용할 stores 폴더에 만든 global.ts를 import 해서 사용합니다.
<template>
<div>
<v-btn @click="handleClickEvent">Click Me</v-btn>
<div>{{ state.name }}</div>
</div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue'
import { useGlobalStore } from '~/stores/global'
// pinia 스토어 할당
const global = useGlobalStore()
const state = reactive({
test: 'test',
name: ''
})
const handleClickEvent = () => {
state.name = global.getUserName
}
</script>
위에 과정이 귀찮으시다면 제 Github repo에 Nuxt2 + Composition API + Pinia + Typesciprt로 초기 설정만 한 프로젝트가 있습니다. 한번 참고하시면 될 거 같습니다. vuetify , axios, proxy 등 기본적인 설정은 다 해둔 상태입니다.