본문 바로가기
반응형

안정성이 입증되었는지 요즘에는 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.jsvue.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; // 변수 사용 }

UX 공작소

UX와 UI에 관해 내가 알게된 다양한 이야기를 공유해요~