[클론 코딩] Nuxt3 웹 사이트 만들기(프로젝트 생성 및 초기 구성) - 1편

2023. 7. 2. 20:20초기 과업/FrontEnd

작성자알 수 없는 사용자

728x90
반응형

안녕하세요! 기깔나는 사람들에서 프론트엔드을 맡고 있는 해리입니다!

신규 프로젝트에 들어가기 전 팀원분과 클론 코딩이란 주제로 미소(https://miso.kr/deepclean) 웹 사이트를 구현하게되었습니다!

 

이사청소, 입주청소 전문업체 | 대한민국 1등 홈서비스 - 미소

이사청소, 입주청소, 거주청소 전문 집청소업체 무료 견적 받고 비용 비교하세요. 평당 10,900원으로 간편예약도 가능! 평점으로 검증된 파트너, 당일 검수 후 A/S 보장해 드려요.

miso.kr

 

모두 아래와 동일한 기술 스택으로 개발을 진행하려고합니다!

JavaScript Framework : Vue3

Vue Framework : Nuxt3

Language : TypeScript

UI Framework : Quasar

State Management : Pinia

Test Library : Vitest

 

이번 편에선 Nuxt 프로젝트 생성 및 기본적으로 사용할 라이브러리들을 추가하는 작업을 해보려고합니다! 🙂

 

✅ 프로젝트 생성

Nuxt3 프로젝트 생성 및 의존성 라이브러리 설치

# nuxt3 프로젝트 생성
npx nuxi@latest init <project-name>

# 의존성 라이브러리 설치
yarn install

# nuxt3 프로젝트 실행
yarn dev

localhost:3000 으로 실행된 페이지

 

프로젝트 폴더 구성

아래는 제가 자주 사용하는 폴더 구성입니다.

.nuxt : 개발 중인 디렉토리를 사용하여 Vue 애플리케이션을 생성합니다. 서버를 실행할 때마다 다시 생성됩니다.

assets : 프로젝트에서 사용하는 css, image, font 등을 관리하며 webpack, vite 의 영향을 받습니다.

components :  페이지에서 사용하는 공통 컴포넌트들을 관리하는 저장소입니다.

composables : composable 을 관리하는 저장소로 Nuxt 애플리케이션에서 자동 가져오기를 통해 애플리케이션 전체에서 사용할 수 있습니다

layouts : Nuxt 애플리케이션에서 제공하는 사용자 지정 가능한 레이아웃으로 공통적인 요소들을 정의하여 각 페이지들에서 지정하여 사용할 수 있습니다.

pages : Nuxt 애플리케이션은 파일 기반의 라우팅을 제공합니다. pages 에 위치한 파일, 폴더를 기반으로 경로가 자동으로 생성됩니다.

public : 변경되지 않을 가능성이 있는 파일들을 관리하는 저장소입니다.

server : API 및 서버 핸들러를 등록할 수 있으며 Nuxt 애플리케이션에서 아래의 디렉토리 내의 파일을 자동으로 스캔합니다.

- server/api
- server/routes
- server/middleware

types : interface 또는 type 을 관리하는 저장소입니다.

utils : 헬퍼 기능 및 유틸리티 함수를 관리하는 저장소로 Nuxt 애플리케이션에서 자동 가져오기를 통해 애플리케이션 전체에서 사용할 수 있습니다.

 

eslint와 prettier

eslint와 prettier를 통해 일관성있는 코드 스타일을 유지할 수 있습니다!

eslint는 코드의 잠재적인 문제와 구문오류 등의 문제를 포착하여 알려주고, prettiersms 자동 코드 포맷터입니다.

 

eslint, prettier 관련 라이브러리 설지

# eslint
yarn add --dev eslint

# airbnb
yarn add --dev eslint-config-airbnb

# prettier
yarn add --dev prettier eslint-config-prettier eslint-plugin-prettier

# typescript 관련 라이브러리
yarn add --dev typescript @typescript-eslint/parser @nuxtjs/eslint-config-typescript

 

.eslintrc 파일 추가

설치한 라이브러리로 ESLint Configuration 를 작성합니다.

parser : 구문 분석을 위한 파서를 지정할 수 있습니다.

parserOptions : Eslint 사용을 위해 지원하려는 JavaScript 언어 옵션을 지정할 수 있습니다.

extends : 추가한 플러그인에서 사용할 규칙을 설정할 수 있습니다.

rules : 현재 프로젝트에서 사용하는 규칙을 수정할 수 있습니다.

- off or 0 : 규칙 사용안함

- warn or 1 : 규칙 경고 사용

- error or 2 : 규칙 오류 표시

{
  "parser": "vue-eslint-parser",
  "parserOptions": {
    "parser": "@typescript-eslint/parser"
  },
  "extends": [
    "plugin:vue/vue3-essential",
    "@nuxtjs/eslint-config-typescript", // TypeScript 지원을 위해 권장하는 extends 입니다
    "plugin:prettier/recommended",
    "airbnb"
  ],
  // 서드파티 플러그인 사용
  "plugins": [],
  // 규칙 수정
  "rules": {
    "prettier/prettier": "error"
  }
}

 

.prettierrc 파일 추가

{
  "trailingComma": "es5",
  "tabWidth": 2,
  "semi": true,
  "singleQuote": false
}

 

 

Pinia 추가하기

 

Pinia 설치

yarn add pinia @pinia/nuxt

 

모듈 등록

nuxt.config.ts 파일에 pinia를 모듈에 등록하고 auto import 옵션을 추가해주면 pinia 사용을 위한 준비는 끝이납니다.

export default defineNuxtConfig({
	// ...
    modules: ["@pinia/nuxt"],
    pinia: {
    	autoImports: ["defineStore"],
    },
});

 

Store 생성

pinia 가 제대로 적용되었는 지 확인하기 위해 Store를 생성하여 테스트해보겠습니다.

store 폴더와 폴더안에 test.ts 파일을 생성합니다.

 

이번 프로젝트에서 Pinia 의 장점인 Composition API 를 사용하여 구현해볼 예정입니다!

아래는 Composition API 를 사용하여 간단하게 Store 에 title State 값을 추가해주었습니다.

export const useTestStore = defineStore("test", () => {
  const title = ref<string>("제목입니다.");

  return { title };
});

 

Store 사용

<template>
  <div>{{ title }}</div>
</template>

<script lang="ts">
import { useTestStore } from "@/store/test";

export default {
  setup() {
    const testStore = useTestStore();

    return { title: testStore.title };
  },
};
</script>

<style lang=""></style>

 

정상적으로 State 값을 가져오신 것을 확인하실 수 있습니다.

localhost:3000 실행 화면

 

 

Vitest 추가하기

 

vitest 설치 및 의존성 라이브러리 설치

vitest 관련 라이브러리로는 @vitestjs/plugin-vue 는 Vue 3에서 제공하고 있는 API 를 사용할 수 있게해줍니다. vitest 는 코드 커버리지 기능을 제공하는데 그 중 하나가 @vitest/coverage-v8 라이브러리 입니다. 

vue 에서 지원하는 테스트 라이브러리로는 @vue/test-utils 와 nuxt 테스트를 위한 @nuxt/test-utils 가 있습니다.

unplugin-auto-import는 테스트 시 자동으로 지정한 라이브러리를 가져와줍니다. nuxt.config.js 에서 적용한 auto import와 맞추기 위해 사용해줍니다.

# vitest
yarn add --dev vitest jsdom @vitejs/plugin-vue @vitest/coverage-v8

# vue
yarn add --dev @vue/test-utils @nuxt/test-utils

# third party library
yarn add --dev unplugin-auto-import

 

vitest.config.js 파일 추가

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import AutoImport from "unplugin-auto-import/vite";
import path from "path";

export default defineConfig({
  plugins: [
    vue(),
    AutoImport({
      imports: ["vue", "pinia"],
      dirs: ["./composables/"],
    }),
  ],
  test: {
    globals: true,
    environment: "jsdom",
    include: [path.resolve(__dirname, "**", "*.spec.ts")],
    coverage: {
      provider: "v8",
      reporter: "html",
      reportsDirectory: "./coverage",
    },
  },
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./"),
    },
  },
});

 

