안정성이 입증되었는지 요즘에는 Vue로 대규모 프로젝트를 많이 하는 추세인것 같습니다. 저도 대규모 프로젝트에 퍼블리셔로 참여하면서 얻은 경험을 기록 차원에서 포스팅을 해보려고 합니다.
Vue는 하나의 파일에 구조(Template)와 구현(javascript), 표현(CSS)을 모두 다 담고 있기 때문에 풀스택(Full Stack) 개발자에게는 더할 나위 없이 편한 구조이지만 대규모 프로젝트 처럼 개발자, 디자이너, 퍼블리셔가 별도로 존재하는 경우에는 상당히 불편할 수 있는 구조를 가지고 있습니다. 개발자가 개발하는 파일을 퍼블리셔도 동일한 파일의 <style>
부분을 작업해야 하기 때문에 아무래도 충돌이 날 확율이 높아지기 때문입니다.
index.vue 예제
<template> <!-- 구조에 대해 구성 --> </template> <script> // 구현에 대한 구성 </script> <style> // 표현에 대한 구성 </style>
이번 포스팅에서는 Vue로 대규모 프로젝트를 진행할 때 퍼블리셔 관점에서 퍼블리셔와 프론트앤드 개발자와 협업을 원활히 하는 방법에 대해서 기술하려고 합니다. 예제는 Vue에서 가장 많이 사용하는 Vuetify
를 사용하여 진행합니다.
Vue 파일과 SCSS(CSS) 분리
위에서 설명했듯이 기본적으로 Vue파일에 스타일을 입히기 위해서는 Vue파일을 열어서 <style></style>
태그 내에서 해당 페이지의 CSS를 작업해야 합니다. 그런데 프론트앤드 개발자가 해당 소스를 같이 동시에 작업했다면 충돌의 우려가 존재할 수 있습니다. 그래서 프로젝트의 각 개별 Vue파일에서는 <style></style>
을 사용하지 않고 별도의 위치에 SCSS폴더를 만들어 여기에서만 작업하도록 하려고 합니다. 저는 그 위치를 assets
으로 잡았습니다.
SCSS란??
SCSS, SASS, LESS, Stylus 같은 것을 CSS 전처리기(CSS Pre-processor)라고 합니다.
css가 그냥 나열식으로 스타일을 구현 한다면 CSS 전처리기는 약간의 프로그램적으로 CSS를 구현한다고 보시면 됩니다.
웹브라우저에서 바로 SCSS를 해석해서 보여주는 것은 아니므로 SCSS로 작업한 파일들을 한번 컴파일해서 CSS로 변환한 후 적용되게 되어 있습니다.
보통node.js
를 기반으로 프로젝트를 개발할 경우 전처리기를 작업하는 도중에 바로바로node.js
가 컴파일을 해 주므로 매우 편하게 작업을 할 수 있습니다.
SCSS는 여러가지 다양하고 많은 기능을 가지고 있지만 가장 핵심적인 기능이라고 하면 CSS에 변수를 적용 할 수 있어서 일괄 수정과 적용이 매우 쉽습니다. 또한 import 기능이 있어서 화면별로 또는 구성별로 나누어서 작업할 수 도 있습니다. 마지막으로 nested 기능이 있어서 css의 브라켓 안에 css를 작업할 수 있어서 구조적으로 css를 작업할 수 있습니다.
자세한 정보는 아래 SCSS 홈페이지를 참조하세요
https://sass-lang.com
모든 SCSS는 이곳에서만 작업할 예정입니다. 프로젝트마다 다르겠지만 저희는 아래와 같이 구성을 했습니다.
SCSS 폴더 구성
- layouts : 웹페이지 전체를 구성하는 레이아웃에 대한 CSS
- pages : 로그인, 매인화면 등등 개별로 존재하는 화면에 대한 CSS
- templates : 여러 개의 Components로 구현된 해당 웹사이트에 특화된 템플릿에 대한 CSS
- components : 버튼, 인풋박스, 컨테이너 등등.. 개별 컴포넌트에 대한 CSS
- commons.scss : 웹사이트에 공통적으로 적용되는 CSS
- _index.scss : 위의 모든 SCSS를 한곳으로 모으는 CSS (단, variables.scss는 여기에 포함되지 않음)
- variables.scss : 모든 SCSS 파일에서 사용할 변수에 대한 정의만 작성(이 파일은
vue.config.js
또는webpack.config.js
에 적용함 )
variables.scss 의 구성
variables.scss는 프로젝트 전체의 scss에 대한 변수의 정의 파일입니다.
/******************************************************************* // 위치 : src/assets/scss/variables.scss // 설명 : 프로젝트 전체에 적용되는 변수에 대해 정의함 // 주의 : 컴포넌트 갯수 만큼 실행되기 때문에 변수에 대해서만 정의해야합니다. (실제 CSS에 대한 적용은 _index.scss에 작성) // 이 파일은 vue.config.js에 설정되면 됨 ********************************************************************/ // vuetify를 사용할 경우 vuetify의 일부 변수를 사용할 수 있음 @import "~vuetify/src/styles/styles.sass"; // Vuetify Globals // Vuetify에 자동으로 오버라이드 됨 /////////////////////////////////////////////// $body-font-family: "Apple SD Gothic Neo", "Malgun Gothic", sans-serif; $border-radius-root: 6px; $font-size-root: 14px; // 사용자 정의 변수 // 여기에 매인컬러, 서브컬러 등의 변수를 설정하면 SCSS 어디에서도 사용할 수 있습니다. ////////////////////////////////////////////// $color-main : #ff3322; $color-sub : #334455; $color-gray-1 : #333333; $color-gray-2 : #666666; $color-gray-3 : #999999;
variables.scss 의 적용위치
node.js로 프로젝트를 개발한다는 전제 입니다.
그럴경우 보통 프로젝트 루트 위치에 webpack.config.js
나 vue.config.js
파일이 있을 텐데 이곳에 아래와 같이 설정을 해 줘야 합니다. 아래 예제는 vue.config.js
에 적용한 모습입니다.
module.exports = { css: { loaderOptions: { scss: { prependData: ` @import "@/assets/scss/variables.scss"; `, }, }, }, };
_index.scss 의 구성
_index.scss는 import외에는 별다른 역활을 하지 않습니다. 그냥 여러군데에 있는 scss파일을 한군데 모으는 역활만 합니다.
/******************************************************************* // 위치 : src/assets/scss/_index.scss // 설명 : 각 요소에 적용될 SCSS를 한곳에 모아서 관리함 // 주의 : 이 파일은 vue.config.js에 설정하면 안되요 ********************************************************************/ // vuetify의 변수를 사용할 경우 적용합니다. vuetify를 사용하지 않는다면 삭제하시면 됩니다. @import "~vuetify/src/styles/main.sass"; // 공통으로 적용되는 스타일 @import "common.scss"; // 4. 컴포넌트별 스타일 // Vuetify에서 제공되는 컴포넌트에 대한 스타일 재정의 /////////////////////////////////////////////// @import "4_components/v-btn.scss"; // 3. 템플릿 스타일 // Vuetify의 여러 컴포넌트를 조합하여 공통적으로 적용되는 스타일 정의 /////////////////////////////////////////////// @import "3_templates/search_grid.scss"; // 2. 페이지 스타일 // 화면 중 특별히 해당 페이지에만 적용되어야 할 경우 스타일 정의 /////////////////////////////////////////////// @import "2_pages/login.scss"; // 1. 레이아웃 스타일 // 전체 레이아웃에 대한 스타일, 경우에 따라 1~2개정도의 소량이 생산될 확율이 높음 /////////////////////////////////////////////// @import "1_layouts/layout1.scss";
_index.scss 의 적용위치
Vuetify를 사용한다고 가정하면…
src > plugins > vuetify.js
에 아래와 같이 코드를 추가해 주면 됩니다.
import Vue from 'vue'; import Vuetify from 'vuetify/lib'; import '@mdi/font/css/materialdesignicons.css'; // 아이콘 불러오기 import '@/assets/scss/_index.scss'; // _index.scss를 한번만 불러오면 자동으로 css로 컴파일 해줌 Vue.use(Vuetify); export default new Vuetify({ icons: { iconfont: 'mdi', }, });
common.scss 의 구성
사용예제로 하나만 보면 아래와 같이 변수와 nested를 활용하는 것을 볼 수 있습니다.
// common.scss .container { width: 100%; .nested-test1 { // nested 사용 font-size: $font-size-root; // 변수 사용 .nested-test2 { // nested 사용 font-size: $font-size-root; // 변수 사용 } } } .row { color: $color-main; // 변수 사용 }
layout1.scss 의 구성
필요할 경우 각각 컴포넌트, 템플릿, 페이지, 레이아웃을 감싸는 Class를 잡아주는 것도 좋을 수 있습니다.
아래 layout1.scss
는 .layout1
이라는 Class로 설정해 봤습니다.
// 1_layouts/layout1.scss .layout1 { width: 100%; .nested-test1 { // nested 사용 font-size: $font-size-root; // 변수 사용 } } .row { color: $color-main; // 변수 사용 }