안녕하세요. 사람인HR IT연구소 UI개발2팀 정영환입니다.
등용문S 프로젝트를 진행하면서 겪은 프론트엔드 개발자로서의 개발 경험을 공유하고자 합니다.

등용문S은 HR솔루션으로써 이력서 접수, 심사, 발표를 한번에 관리하는 기업 맞춤형 채용관리 시스템입니다. 기존 등용문 3.0과 5.0의 결합체이며, 기존의 채용홈페이지와 채용관리자를 새롭게 구축 하였습니다.
또한, 기업관리자가 쉽게 홈페이지를 커스터마이징 할 수 있도록 채용홈페이지 빌더도 업그레이드 되었습니다.

여기서 UI개발팀은 채용홈페이지 UI/UX와 채용홈페이지 관리자 빌더를 구축하게 되었습니다.


목차

Sprint를 활용한 Agile
기획을 그리다.
vuejs 와 vuetify
페이지 생성의 변화 (feat. vue-router)
마침표.



Sprint를 활용한 Agile

단계별 리뷰 → 스프린트 리뷰 → 다음 스프린트 준비 → 스프린트 시작

1) 단계별 리뷰

UI개발팀 내부 리뷰를 통하여 구현된 화면을 보면서 진행 현황 및 이슈를 공유하고 토론하여 보완사항을 파악하는 단계입니다.
단계별 리뷰는 스프린트 기간 내에 담당자의 필요에 의하여 언제든 리뷰를 요청 할 수 있습니다. 단계별 리뷰를 통하여 스프린트 리뷰 시에 나올 크리티컬한 요소를 최소화 하고 작업자 간의 코드를 통일화 하는 단계입니다.

2) 스프린트 리뷰

각자 할당 된 업무에 대한 리뷰를 전체 인원(등용문S UI개발 담당자)을 대상으로 실시 하여 할당된 업무를 마무리 하고 리뷰에서 나온 수정사항들은 Sprint 일정에 맞춰 완료 처리하는게 목표입니다. 만약, 크리티컬한 이슈가 있거나 수정이 있을 때는 해당 스프린트 일자를 추가 하거나 다음 스프린트로 이관합니다.

3) 다음 스프린트 준비

말그대로 다음 스프린트 업무를 할당하여 준비하는 단계입니다.

4) 스프린트 시작

할당된 업무를 진행합니다.


위와 같이 등용문S 프로젝트를 Sprint를 이용한 Agile 방식으로 진행하였습니다.

스프린트의 주기는 1주~2주 가량이었으며, 담당자에 따라 추가적으로 스프린트 기간이 연장되곤했습니다.



기획을 그리다.

스토리보드(화면명세서)를 그리다.
디자인을 생각하다.
UI개발 주도적으로 서비스를 구축한다.

UI개발팀은 등용문S 프로젝트를 진행하면서 프론트엔드개발자로 거듭나기 위한 주도적 개발을 시작합니다.

1) 등용문 운영 담당자와 리뷰

처음 운영 담당자에게 등용문 3.0과 5.0을 기반으로 IA구조와 기능명세서를 요청하였고 전달받은 문서에서 삭제 및 추가해야 할 요소들을 정리하는 작업을 진행했습니다. 이 과정에서 운영 담당자와 수차례 리뷰를 진행하였고 이 후 스토리보드(화면명세서)를 작성하게 됩니다. 이때 리뷰에서 나온 이야기들은 모두 스토리보드에 들어가야 할 정책들이자 앞으로의 작업 key point 입니다.

2) UI개발자 스토리보드 작성 업무분담

서비스 전체 IA를 구성하고 스토리보드 레이아웃을 구성합니다.

  • 상단 : 서비스 구분 (페이지명)
  • 화면단 : 화면을 구성할 요소 (도형, 이미지)
  • description : 기능 상세 (정책과도 같은 중요한 부분)
  • 하단 : 페이지 번호 및 로고

4명의 작업자가 각자의 경험을 담아 스토리보드를 작성한 후 공통으로 가져가야 할 요소를 정의하고 공유합니다.

  • form 요소
  • 버튼 요소
  • 테이블 요소
  • 텍스트 스타일


화면명세서

3) 개별 기획서 작성 후 리뷰 그리고 feedback

각 담당자들이 작성한 페이지를 공유하고 리뷰를 통해 수정사항을 파악합니다.

  • 탭box 모양
  • 날짜 표시 방식
  • 리스트 없을때 안내문구 통일
  • placeholder 문구 통일

