개발자 측면 기능:
사용자 측면 기능:
터미널 설정:
Node.js 및 NPM 설치:
웹 브라우저:
Git 소개 및 설치 확인: Git은 버전 관리 시스템으로 파일의 변경 사항을 추적하여 협업을 용이하게 합니다. 터미널에서 git --version 명령어로 Git이 설치되어 있는지 확인합니다.
Git 설정: 사용자 이름과 이메일을 설정하기 위해 다음 명령어를 사용합니다.
로컬 저장소 초기화:
GitHub와 연결:
원격 저장소 생성 및 연결:
향후 변경 사항 커밋 및 푸시:
<script setup lang="ts">
</script>
<template>
<RouterView />
</template>
<style scoped>
</style>
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.mount('#app')
프로젝트 관리 앱을 계획할 때, 이를 여러 페이지로 구성하는 것이 필수적입니다. 모든 프로젝트를 볼 수 있는 페이지와 특정 프로젝트를 볼 수 있는 페이지가 필요합니다. 이러한 페이지 간에 원활하게 탐색하기 위해 Vue Router를 설정합니다. 필요한 경로를 만들고 구성한 다음 RouterLink구성 요소를 사용하여 원활한 탐색을 가능하게 합니다. 이렇게 하면 페이지 간에 효율적으로 탐색할 수 있는 훌륭한 단일 페이지 애플리케이션 경험이 보장됩니다.
각 페이지는 Vue 컴포넌트로 표현되며, 사용자들이 페이지 간에 원활하게 이동할 수 있도록 Vue.js의 공식 라우팅 엔진인 Vue Router를 사용합니다. Vue Router를 사용하면 특정 경로에 컴포넌트를 매핑하여 전체 페이지를 새로 고침하지 않고도 필요한 컴포넌트만 교체하여 렌더링할 수 있습니다.
Vue Router 설정:
라우트 및 컴포넌트 생성:
라우터 링크 사용:
<a>
태그를 사용하여 내비게이션을 구현했지만, 전체 페이지가 새로 고침되는 문제가 있었습니다.<router-link>
컴포넌트로 변경하고 to
속성을 사용하여 페이지 전환 시 전체 페이지 새로 고침 없이 컴포넌트를 교체하도록 수정하였습니다.SPA
) 경험을 제공하지만, 현재 상태에서는 성능 최적화가 이루어지지 않아 오히려 성능에 부정적인 영향을 줄 수 있습니다. 이는 다음에 자세히 다룹니다.import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import HomeView from '@/views/HomeView.vue';
import ProjectsView from '@/views/ProjectsView.vue';
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'home',
component: HomeView,
},
{
path: '/projects',
name: 'projects',
component: ProjectsView,
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
<script setup lang="ts">
</script>
<template>
<RouterView />
</template>
<style scoped>
</style>
<template>
<div>
<h1>홈 페이지</h1>
<router-link to="/projects">프로젝트로 이동</router-link>
</div>
</template>
<script setup lang="ts">
// 스크립트 내용 없음
</script>
<style scoped>
/* 스타일 내용 없음 */
</style>
<template>
<div>
<h1>프로젝트 페이지</h1>
<router-link to="/">홈으로 이동</router-link>
</div>
</template>
<script setup lang="ts">
// 스크립트 내용 없음
</script>
<style scoped>
/* 스타일 내용 없음 */
</style>
잘 구성된 Vue Router 설정에도 숨겨진 성능 문제가 있을 수 있습니다. Vue Router를 사용하는 동안 흔히 범하는 함정 중 하나는 모든 페이지 뷰 구성 요소를 브라우저에 미리 제공하는 것입니다. 이렇게 하면 불필요한 JavaScript 파일로 브라우저가 부풀어 오르고 초기 로드 시간에 영향을 미칠 수 있습니다.
이번엔 Vue Router의 지연 로딩 지원과 Vite의 동적 가져오기를 활용하여 이 문제를 해결합니다. 이 접근 방식은 필요할 때만 구성 요소가 로드되도록 하여 앱의 속도와 반응성을 유지합니다.
현재 애플리케이션에서는 모든 페이지의 컴포넌트가 초기 로드 시 한꺼번에 번들되어 브라우저로 전송되고 있습니다. 이는 사용자가 특정 페이지만 방문하더라도 불필요한 컴포넌트까지 모두 다운로드하게 되어 초기 로딩 시간이 길어지고 성능이 저하되는 문제를 야기합니다. 이를 해결하기 위해 동적 임포트(
Dynamic Imports
)를 사용하여 필요한 컴포넌트만 로드하도록 Vue Router 설정을 수정합니다. 이렇게 하면 초기 번들 크기가 감소하여 애플리케이션의 성능과 사용자 경험이 향상됩니다.
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'home',
component: () => import('@/views/HomeView.vue'),
},
{
path: '/projects',
name: 'projects',
component: () => import('@/views/ProjectsView.vue'),
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
Vue Router에서 와일드카드를 사용하여 동적 경로로 라우팅 설정을 개선할 때입니다. 이 기능을 사용하면 각 프로젝트에 대한 전용 페이지를 만들 수 있습니다. 또한 Vue Router의 useRoute() 컴포저블을 탐색하여 동적 경로 정보에 액세스하고 관련 프로젝트 세부 정보를 표시합니다. 이 세션을 마치면 프로처럼 동적 경로를 관리하여 사용자 친화적인 앱을 보장할 수 있습니다.
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'home',
component: () => import('@/views/HomeView.vue'),
},
{
path: '/projects',
name: 'projects',
component: () => import('@/views/ProjectsView.vue'),
},
{
path: '/projects/:id',
name: 'single-project',
component: () => import('@/views/SingleProjectView.vue'),
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
<template>
<div>
<h1>프로젝트 상세 페이지</h1>
<p>프로젝트 이름: {{ projectName }}</p>
<p>프로젝트 ID: {{ route.params.id }}</p>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
const projectName = ref('프로젝트 이름');
// 추가 로직이 필요한 경우 여기에 작성합니다.
</script>
<style scoped>
/* 스타일 정의 */
</style>
정의되지 않은 경로를 처리하는 것은 사용자가 존재하지 않는 페이지에 도착했을 때 적절한 피드백을 제공하는 데 중요합니다. Vue Router에서 404 오류를 효과적으로 관리하기 위해 catch-all 경로를 설정합니다. NotFound 페이지를 생성하면 사용자가 빈 페이지를 마주치는 대신 항상 명확하고 유익한 피드백을 받을 수 있습니다. 또한 더 세부적인 제어를 위해 다른 경로 아래에 중첩된 모든 정의되지 않은 경로를 catch하는 방법도 알아봅니다.
현재 애플리케이션에서는 정의되지 않은 경로로 이동할 경우 빈 페이지가 나타나고, Vue Router는 콘솔에서 오류를 표시합니다. 이를 개선하기 위해 모든 정의되지 않은 경로를 포착하여 404 Not Found 페이지를 제공하는 방법을 구현합니다.
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'home',
component: () => import('@/views/HomeView.vue'),
},
{
path: '/projects',
name: 'projects',
component: () => import('@/views/ProjectsView.vue'),
},
{
path: '/projects/:id',
name: 'single-project',
component: () => import('@/views/SingleProjectView.vue'),
},
// 모든 정의되지 않은 경로를 포착하는 catch-all 라우트
{
path: '/:catchAll(.*)',
name: 'not-found',
component: {
render() {
return h(
'p',
{ style: { color: 'red' } },
'404 Not Found'
);
},
},
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
설명:
특정 경로 아래의 undefined 경로 포착 예시:
{
path: '/projects/:catchAll(.*)',
name: 'projects-not-found',
component: {
render() {
return h(
'p',
{ style: { color: 'blue' } },
'404 Project Not Found'
);
},
},
},
파일 기반 라우팅과 TypeScript를 사용하여 Vue Router에서 자동 경로를 설정하면 라우팅 설정이 간소화되어 코드베이스가 더 깔끔하고 관리하기 쉬워집니다. Nuxt.js와 유사하게 파일 구조에 따라 경로 생성을 자동화하기 위해 unplugin-vue-router를 사용합니다. 이렇게 하면 수동 경로 정의가 필요 없습니다.
unplugin-vue-router를 설치하고 구성하고, 디렉토리 구조를 조정하고, TypeScript 오류를 해결하는 것으로 시작합니다. 마지막에는 앱에서 동적으로 경로를 생성하여 간소화되고 효율적인 라우팅 시스템을 제공합니다.
이번 시간에는 Vue Router에서 파일 기반 라우팅(file-based routing
)과 TypeScript를 사용한 자동 라우팅(auto routing
)을 탐구합니다.
이를 통해 라우팅 설정을 단순화하고 코드베이스를 더욱 깔끔하고 관리하기 쉽게 만들 수 있습니다.
파일 기반 라우팅이란?
Vue에서 파일 기반 라우팅 구현하기
플러그인 설치
npm install -D unplugin-vue-router
Vite 설정 파일 수정 (vite.config.ts)
플러그인을 가져와서 Vite 플러그인 배열에 추가합니다.
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
import VueRouter from 'unplugin-vue-router/vite'
// https://vite.dev/config/
export default defineConfig({
plugins: [
VueRouter(), // Vue 플러그인보다 앞에 위치해야 합니다.
vue(),
vueDevTools(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
},
})
경로 별칭(alias) 설명
@
기호는 src 디렉토리를 가리키도록 Vite에서 설정되어 있습니다.
임포트 시 경로를 간결하게 작성할 수 있습니다.
// 예시:
import MyComponent from '@/components/MyComponent.vue';
Vue Router 설정 파일 수정 (src/router/index.ts)
vue-router 대신 vue-router/auto에서 필요한 함수를 가져옵니다.
import { createRouter, createWebHistory } from 'vue-router/auto'
import { routes } from 'vue-router/auto-routes'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes
})
export default router;
기존에 수동으로 정의한 라우트는 삭제합니다.
플러그인이 자동으로 라우트를 생성하므로 직접 정의할 필요가 없습니다.
디렉토리 이름 변경
TypeScript 타입 오류 해결
tsconfig.json 또는 tsconfig.app.json 파일에서 다음을 추가합니다.
{
"compilerOptions": {
// 기존 설정...
"moduleResolution": "bundler"
},
"include": [
"src/**/*",
"typed-router.d.ts"
]
}
moduleResolution을 bundler로 설정하여 모듈 해석 방식을 지정합니다.
typed-router.d.ts 파일을 include 배열에 추가하여 타입 정보를 포함합니다.
환경 타입 파일 수정 (src/env.d.ts)
파일 상단에 다음을 추가하여 글로벌 타입을 설정합니다.
/// <reference types="vite/client" />
/// <reference types="unplugin-vue-router/client" />
개발 서버 실행 및 타입 파일 생성
터미널에서 개발 서버를 실행합니다.
npm run dev
이때 typed-router.d.ts 파일이 자동으로 생성되며, pages 디렉토리의 라우트 타입 정보를 선언합니다.
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
import VueRouter from 'unplugin-vue-router/vite'
// https://vite.dev/config/
export default defineConfig({
plugins: [
VueRouter(), // Vue 플러그인보다 앞에 위치해야 합니다.
vue(),
vueDevTools(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
},
})
import {createRouter, createWebHistory} from 'vue-router'
import {routes} from "vue-router/auto-routes";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes,
})
export default router
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": [
// ...
"typed-router.d.ts"
],
// ...
"compilerOptions": {
// ...
"moduleResolution": "bundler",
// ...
}
}
/// <reference types="vite/client" />
/// <reference types="unplugin-vue-router/client" />
이번엔 Vue.js 앱에서 파일 기반 라우팅의 개념을 적용하기 위해 코드베이스를 리팩토링합니다. 디렉토리와 파일 이름을 경로에 손쉽게 매핑하고, 동적 및 중첩 경로를 만들고, 랜딩 페이지를 설정하는 방법을 알아봅니다. 또한 훌륭한 개발 경험을 위해 TypeScript를 Vue Router와 통합하는 이점도 다룹니다.
이번엔 파일 기반 라우팅(file-based routing
)을 활용하여 Vue.js 애플리케이션의 라우팅을 더욱 간단하고 효율적으로 관리하는 방법을 배웁니다.
주요 내용은 다음과 같습니다:
파일 및 디렉토리 구조가 라우트 경로를 결정합니다.
특정 경로의 랜딩 페이지를 만들기 위해 index.vue 파일을 사용합니다.
동적 라우트(Dynamic Route) 생성:
캐치올(Catch-All) 라우트 생성:
코드베이스 변경 사항 적용:
타입스크립트와의 통합 및 자동 완성 기능 활용:
<router-link :to="{ name: 'projects-[id]', params: { id: 1 } }">프로젝트 1로 이동</router-link>
ESLint 오류 해결:
rules
섹션에 "vue/multi-word-component-names": 0
을 추가합니다.결론:
lazy loading
)되며, 파일 구조에 따라 자동으로 생성됩니다.src/
├─ pages/
│ ├─ index.vue
│ ├─ projects/
│ │ ├─ index.vue
│ │ ├─ [id].vue
│ │ └─ [...catchAll].vue
│ └─ [...catchAll].vue
<script setup lang="ts">
</script>
<template>
<h1>메인페이지</h1>
<RouterLink to="/projects">프로젝트로 이동</RouterLink>
</template>
<style scoped>
</style>
<script setup lang="ts">
</script>
<template>
<h1>프로젝트 메인 페이지</h1>
<RouterLink :to="{name: '/projects/[id]', params: {id: 1}}">프로젝트 1로 이동</RouterLink>
</template>
<style scoped>
</style>
<script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute('/projects/[id]')
</script>
<template>
<h1>프로젝트 상세 페이지</h1>
<p>프로젝트 ID: {{ route.params.id }}</p>
<RouterLink to="/">홈으로 이동</RouterLink>
</template>
<style scoped>
</style>
<script setup lang="ts">
</script>
<template>
<h1>404 에러 페이지</h1>
<RouterLink to="/projects">프로젝트로 이동</RouterLink>
</template>
<style scoped>
</style>
<script setup lang="ts">
</script>
<template>
<h1>404 프로젝트 에러 페이지</h1>
<RouterLink to="/">홈으로 이동</RouterLink>
</template>
<style scoped>
</style>
import pluginVue from 'eslint-plugin-vue'
import vueTsEslintConfig from '@vue/eslint-config-typescript'
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'
export default [
{
name: 'app/files-to-lint',
files: ['**/*.{ts,mts,tsx,vue}']
},
{
name: 'app/files-to-ignore',
ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**']
},
...pluginVue.configs['flat/essential'],
// rules 위치 // ...pluginVue.configs['flat/essential'] 뒤에 추가
{
rules: {
'vue/multi-word-component-names': 0
}
},
...vueTsEslintConfig(),
skipFormatting
]
프런트엔드를 만드는 것은 이야기의 절반에 불과합니다! 앱의 데이터를 저장하고, 사용자 인증을 처리하고, 모든 것을 원활하게 실행하려면 강력한 백엔드가 필요합니다. 바로 여기서 Supabase가 등장합니다. 이 오픈소스 Firebase 대안은 즉각적인 API, 사용자 인증, 안전한 스토리지, 심지어 실시간 기능까지 갖춘 강력한 PostgreSQL 데이터베이스를 제공합니다. 이 모든 것이 견고한 백엔드를 위한 요소입니다.
Supabase는 사용하기 쉬운 것으로 유명하므로 복잡한 설정을 건너뛰고 정말 중요한 것, 즉 멋진 Vue.js 애플리케이션을 만드는 데 집중할 수 있습니다. 이 수업에서는 Supabase를 함께 살펴보고 앞으로의 작업에 대비할 수 있도록 준비합니다.
이번엔 Vue.js 애플리케이션을 위한 백엔드 솔루션으로 Supabase를 소개합니다. 대규모 애플리케이션을 구축할 때는 프론트엔드뿐만 아니라 데이터 저장, 인증, API 통신 등을 위한 백엔드가 필요합니다.
Supabase는 오픈 소스 Firebase 대안으로, 강력하고 안정적인 PostgreSQL 데이터베이스를 기반으로 합니다. 다음과 같은 주요 기능을 제공합니다:
데이터베이스: 즉시 사용 가능한 API와 함께 제공되는 PostgreSQL 데이터베이스로, 데이터와 쉽게 상호 작용할 수 있습니다.
인증: 회원 가입, 로그인, 사용자 세션 관리를 간편하게 처리할 수 있습니다.
스토리지: 이미지, 문서 등 다양한 파일 유형을 저장할 수 있는 확장 가능하고 안전한 스토리지 솔루션을 제공합니다.
엣지 함수(Edge Functions): 사용자에게 가까운 위치에서 커스텀 백엔드 로직을 실행할 수 있는 서버리스 함수로, 낮은 지연 시간과 높은 성능을 보장합니다.
실시간 기능: 데이터베이스의 변경 사항에 따라 애플리케이션이 실시간으로 업데이트될 수 있도록 실시간 구독 기능을 제공합니다.
Supabase를 선택한 이유로 백엔드 설정에 소요되는 시간을 줄이고, 인증 로직이나 백엔드 구축에 대한 별도의 학습 없이도 쉽게 백엔드를 구성할 수 있다는 점을 강조합니다.
또한, 스키마(Schema), 시드(Seed), 마이그레이션(Migration
)과 같은 용어에 익숙하지 않아도 걱정할 필요 없으며, 모든 과정을 단계별로 안내할 것입니다.
결과적으로 Vue.js 애플리케이션을 위한 견고한 백엔드를 구축하게 될 것입니다.
[사용자 요청]
↓
[Vue.js 프론트엔드 애플리케이션]
↓
[Supabase SDK를 통한 API 호출]
↓
[Supabase 백엔드]
├─ PostgreSQL 데이터베이스 (데이터 저장 및 조회)
├─ 인증 서비스 (회원 가입, 로그인, 세션 관리)
├─ 스토리지 서비스 (파일 업로드 및 관리)
├─ 엣지 함수 (커스텀 백엔드 로직 실행)
└─ 실시간 기능 (데이터 변경 사항 실시간 반영)
↓
[데이터 또는 응답 반환]
↓
[Vue.js 애플리케이션에서 데이터 표시 및 업데이트]
Supabase 클라이언트 설정 (supabaseClient.ts):
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = 'https://your-supabase-url.supabase.co';
const supabaseAnonKey = 'your-anon-key';
export const supabase = createClient(supabaseUrl, supabaseAnonKey);
사용자가 로그인하는 컴포넌트 (Login.vue):
<template>
<div>
<h1>로그인</h1>
<form @submit.prevent="login">
<input v-model="email" type="email" placeholder="이메일" required />
<input v-model="password" type="password" placeholder="비밀번호" required />
<button type="submit">로그인</button>
</form>
<p v-if="error">{{ error }}</p>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { supabase } from '@/supabaseClient';
const email = ref('');
const password = ref('');
const error = ref<string | null>(null);
const login = async () => {
const { user, session, error: loginError } = await supabase.auth.signIn({
email: email.value,
password: password.value,
});
if (loginError) {
error.value = loginError.message;
} else {
error.value = null;
// 로그인 성공 처리 (예: 페이지 이동)
}
};
</script>
<style scoped>
/* 스타일 정의 */
</style>
데이터베이스에서 데이터 가져오기 (Projects.vue):
<template>
<div>
<h1>프로젝트 목록</h1>
<ul>
<li v-for="project in projects" :key="project.id">
{{ project.name }}
</li>
</ul>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { supabase } from '@/supabaseClient';
interface Project {
id: number;
name: string;
}
const projects = ref<Project[]>([]);
onMounted(async () => {
const { data, error } = await supabase
.from<Project>('projects')
.select('*');
if (error) {
console.error('프로젝트를 불러오는 중 오류 발생:', error.message);
} else {
projects.value = data || [];
}
});
</script>
<style scoped>
/* 스타일 정의 */
</style>
이번엔 오픈소스 백엔드 솔루션인 Supabase를 설정하는 방법을 보여드리겠습니다. Supabase 계정, 조직 및 프로젝트를 만드는 방법을 안내해드리겠습니다. 이 프로젝트는 백엔드 명령 센터 역할을 하며 앱의 데이터를 저장하고 사용자 인증을 처리합니다.
Vue.js 앱을 Supabase에 원활하게 연결하기 위해 Supabase JavaScript 클라이언트 라이브러리를 활용하겠습니다. 이 라이브러리는 브릿지 역할을 하여 프런트엔드 Vue.js 앱과 Supabase 백엔드 간의 원활한 통신을 가능하게 합니다.
또한, 보안 문제와 이를 해결하는 방법에 대해서도 나중에 다루겠습니다. 지금은 Supabase를 연결하고 작동 준비를 합시다!
이번엔 Vue.js 애플리케이션을 위한 백엔드 솔루션으로 Supabase를 설정하고 통합하는 과정을 다룹니다. Supabase는 PostgreSQL 기반의 오픈 소스 백엔드 서비스로, 데이터베이스 관리, 인증, 스토리지, 실시간 기능 등을 제공하여 Vue.js 애플리케이션과의 원활한 통합을 지원합니다. 주요 내용은 다음과 같습니다:
Supabase 클라이언트 설정
Supabase 클라이언트 설정 (supabaseClient.ts):
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = 'https://your-supabase-url.supabase.co';
const supabaseAnonKey = 'your-anon-key';
export const supabase = createClient(supabaseUrl, supabaseAnonKey);
Vue.js 애플리케이션과 Supabase 통합
보안 고려사항
[사용자]
↓
[Vue.js 프론트엔드 애플리케이션]
↓
[Supabase SDK를 통한 API 호출]
↓
[Supabase 백엔드]
├─ PostgreSQL 데이터베이스 (데이터 저장 및 조회)
├─ 인증 서비스 (회원 가입, 로그인, 세션 관리)
├─ 스토리지 서비스 (파일 업로드 및 관리)
├─ 엣지 함수 (커스텀 백엔드 로직 실행)
└─ 실시간 기능 (데이터 변경 사항 실시간 반영)
↓
[데이터 또는 응답 반환]
↓
[Vue.js 애플리케이션에서 데이터 표시 및 업데이트]
우리 애플리케이션의 보안은 항상 최우선이어야 합니다. 따라서 민감한 데이터를 보호하고 숨기는 방법을 이해하는 데 시간을 투자해야 합니다.
이번엔 Vue.js와 같은 클라이언트 측 단일 페이지 애플리케이션에서도 환경 변수를 사용하여 민감한 데이터를 숨기는 이점에 대해 논의합니다. 이 접근 방식이 코드를 더 유연하고 안전하게 만들어 다양한 환경에 대한 키를 동적으로 관리하고 민감한 정보를 보호할 수 있는 방법을 알아봅니다.
이는 보안을 향한 한 걸음일 뿐이지만, 앱의 보안을 강화하기 위해 해야 할 일은 아직 많습니다.
이번엔 Vue.js 애플리케이션의 보안을 강화하기 위해 환경 변수(Environment Variables
)를 사용하는 방법을 다룹니다.
환경 변수는 민감한 정보(예: Supabase URL, 익명 키)를 코드에 직접 노출하지 않고 관리할 수 있게 해주어 보안과 유연성을 동시에 제공합니다.
주요 내용은 다음과 같습니다:
환경 변수의 중요성 및 역할:
Vue.js에서 환경 변수 사용 방법:
VITE_
를 붙이면 클라이언트 사이드에서 접근할 수 있습니다.vite env key 정의 방법
VITE_SUPER_SECRET_KEY=MasterclassRules! npm run dev
console.log(import.meta.env.VITE_SUPER_SECRET_KEY)
이번엔 PostgreSQL용 Supabase UI를 사용하여 PostgreSQL 데이터베이스를 설정하고 채우는 것을 시작합니다. 프로젝트에 대한 테이블을 만들고 열을 추가합니다.
supabase dashboard -> database -> tables
table editor
이번엔 PostgreSQL 구문을 사용하여 유형을 정의하고 쿼리를 작성하는 방법을 알아봅니다.
sql editor
table editor
sql editor
이번엔 Supabase CLI를 사용하여 로컬 Supabase 놀이터를 초기화한 다음 라이브 Supabase 프로젝트에 연결합니다. 이렇게 하면 Vue.js 프로젝트를 벗어나지 않고도 원격 데이터베이스를 제어할 수 있습니다.
npm install supabase --save-dev
package.json에 supabase 초기화 명령어 추가
{
"scripts": {
"supabase:init": "supabase init"
}
}
npm run supabase:init
> vue-2024@0.0.0 supabase:init
> supabase init
Generate VS Code settings for Deno? [y/N] n
Generate IntelliJ Settings for Deno? [y/N] n
Finished supabase init.
package.json에 로그인 명령어 추가
{
"scripts": {
"supabase:login": "supabase login"
}
}
npm run supabase:login
> vue-2024@0.0.0 supabase:login
> supabase login
Hello from Supabase! Press Enter to open browser and login automatically.
Here is your login link in case browser did not open https://supabase.com/dashboard/cli/login?session_id=d79f3da9-ea85-4eb7-a744-4f4527d4b149&token_name=cli_aaa@AL01598765.local_1732314487&public_key=04c8a5657869f42e30c515dfeebc28118f9a3a3c28c8eb2bd5370b082965e1e178165b7d26d496038f834734c26cfdf504f1d169267abccb501152413bbbdbecb1
Enter your verification code: xxxxxxx
Token cli_aaa@AL01598765.local_1732314487 created successfully.
You are now logged in. Happy coding!
package.json에 프로젝트 연결 명령어 추가
********************
이 부분은 project id (or project reference){
"scripts": {
"supabase:link": "supabase link --project-ref ********************"
}
}
npm run supabase:link
> vue-2024@0.0.0 supabase:link
> supabase link --project-ref yfuucibtdvvzzxlswqva
WARN: no seed files matched pattern: supabase/seed.sql
Enter your database password (or leave blank to skip):
Finished supabase link.