package.json 에 아래 명령어를 추가해줍니다.

"scripts": {
	// ...
	"test": "yarn vitest run --dir test",
	"coverage": "vitest run --coverage"
}

 

pinia 테스트하기

위에서 생성한 test store의 초기 State 값을 정상적으로 가져오는지 확인하는 테스트 코드를 작성해보았습니다.

아래와 같이 작성 시 describe 와 setActivePinia 등 vitest, pinia 를 통해 가져오는 코드가 없어 오류가 날 것입니다. yarn test 를 실행하면 "auto-imports.d.ts" 파일이 생성되면서 오류가 없어집니다!

import { useTestStore } from "@/store/test";

describe("Test Store", () => {
  beforeEach(() => {
    setActivePinia(createPinia());
  });

  test("title", () => {
    const testStore = useTestStore();
    expect(testStore.title).toMatch(/제목입니다./);
  });
});

 

테스트 코드 또한 통과하신 것을 보실 수 있습니다!

테스트 성공!

 

 

Quasar 추가하기

 

Quasar 설치 및 의존성 라이브러리 설치

# quasar
yarn add quasar @quasar/extras

# vue
yarn add --dev nuxt-quasar-ui

 

모듈 등록

nuxt.config.ts 파일에 nuxt-quasar-ui를 모듈에 등록하면 Quasar를 사용하기 위한 준비가 끝이났습니다.

export default defineNuxtConfig({
	// ...
    modules: [
    	// ...
        "nuxt-quasar-ui"
    ],
    // ...
});

 

아래는 Quasar 가 제대로 적용되었는지 확인하기 위해 QCard Component 를 사용하여 카드를 구현해봤습니다.

<template>
  <q-card class="my-card">
    <q-card-section>
      <div class="text-h6">{{ title }}</div>
    </q-card-section>

    <q-separator />

    <q-card-actions vertical>
      <q-btn flat>Action 1</q-btn>
      <q-btn flat>Action 2</q-btn>
    </q-card-actions>
  </q-card>
</template>

<script lang="ts">
export default {
  setup() {
    const title = ref("제목입니다.");

    return { title };
  },
};
</script>

<style lang="css">
.my-card {
  margin: 10px;
  width: 100%;
  max-width: 250px;
}
</style>

 

정상적으로 카드가 그려졌습니다!

q-card

 

이렇게 기본적인 프로젝트 설정이 끝이났습니다!👏🏻👏🏻👏🏻

다음편에서는 Quasar 를 이용한 miso 웹 사이트의 레이아웃을 구현해보겠습니다!

 

끝까지 읽어주셔서 감사합니다 :)


728x90
반응형