리뷰에서 나온 수정사항을 수정하고 마무리 후 운영 담당자에게 공유하고 feedback을 기다립니다.

  • 여기서 feedback은 프로젝트 진행과정에서 상당히 중요한 부분을 차지합니다.
  • 최초 운영 담당자와의 리뷰에서 나온 정책들을 녹여놓은 스토리보드이고 앞으로 개발 작업의 기준이 되므로 꼼꼼히 체크해야 합니다.
  • 여기서 놓친 정책은 추후 나비효과가 되어 겉잡을 수 없는 일이 될 수 있습니다.

feedback에 따른 수정 및 변경사항을 고친 후 스토리보드를 마무리합니다.

4) 화면개발

“디자인을 생각하다.”
디자인이 필요한 페이지(메인, 템플릿, 메일폼 등)를 제외하고 기획서를 기반으로 개발을 진행했습니다.

처음 전체 컴퍼넌트를 제작하기에 시간적 여유가 없었기 때문에 Vue UI 라이브러리를 선정하여 부분적으로 컴퍼넌트를 사용하기로 결정하고, 선정된 Vue UI 라이브러리(vuetify)를 이용하여 form요소 및 버튼, 아이콘 등을 가이드화 하여 작업자들 간 페이지 통일성을 유지하였습니다.

  • v-btn
  • v-icon
  • v-pagination
  • v-tabs
  • v-expansion-panels
  • form 요소들


공통 컴포넌트 가이드



vuejs 와 vuetify

1) 디렉토리 구조

최초 PC와 M의 디렉토리 구조를 설계할때 반응형을 고려하지 않았고 별도의 URL 구조로 구성을 고려했습니다. 추후 운영관리에서 PC와 M 사이에서 사이드이펙트를 최소화 하고자 폴더를 완전 분리하여 디렉토리 구조를 생성한 것 입니다.

resources
 ├─ js
 │  ├─ mobile                   // 모바일(pc와 내부 구조 동일)
 │  ├─ pc
 │  │  ├─ components            // 공통 컴퍼넌트
 │  │  │  └─ ...
 │  │  └─ pages                 // 서비스별 페이지
 │  │
 │  ├─ plugin                   // 플러그인
 │  │  └─ ...
 │  │      
 │  ├─ app.js                   // js build point (PC)
 │  └─ m-app.js                 // js build point (M)
 │      
 ├─ sass
 │  ├─ mobile                   // 모바일(pc와 내부 구조 동일)
 │  ├─ pc
 │  │  ├─ component             // 공통 style
 │  │  │  └─ ...
 │  │  ├─ layout                // layout style
 │  │  │  └─ ...
 │  │  ├─ page                  // 서비스별 style
 │  │  │  └─ ...
 │  │  └─ util                  // mixin, variables
 │  │     └─ ...
 │  │      
 │  └─ app.scss                 // scss build point (PC)
 │  └─ m-app.scss               // scss build point (M)
 │      
 └─ views                       // php file

2) 네이밍 규칙

HTML 태그와 충돌을 피하기 위하여 아래와 같이 합성어를 사용하였습니다.

file name : 파스칼케이스

ApplyConfirm.vue

In a .vue file name : 파스칼케이스

export default {
	name: ApplyConfirm
}

component Tag : 케밥케이스

<apply-confirm></apply-confirm>

👉 HTML에서는 대소문자를 구별하지 않기 때문에 케밥형식으로 변경하여 작성합니다.

3) 가상데이터 연동

홈페이지 builder 및 관리자 데이터 연동을 위하여 가상으로 json 데이터를 만들어 axios를 통해 연동하고 화면개발을 시작하였습니다.
초기 홈페이지 builder 관련 데이터는 각 페이지별로 작성하여 작업하였습니다. 개발담당자 각자가 필요에 의해서 가상데이터를 만들어서 사용하였는데, 개발 중간에 여러개로 쪼개진 데이터를 하나의 json에 담아 화면구성을 하는 것이 효율적이라 판단하여 이후 관리자에서 builder 데이터를 만들때 하나의 가상 데이터로 구축하여 구성하였습니다.

[수정 전]

{
  "bi_url" : "//www.url정보",
  "menu" : [...]
}

menu.json

{
  "templateInfo" : [...],
  "edit" : [...],
  "list" : [...]
}

template.json

[수정 후]

