이전 글에서 이어집니다.
결론부터 말하자면 제가 공식 가이드만 읽으면서 만든 Vue 프로젝트는 아무것도 진전된 게 없었습니다.
마지막 커밋 내역이 25년도 4월이었으니까요.
혹시 라이브러리 공식 가이드만 보고 소규모 프로젝트 하나 만드신 분 있으세요? 축하합니다. 교과서만 보고 서울대 가신 분입니다. 근데 전 모르겠더라고요.
공식 가이드와 다른 사람들이 쓴 예제를 보면서 이렇게 쓰는 건가? 하고 멋대로 넘겨짚기만 하다 보니까 문법이 완전히 꼬여버려, scss를 import만 해도 오류가 나버린 사태가 벌어졌습니다.
그래도 꼴에 익숙한 라이브러리좀 쓰고 싶어서 냅다 css 라이브러리를 설치했어요. 물론 제 vue 버전은 vue3였고, Vue Styled Components 라는 라이브러리가 따로 있는지도 몰랐습니다.
그렇게 저는 react에 설치하는 버전을 설치한겁니다.
덕분에 영문 모르는 오류가 나며, styled component는 사용도 하지 못한 채 오리지널 css 시트를 사용해 스타일링을 입혔습니다. 게다가 이때는 ai의 도움 없이 혼자서만 해결하겠다는 고집을 부렸던 시기고요.
거의 생 html 퍼블리싱이나 다름없다고 생각한 저는 여기서 무력감을 느끼고 프로젝트를 던졌습니다.
다행히 새로 입사한 회사에서는 클로드 ai를 지원해줘서 유료 ai툴의 덕을 톡톡히 봤습니다.
시간적 여유가 났기 때문에, 제가 던져두었던 뷰 프로젝트가 생각이 났고 이녀석을 클로드의 도움을 받아 다시 만져보기로 했습니다.
가장 먼저 확인한건 현재 프로젝트의 세팅이 잘 되어있는지 물어보는 것.
크게 문제는 없었지만, 새로 알게된 사실이 있습니다.
.vue 확장자 파일을 생성할 경우의 컴포넌트 네이밍 규칙은 카멜케이스의 두글자 조합으로 만들어진다는 것이었습니다. 물론 회사마다 다르겠죠?
처음엔 이 규칙을 지키지 않아 eslint에서 오류가 났습니다.
Home.vue (X) => 리액트에선 이래도 된다고요
HomeView.vue (O)
이건 뭐 파일명만 고쳐주면 되니까 넘어가고, 저는 이걸 타입스크립트 프로젝트로 고치고 싶었습니다. 처음 설치할때 ts버전으로 못깔았거든요.그래서 클로드에게 도움을 요청했습니다.(혼자서 타입스크립트로 전환하려 했으나, 변환한 사례를 못찾았음)
npm install --save-dev typescript @vue/cli-plugin-typescript vue-tsc @types/node
근데 초장부터 에러가 납니다
npm error code ERESOLVE
npm error ERESOLVE could not resolve
npm error
npm error While resolving: profile@0.1.0
npm error Found: webpack@5.95.0
npm error node_modules/webpack
npm error peer webpack@"^4.0.0 || ^5.0.0" from @soda/friendly-errors-webpack-plugin@1.8.1
npm error node_modules/@soda/friendly-errors-webpack-plugin
npm error @soda/friendly-errors-webpack-plugin@"^1.8.0" from @vue/cli-service@5.0.8
npm error node_modules/@vue/cli-service
npm error peer @vue/cli-service@"^3.0.0 || ^4.0.0 || ^5.0.0-0" from @vue/cli-plugin-babel@5.0.8
npm error node_modules/@vue/cli-plugin-babel
npm error dev @vue/cli-plugin-babel@"~5.0.0" from the root project
npm error 4 more (@vue/cli-plugin-eslint, @vue/cli-plugin-router, ...)
npm error webpack@"^5.54.0" from @vue/cli-plugin-babel@5.0.8
npm error node_modules/@vue/cli-plugin-babel
npm error dev @vue/cli-plugin-babel@"~5.0.0" from the root project
npm error 19 more (@vue/cli-plugin-eslint, @vue/cli-service, css-loader, ...)
npm error
npm error Could not resolve dependency:
npm error dev @vue/cli-plugin-typescript@"*" from the root project
npm error
npm error Conflicting peer dependency: webpack@4.47.0
npm error node_modules/webpack
npm error peer webpack@"^4.0.0" from cache-loader@4.1.0
npm error node_modules/cache-loader
npm error peerOptional cache-loader@"^4.1.0" from @vue/cli-plugin-typescript@5.0.9
npm error node_modules/@vue/cli-plugin-typescript
npm error dev @vue/cli-plugin-typescript@"*" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error /Users/ontact/.npm/_logs/2025-11-27T01_17_29_283Z-eresolve-report.txt
npm error A complete log of this run can be found in: /Users/ontact/.npm/_logs/2025-11-27T01_17_29_283Z-debug-0.log
평범한 웹팩 버전 충돌 문제입니다. 안전하게 Vue CLI 5와 호환되는 버전으로 설치했습니다.
npm install --save-dev typescript@~5.0.0 @vue/cli-plugin-typescript@~5.0.0 vue-tsc@^1.0.0 @types/node@^18.0.0 --legacy-peer-deps
그렇게 설치된 package.json의 디펜던시 목록입니다.(버전 참고용)
"dependencies": {
"core-js": "^3.8.3",
"vue": "^3.2.13",
"vue-router": "^4.0.3"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.25.1",
"@babel/preset-env": "^7.25.4",
"@types/node": "^18.19.130",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-typescript": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"@vue/eslint-config-typescript": "^11.0.3",
"autoprefixer": "^10.4.22",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^9.33.0",
"postcss": "^8.5.6",
"sass": "^1.79.4",
"sass-loader": "^16.0.2",
"tailwindcss": "^3.4.18",
"typescript": "~5.0.0",
"vue-tsc": "^1.8.27"
},
그냥 ai가 추천해주는 대로 쓰고 파일 최상단에 저장했습니다.
//tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
"exclude": ["node_modules"]
}
파일 내의 모든 js파일을 ts파일로 변경해야 합니다.
이건 귀찮아서 그냥 ai한테 알아서 해달라 했습니다.
vue 파일을 보면 이렇게 스크립트가 들어가 있는데, 이 스크립트를 ts로 바꾸어줘야 합니다.
//변경 전
<script>
import FooterComponent from '@/components/common/FooterComponent.vue'
import HeaderComponent from '@/components/common/HeaderComponent.vue'
</script>
//변경 후
<script setup lang="ts">
import FooterComponent from '@/components/common/FooterComponent.vue'
import HeaderComponent from '@/components/common/HeaderComponent.vue'
</script>
파일 최상단에 추가되는 파일입니다.
//shims-vue.d.ts
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
이놈은 왜 넣는가?하고 물어봤더니 타입스크립트가 뷰 파일을 이해할 수 있도록 타입 선언을 제공하는 역할을 한다고 하네요.그래서 이 파일이 없으면 다음과 같은 에러가 난다 합니다.
import App from './App.vue' // ❌ Cannot find module './App.vue'
추가적으로 IDE가 뷰 파일을 import 할때 타입 추론과 자동완성을 제공한다고도 합니다.
Vue 3 + TypeScript 조합의 프로젝트이므로 이 파일이 필수적으로 들어갑니다.
와중에 eslint에서 이 파일을 오류로 인식하여, package.json에 다음과 같이 설정을 추가했습니다.
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/typescript/recommended"//추가됨
],
"parserOptions": {
"parser": "@typescript-eslint/parser",//추가됨
"ecmaVersion": 2020//추가됨
},
"rules": {
"vue/multi-word-component-names": "error"
}
},
npm i로 패키지를 재설치하려 했으나 아래와 같은 오류가 발생합니다.
npm error code ERESOLVE
npm error ERESOLVE could not resolve
npm error
npm error While resolving: @typescript-eslint/eslint-plugin@8.48.0
npm error Found: eslint@7.32.0
npm error node_modules/eslint
npm error dev eslint@"^7.32.0" from the root project
npm error peer eslint@"^7.5.0 || ^8.0.0 || ^9.0.0" from @babel/eslint-parser@7.25.1
npm error node_modules/@babel/eslint-parser
npm error dev @babel/eslint-parser@"^7.25.1" from the root project
npm error 7 more (@eslint-community/eslint-utils, ...)
npm error
npm error Could not resolve dependency:
npm error peer eslint@"^8.57.0 || ^9.0.0" from @typescript-eslint/eslint-plugin@8.48.0
npm error node_modules/@typescript-eslint/eslint-plugin
npm error dev @typescript-eslint/eslint-plugin@"^8.48.0" from the root project
npm error @typescript-eslint/eslint-plugin@"8.48.0" from typescript-eslint@8.48.0
npm error node_modules/typescript-eslint
npm error typescript-eslint@"^8.35.1" from @vue/eslint-config-typescript@14.6.0
npm error node_modules/@vue/eslint-config-typescript
npm error dev @vue/eslint-config-typescript@"^14.6.0" from the root project
npm error
npm error Conflicting peer dependency: eslint@9.39.1
npm error node_modules/eslint
npm error peer eslint@"^8.57.0 || ^9.0.0" from @typescript-eslint/eslint-plugin@8.48.0
npm error node_modules/@typescript-eslint/eslint-plugin
npm error dev @typescript-eslint/eslint-plugin@"^8.48.0" from the root project
npm error @typescript-eslint/eslint-plugin@"8.48.0" from typescript-eslint@8.48.0
npm error node_modules/typescript-eslint
npm error typescript-eslint@"^8.35.1" from @vue/eslint-config-typescript@14.6.0
npm error node_modules/@vue/eslint-config-typescript
npm error dev @vue/eslint-config-typescript@"^14.6.0" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error /Users/ontact/.npm/_logs/2025-11-27T01_24_54_780Z-eresolve-report.txt
npm error A complete log of this run can be found in: /Users/ontact/.npm/_logs/2025-11-27T01_24_54_780Z-debug-0.log
이건 eslint 버전 7이 버전 충돌을 일으켜서 발생한 에러로, eslint를 삭제한 후 호환이 되는 구버전으로 설치를 진행했습니다.
npm uninstall @typescript-eslint/eslint-plugin @typescript-eslint/parser @vue/eslint-config-typescript
npm install --save-dev @typescript-eslint/eslint-plugin@^5.0.0 @typescript-eslint/parser@^5.0.0 @vue/eslint-config-typescript@^11.0.0 --legacy-peer-deps
eslint-plugin-vue 패키지도 업데이트가 필요하여
npm install --save-dev eslint-plugin-vue@^9.0.0 --legacy-peer-deps
이렇게 진행하였습니다.
패키지 설치까지 잘 됐으나 이번엔 빌드 에러가 납니다. 기존의 컴포넌트들이 Vue2의 Option API를 사용하고 있었기에, Vue3에서 권장하는 Composition Api로 교체해야 합니다. (Option Api 문법이 어려워서 바꾼게 맞습니다.)
이 작업 또한 귀찮아서 AI에게 맡겼습니다. 여기까지 고치니까 이제 겨우겨우 프로젝트가 돌아가서, 다음 단계로 넘어갑니다.
아무래도 styled-component를 사용하는걸 고집할 필요는 없을 것 같아,타입스크립트로 바꾼 겸 tailwind css를 사용하기로 합니다. 저는 테일윈드의 방식이 썩 마음에 들지는 않지만 트렌드를 따라 익숙해져 보자는 취지였습니다. (물론 CSS Modules를 사용하는 방법도 좋지만 대충 아는 방식이기 때문에..)
ai가 하라는 대로 세 명령어를 실행했습니다.
npm uninstall tailwindcss
npm install -D tailwindcss@^3.4.0 --legacy-peer-deps
npx tailwindcss init -p
이후 세 가지 파일들을 작성해줍니다.
//파일 최상단- postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
//파일 최상단- tailwind.config.js
/** @type {import('tailwindcss').Config} */
const plugin = require('tailwindcss/plugin')
module.exports = {
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
//임의로 사용할 컬러 테마, 폰트, 박스 섀도우 스타일들
theme: {
extend: {
colors: {
'black-333': '#333333',
'gray-7d': '#7d7d7d',
'gray-ed': '#EDEDED',
'green-01': '#158000',
'green-02': '#0F622D',
},
fontFamily: {
sans: ['SUIT', 'sans-serif'],
},
boxShadow: {
default: '0px 0px 20px 0px rgba(0, 0, 0, 0.08)',
},
},
},
//이런 식으로 임의의 클래스명도 추가 가능
plugins: [
plugin(({ addUtilities }) => {
addUtilities({
'.container-custom': {
width: '1000px',
marginLeft: 'auto',
marginRight: 'auto',
},
})
}),
],
}
/*
/assets/tawilwind.css
*/
@tailwind base;
@tailwind components;
@tailwind utilities;
그리고 사전에 scss로 글로벌 스타일, reset.css도 수정하고 적용해둔 상태입니다.
/*
/assets/scss/global.scss
여러 굵기의 폰트를 불러오고 글로벌로 적용하기
*/
@font-face {
font-family: 'SUIT';
src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/noonfonts_suit@1.0/SUIT-Regular.woff2')
format('woff2');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'SUIT';
src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/noonfonts_suit@1.0/SUIT-Medium.woff2')
format('woff2');
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'SUIT';
src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/noonfonts_suit@1.0/SUIT-SemiBold.woff2')
format('woff2');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'SUIT';
src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/noonfonts_suit@1.0/SUIT-Bold.woff2')
format('woff2');
font-weight: 700;
font-style: normal;
}
html,
*,
*:before,
*:after {
font-family: 'SUIT', sans-serif !important;
box-sizing: border-box;
::-webkit-scrollbar {
display: none;
}
font-size: 10px;
-webkit-touch-callout: none;
user-select: none;
}
body {
margin: 0;
padding: 0;
color: #333333;
overscroll-behavior-y: none;
letter-spacing: -1px;
}
전반적인 프로젝트 세팅이 끝나고, vscode에서 뷰를 좀더 수월하게 다루기 위해 익스텐션을 추가로 설치했습니다.
귀찮아서 아래 4개 정도만 설치했습니다. 자동 완성이나 스니펫 같은 것들을 지원해주는 익스텐션입니다.
1. Volar
2. Vue(Official)
3. Vue VSCode Snippets
4. Auto Close Tag
대충 세팅은 이 정도로 완료되었습니다. 이제는 본격적으로 뷰 컴포넌트를 작성할 차례입니다.
세팅만 해도 글이 길어져서, 컴포넌트 작성 편은 다음 포스팅으로 넘깁니다.