📌 개요
Vue 프로젝트에서 여러 개의 독립적인 애플리케이션을 관리해야 하는 상황이 있습니다. 예를 들어, 관리자용 앱과 고객용 앱을 하나의 코드베이스에서 관리하면서도 별도로 빌드해야 한다면 어떻게 해야 할까요? 이 글에서는 Vite를 사용하여 Vue 3 프로젝트에서 다중 앱을 구성하고 빌드하는 방법을 소개합니다.
🎯 목표
- App1.vue → 빌드 시 dist/gtc/index.html로 출력
- App2.vue → 빌드 시 dist/customer/index.html로 출력
- 공통 컴포넌트와 유틸리티는 재사용
- 각 앱마다 독립적인 진입점(entry point) 설정
🗂️ 프로젝트 구조
다중 앱 구성을 위한 권장 프로젝트 구조는 다음과 같습니다:
my-vue-app/
├── index.html ← 기본 템플릿 (사용 안함)
├── apps/
│ ├── gtc/
│ │ ├── index.html ← gtc 전용 템플릿
│ │ └── main.js ← App1.vue 마운트
│ └── customer/
│ ├── index.html ← customer 전용 템플릿
│ └── main.js ← App2.vue 마운트
├── src/
│ ├── App1.vue ← GTC 앱의 루트 컴포넌트
│ ├── App2.vue ← Customer 앱의 루트 컴포넌트
│ ├── components/ ← 공유 컴포넌트
│ ├── assets/ ← 공유 에셋
│ └── utils/ ← 공유 유틸리티 함수
├── package.json
└── vite.config.js ← 멀티 앱 빌드 설정
🛠️ 주요 설정 파일
1. Vite 설정 - vite.config.js
Vite를 사용하여 다중 앱을 구성하기 위한 핵심 설정 파일입니다:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
export default defineConfig({
plugins: [vue()],
build: {
rollupOptions: {
input: {
gtc: resolve(__dirname, 'apps/gtc/index.html'),
customer: resolve(__dirname, 'apps/customer/index.html'),
},
output: {
// 출력 파일 커스터마이징 (선택사항)
// entryFileNames: (chunk) => {
// return `assets/${chunk.name}/[name]-[hash].js`;
// },
// chunkFileNames: 'assets/js/[name]-[hash].js',
// assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
},
},
outDir: 'dist', // 기본 출력 디렉터리
emptyOutDir: true
},
resolve: {
alias: {
'@': resolve(__dirname, 'src'), // '@' 별칭 설정
},
},
});
2. GTC 앱 진입점 - apps/gtc/main.js
import { createApp } from 'vue';
import App1 from '../../src/App1.vue';
// 필요한 경우 앱별 스타일 임포트
import '../../src/assets/styles/gtc.css';
// 앱별 라우터 설정 (선택사항)
// import router from './router';
const app = createApp(App1);
// 앱에 필요한 플러그인 추가
// app.use(router);
app.mount('#app');
3. Customer 앱 진입점 - apps/customer/main.js
import { createApp } from 'vue';
import App2 from '../../src/App2.vue';
// 필요한 경우 앱별 스타일 임포트
import '../../src/assets/styles/customer.css';
// 앱별 라우터 설정 (선택사항)
// import router from './router';
const app = createApp(App2);
// 앱에 필요한 플러그인 추가
// app.use(router);
app.mount('#app');
4. HTML 템플릿 - apps/gtc/index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="/favicon.ico" />
<title>GTC 애플리케이션</title>
<meta name="description" content="GTC 관리자용 애플리케이션입니다" />
</head>
<body>
<div id="app"></div>
<script type="module" src="./main.js"></script>
</body>
</html>
5. HTML 템플릿 - apps/customer/index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="/favicon.ico" />
<title>고객용 애플리케이션</title>
<meta name="description" content="고객을 위한 서비스 애플리케이션입니다" />
</head>
<body>
<div id="app"></div>
<script type="module" src="./main.js"></script>
</body>
</html>
🚀 앱별 라우터 설정 (선택사항)
각 앱에 독립적인 라우터를 설정하려면, 다음과 같이 구성할 수 있습니다:
GTC 앱 라우터 - apps/gtc/router.js
import { createRouter, createWebHistory } from 'vue-router';
const routes = [
{
path: '/',
name: 'GtcHome',
component: () => import('@/views/gtc/HomeView.vue'),
},
{
path: '/dashboard',
name: 'GtcDashboard',
component: () => import('@/views/gtc/DashboardView.vue'),
},
// GTC 앱 전용 라우트
];
const router = createRouter({
history: createWebHistory('/gtc/'),
routes,
});
export default router;
Customer 앱 라우터 - apps/customer/router.js
import { createRouter, createWebHistory } from 'vue-router';
const routes = [
{
path: '/',
name: 'CustomerHome',
component: () => import('@/views/customer/HomeView.vue'),
},
{
path: '/products',
name: 'CustomerProducts',
component: () => import('@/views/customer/ProductsView.vue'),
},
// 고객용 앱 전용 라우트
];
const router = createRouter({
history: createWebHistory('/customer/'),
routes,
});
export default router;
🌐 환경 변수 설정
앱별로 다른 환경 변수를 사용하려면, 다음과 같이 설정 파일을 분리할 수 있습니다:
공통 환경 변수 - .env
VITE_API_TIMEOUT=30000
VITE_DEFAULT_LOCALE=ko
GTC용 환경 변수 - .env.gtc
VITE_APP_TITLE=GTC Admin
VITE_API_BASE_URL=https://api.example.com/admin
Customer용 환경 변수 - .env.customer
VITE_APP_TITLE=Customer Portal
VITE_API_BASE_URL=https://api.example.com/customer
📦 빌드 명령어
package.json에 앱별 빌드 스크립트를 추가합니다:
{
"scripts": {
"dev:gtc": "vite --config vite.config.js --mode gtc",
"dev:customer": "vite --config vite.config.js --mode customer",
"build": "vite build",
"build:gtc": "vite build --mode gtc",
"build:customer": "vite build --mode customer",
"preview:gtc": "vite preview --mode gtc",
"preview:customer": "vite preview --mode customer"
}
}
📝 빌드 결과
빌드가 완료되면 다음과 같은 디렉터리 구조가 생성됩니다:
dist/
├── gtc/
│ ├── index.html
│ ├── assets/
│ ├── js/
│ ├── css/
│ └── images/
├── customer/
│ ├── index.html
│ ├── assets/
│ ├── js/
│ ├── css/
│ └── images/
💡 추가 팁
공통 컴포넌트 활용
공통 컴포넌트는 src/components 폴더에 위치시키고, 각 앱에서 필요에 따라 임포트하여 사용할 수 있습니다:
// 앱별 진입점 파일에서
import BaseButton from '@/components/BaseButton.vue';
import BaseInput from '@/components/BaseInput.vue';
const app = createApp(App1);
// 전역 컴포넌트로 등록
app.component('BaseButton', BaseButton);
app.component('BaseInput', BaseInput);
개발 서버 설정
개발 중에는 주로 한 앱만 작업하게 되므로, Vite 개발 서버를 앱별로 시작할 수 있습니다:
# GTC 앱 개발
npm run dev:gtc
# Customer 앱 개발
npm run dev:customer
Monorepo로 확장하기
앱이 더 복잡해지거나 공유 라이브러리가 많아지면 pnpm workspace나 nx를 활용한 monorepo 구조로 전환을 고려해볼 수 있습니다.
🔍 결론
Vue 3와 Vite를 사용하면 하나의 프로젝트에서 여러 앱을 효율적으로 관리할 수 있습니다. 이러한 접근 방식은 코드 재사용성을 높이고, 개발 및 유지보수 비용을 절감하는 데 도움이 됩니다. 앱별로 독립적인 빌드 결과물을 얻으면서도, 공통 컴포넌트와 유틸리티를 공유할 수 있어 일관된 사용자 경험을 제공할 수 있습니다.
이 가이드가 Vue 3에서 다중 앱을 구성하는 데 도움이 되셨기를 바랍니다. 더 복잡한 요구사항이 있다면 모노레포 구조나 마이크로프론트엔드 아키텍처도 고려해볼 수 있습니다.
'프로그래밍 > Js' 카테고리의 다른 글
Vue의 계산된 속성(computed) 내 get()과 set() 메서드 설명 (0) | 2025.05.15 |
---|---|
TODO 관리 시스템 (0) | 2025.03.18 |
console.log 출력 내용을 <div>에 표시하는 방법 (0) | 2025.02.28 |
Promise.all 모든 비동기 작업이 끝난후 작업 실행 (0) | 2024.10.25 |
Promise 와 async await 대해 자세하게 알아보자. (0) | 2024.10.24 |