{
  "builderMain": {
    "header": {...},
    "menu": {...},          // 수정  menu.json
    "visual": {...},
    "linkMenu": {...},
    "boardList" : {...}
  },
  "builderSub": {...},
  "builderTemplate": {...}  // 수정  template.json 모음
}

builder.json

4) vuetify - https://vuetify.com

브라우저 호환성

  • Chromium(Chrome, Edge Insider)
  • Firefox
  • Edge
  • Safari 10+
  • IE11 /Safari 9 (polyfill로 지원)
  • IE9 / IE10 (미지원)
  • 등용문S의 브라우저 호환성 정책은 IE10+ 이므로 IE10+ 지원을 위해 Laravel Mix 의 webpackConfig 에서 ‘node_modules/vuetify/lib’ 을 트랜스파일되도록 모듈에 포함시켰습니다.

설치

$ yarn add vuetify

플러그인 파일(vuetify.js)

import Vue from 'vue';
import vuetify from './plugins/vuetify';

Vue.use(Vuetify);

const opts = {};

export default new Vuetify(opts)

app.js

import vuetify from './plugins/vuetify'

const app = new Vue({
	vuetify,
})

👉 vuetify issue note
오류사항 : IE11 에서 v-menu 사용시 안에 있는 item 영역의 넓이가 제대로 설정되지 않아 글씨가 짤림

해결방안 : v-list-item 의 display 속성을 flex에서 block 형태로 변경
참고URL : https://github.com/vuetifyjs/vuetify/issues/8338

오류사항 : IE11 에서 select 선택 후 다른 input form 이나 document 클릭 시 선택된 options 값이 사라지는 현상

해결방안 : 
	- placeholder 방식에서 label 방식으로 변경
	- :placeholder = "[v-model data] ? undefined : '텍스트'"
참고URL : https://github.com/vuetifyjs/vuetify/issues/5225



개발 진행중인 홈페이지

페이지 생성의 변화 (feat. vue-router)

최초 UI/UX 페이지를 생성할때 component 호출방식을 사용하여 페이지를 구성하였고, 이후 vue-router를 사용하여 재구성하였습니다.

1) component 호출 방식

a. blade php 생성

@extends('layouts.app')

@section('title', __('Vuetify 예제'))

@section('content')
	// pagename 은 component 파일 명과 동일 (영문 첫 자는 소문자.)
	<sub-layout pagename="applyForm"></sub-layout>
@endsection

b. 페이지 컴포넌트 생성

c. 페이지 컴포넌트 등록 : app.js

// 레이아웃
Vue.component('sub-layout', require('./components/layout/SubLayout').default);

// 채용관리
Vue.component('apply-form', require('./components/application/ApplyForm.vue').default);

d. LayoutContent.vue 에 props 비교

<template>
	<div>
		<div id="wrap_content">
			// props 비교 후 노출 여부 판단
			<apply-form v-if="this.pagename='apply'"></apply-form>
		</div>
	</div>
</template>

e. Web Routes 페이지 등록

// 채용관리
Route::get('/application/{page?}', function ($page = null) {
	return view("application.$page");
})->name('application');

2) vue-router 변경

a. 페이지 컴포넌트 생성
b. 페이지 컴포넌트 등록 : app.js

// 레이아웃
Vue.component('sub-layout', require('./components/layout/SubLayout').default);

// 채용관리
Vue.component('apply-form', require('./components/application/ApplyForm.vue').default);

c. routes 등록

// UI 개발 페이지
const SubLayout = () => import(/* webpackChunkName: "js/pc" */ "../../js/pc/components/layout/SubLayout");
const ApplyForm = () => import(/* webpackChunkName: "js/application" */ '../../js/pc/pages/application/ApplyForm');

const routes = [
	layout('/', SubLayout, [
		route('application/apply-form', ApplyForm, {name:'ApplyForm', meta: '입사지원서 작성'}),
		route('*', FallbackLayout),
	])
]


마침표.

진행하는 내내 가장 많이 했던 것들이 ‘만들고. 리뷰하고. 수정하고.’ 였던 것 같습니다.
등용문S 프로젝트는 기존의 UI/UX개발을 벗어나 기획(화면명세서)을 진행하고, 디자인(vuetify)을 생각해야 했고, 새로운 javascript 프레임워크(vuejs)를 사용하여 진행한 값진 프로젝트입니다.

마지막으로 함께 개발에 참여해 준 UI개발팀 오현중, 김단희, 임해빈 연구원님 수고하셨습니다.