Tool & Service External

PabloArts website

서비스 홍보나 비지니스에 관한 용도로 회사 웹사이트가 반드시 필요하다고 이야기가 있어와서 디자인 과정에서 오랫동안 시간을 끌어오다가 개발단계로 넘어와서 이런 결과물을 만드는 작업을 하게 되었다.

pabloarts-001.webp

이번 작업은 단순히 몇개의 페이지가 노출되는 홍보용 홈페이지로 끝나는줄 알았지만 작업 과정은 상당히 재미있었고, 개인적으로 단순한 형태의 웹사이트를 만드는데 좋은 전환점이 되어 보이는 기회가 되었다.
단순히 몇페이지를 퍼블리싱으로 만드는것으로 끝나는것이 아니라 디자인 작업을 제외한 모든 프로세스를 다 맡다보니 생각 이상으로 손이 많이가는 일이 되었다.

디자인이 만들어지고 개발시작~

평온하게 회사생활을 보내고 있는데 아무런 예고도 없이 날벼락같이 계속 미뤄왔던 회사 홈페이지를 개발해달라고 미팅에 들어갔다.
미팅에서 만들어진 디자인으로 어떠한 기능으로 사용되고, 어떠한 화면이 들어가는지에 대하여 설명을 듣는데 어짜피 말로 듣는건 흔적만 남을뿐 디테일한 부분은 다 까먹어버리니 그저 멍하게 듣기만 하고 있었다.

이야기를 듣다보니 일부 요소들은 자주 편집을 해야하는 것들이 보인다.
이런 것들은 보통 담당 개발자인 나에게 자꾸 수정해달라고 요청하기 일쑤라 많은 수정이 일어나는 요소들은 직접 수정할 수 있도록 도구로 만들어주는것이 좋을거라 느껴졌다.

pabloarts-002.webp

디자인의 내용은 역시나 페이지 수는 적지만 한 페이지에 내용이 과도하게 몰려있는 모습이다.
처음 접할때는 데스크탑 가장 큰 사이즈로만 만들어져 있었고 반응형 디자인에 아직 고려하지 않은 모습이었다.
웹사이트를 방문하는 사람들의 90% 이상은 모바일 디바이스로 접속하는데 이젠 모바일 사이즈 기준으로 만들어져야 한다고 생각하다보니 모바일에 대하여 소홀한 인상이 안타깝게 느껴진다.

디자인의 요소를 볼때 고개가 갸웃거리는 것들이 좀 보이곤 하는데 디자이너를 믿어야지.. 뭐~

프로젝트 구조에 대하여 구상

미팅이 끝나고 곧장 프로젝트를 만들어서 구성하기 이전에 디자인 화면을 바라보면서 어떻게 만드는게 좋을까 고민했다.
구현에 필요한 기술들을 검증해보고 문서를 읽어보느라 몇일을 보냈다. 곧장 진행하지 못한 가장 큰 이유는 디자인이 개발 작업에 필요한 수준으로 만들어져 있지않고, 여전히 컨텐츠들이 조정될거라는 예감이 들어 급하게 진행시키지 못했다.

pabloarts-003.webp

먼저 만드려는 웹사이트에서 중요한점은 검색엔진에 노출되어야 하는 성격을 가지고 있어야 한다.
효율적으로 개발하면서 서버 스크립트로 HTML 문서를 출력하려면 서버사이드 렌더링(SSR) 으로 환경을 만들어야 한다.
현재 기준으로 리엑트의 next.js 프레임워크가 가장 인기많지만 요즘에는 vue.js로 프로그램을 많이 만들다보니 Nuxt3로 만들기로 결정했다. 현재는 공개된지 얼마안된 수준이지만 vue3를 사용할 수 있으며 괜찮아진 성능으로 운영하기 위하여 한창 개발중인 최신버전으로 개발하는게 좋아보였다.

디자인을 확인할때 몇군데의 컨텐츠가 관리자가 직접 컨텐츠를 등록하고 수정하는 관리자 요소를 만드려면 저장할 데이터베이스가 존재해야하고 인증도 만들어야 한다.
처음에는 백엔드 개발자에게 도움을 요청하여 RestAPI로 통신할 생각이었다.

pabloarts-004.webp

하지만 잘 생각해보니 데이터를 방문객이 등록하는것이 아니고 빈번하게 많은 데이터가 쌓이고 관리할 필요가 없는 것들이다. 그래서 클라이언트 프로젝트 내부에서 처리할 수 있을거라 보였다.
어짜피 인증을 위하여 node.js 영역을 만들고 프로그램을 만들 생각이었다. 간단한 db.json 파일을 만들어서 관리자에서 업데이트하면 db.json 파일을 수정하고, 방문객이 서비스에 접근하면 db.json에서 데이터를 가져와서 내용을 표시하면 어떨까 하는 아이디어가 떠오르니 환경을 어떻게 구성하는지에 대하여 수월하게 그림이 그려졌다.

환경구성

베이스가 되는 환경이 nuxt3라서 가장먼저 설치하고, 공식 사이트에서의 문서들을 열심히 읽어가며 필요한 요소들을 하나씩 구성하면서 hello world 메시지가 적힌 화면을 만들었다.

단순히 페이지만 출력하면 그만인 프로그램을 만든다면 화면만 만들고 끝내겠지만 인증과 내부 데이터를 제어하는 기능을 만들기 위하여 확장 로컬서버를 활용했다. 확장 로컬서버는 특정 주소로 접근할때 node.js 프로그램으로 쿠키와 파일 수정 기능을 사용하게끔 공간을 만든다.
다행히 nuxt3는 파일만 만들어두면 자동으로 라우트를 구성하게끔 기능이 마련되어 있어 편하게 기능을 만들 수 있었다. 올바르게 사용하는 방법인지 확신이 안들지만 그래도 꽤 생각이상으로 편한 방법으로 확장 프로그램을 구현할 수 있었다.

환경 구성은 디자인이 없더라도 진행할 수 있어 처음에 받은 디자인 시안 이미지를 보면서 빈 페이지를 만들고, 필요한 웹글꼴을 설정하고, 기초적으로 필요한 스타일시트, 스크립트 소스들을 구성한다.
처음 개발환경을 구성할때는 현재까지 축척해온 노하우와 리소스들은 대단히 많은 도움이 많이 되었다.

관리자에 관한 영역은 방문객에게 노출되는 영역이 아니기 때문에 디자인이 만들어지기까지 관리자 인증에 관한 기능을 일부 만들어두었다. 진짜 화면과 기능을 만들기 위한 준비작업을 한 수준으로 만들때 디자인이 모두 준비되어서 디자인 검토에 들어갔다.

퍼블리싱

디자인의 결과물을 받아보니 모바일, 데스크탑, 큰 데스크탑 3개의 스크린 사이즈 만들어져 있다. (빠른 작업을 위하여 분명히 2개의 사이즈로 만들어 달라고 했는데..)
빠르게 결과물을 만들기 위해서는 디자이너도 웹 페이지에 대한 이해도가 필요하다는것을 다시한번 깨닫게 된다. 특히 반응형 디자인에서는 더욱..

회사 디자이너의 사정에 의하여 디자이너와의 커뮤니케이션이 대단히 열악한 상태가 되었다. 무엇보다 만든 디자인에 대하여 아무런 메시지가 없다보니 모든 요소들을 추측하거나 일일히 물어봐가면서 UI와 컨텐츠 요소들을 이해해갔다. 이 과정은 대단히 불편했고, 알아서 만들어야하는 패턴이 많이 나왔다.

스타일시트 작성에 대한 변화점

언제나 그렇듯 html 마크업을 진행하고 모바일 사이즈로 스타일시트 코드를 작성했다. 겉으로는 단순해 보이는 레이아웃이지만 막상 건드려보니 구현이 쉽지만은 않았다.

grid

최근 들어서 스타일시트에서 시도해보고 있는 변화점은 레이아웃 구성에서 display: grid를 적극적으로 사용하는 점과 컬러코드를 hex가 아닌 hsl단위로 사용했다는 점이다.

pabloarts-005.webp

그리드 레이아웃은 아직 익숙하지 않아서 버벅댔지만 여태까지 막혔던 레이아웃 구성을 마법같이 해결해낼 수 있었고, 말도 안되는 구성요소들 배치가 가능하게 도움을 주었다. 좀더 많은 기능과 특성들을 알게 된다면 레이아웃 구성에 더욱 강력한 도구가 되어줄거 같았고, 이제 적극적으로 사용해도 좋을것이라는 확신이 커져간다.

먼저 grid-template-columns: auto 1fr형식으로 부모 영역에서 먼저 구조를 지정해둘 수 있고, gap 속성으로 하위요소의 간격을 조절할 수 있어서 간격에 대한 트릭을 사용할 필요가 없어졌다.
무엇보다 display: flex로 사용할적에 사이즈가 넘쳐나는 일이 흔하게 일어났는데 생대적으로 그런면이 덜한 모습을 보이며 부모 요소에서 알아보기 쉬운 모습으로 구조를 만들어 두다보니 미디어쿼리에서 보다적은 코드로 구조를 변경할 수 있다.

마지막으로 세로 영역의 사이즈를 꽉채우는 표현이 가능해진것이 여태까지의 UI 표현의 한계점을 끌어올릴 수 있었다.

hsl

사용하는 컬러 단위는 hex -> rgba -> hsl 순서로 변화해가는데 hsl로 사용하는 이유는 직관적으로 이해할 수 있는 구조 hsl(컬러 채도 명도)라서 각 파트의 수치로 어느정도 세기로 표시되어 있는지 쉽게 알 수 있었다.

background-color: hsl(var(--color, 50 50% 50%) / 75%);

이런 모습으로 컬러만 변수화시키고 속성을 조립하여 투명도만 따로 조절하는것도 가능해졌다.

box-shadow

마지막으로 border -> box-shadow로 외곽선 표현 방식을 변경하게 되었다.
border 속성은 박스모델에서 사이즈가 포함되지만 그림자는 그렇지 않아서 부담없으며 inner 키워드로 박스 바깥이나 안쪽으로 선을 표현할때 결정하기가 명확하다.
결정적으로 WebGL을 적용하고 있어서 애니메이션 표현에서의 성능이 비약적으로 좋아진다. 구글 크롬은 별 차이가 없어 보이지만 예전 사파리 같은 경우는 css 속성에 의해 애니메이션 성능 차이가 크게 일어났다.

컨텐츠 요소의 제작

서비스에서 컨텐츠 데이터가 연동되는 부분이 3,4군데쯤 되는데 pinia로 만든 스토어에다 목업 데이터를 미리 만들어두고 일단 UI를 만들어둔다.
다양한 패턴으로 목업 데이터를 만들어보는일은 항상 깜빡하지만 필요한 일이다. 일부 요소가 없거나 이상한 형태로 내용이 들어가는 일이 일어날때 레이아웃이 깨지는데 꼼꼼한 테스트를 해보지 않으면 다 만들고나서 문제가 일어나기 때문에 최대한 테스트를 해봐야한다.

본문 내용에서의 스타일링이 필요한 요소가 있어 보통 에디터를 넣고 html 코드를 그대로 넣겠지만 html 코드가 그대로 들어가면 변수가 많아 문제가 일어날 가능성이 대단히 커져서 글 본문을 markdown 형식으로 사용하기로 결정했다.
일반적인 텍스트 형식으로 작성하면서 패턴화된 규칙으로 스타일링 할 수 있다. 그리고 일반적인 텍스트를 사용하기에 <textarea/>엘리먼트만으로도 간편하게 에디터 구현이 가능하다. (거창하게 자바스크립트와 스타일시트다 많이 들어있는 에디터 모듈을 붙일 필요가 없어졌다.)

관리자 제작

방문객에게 보이는 화면들을 다 만들고나서 관리자 제작에 들어갔다.
UI 프레임워크를 사용하기에 분량이 너무적고, 디자이너가 UI를 만들어주지 않아서 직접 코드로 UI를 만들다보니 작업 진행이 더디게 흘러갔다. (디자인에 대한 고민을 비우고 코딩을 해야지 막힘없이 진행할 수 있다!)

관리자 화면도 서비스의 톤앤매너를 그대로 활용하여 디자인을 만드는것이 디자인에 관한 고민도 덜하게 되고, 일부 요소들을 재사용할 수 있다.

로그인

먼저 로그인하고 인증하는 플로우에 대하여 구상하고 화면을 심플하게 만들었다.
그저 비밀번호 하나만으로 인증하면 되기에 계정에 대한 구성은 필요없기에 인증에 관한 정보는 단순하다. 하지만 보안이 대하여 더욱 주의가 필요하다.

pabloarts-006.webp

쿠키와 토큰이라는 것들을 사용하다보니 좀더 복잡한 구조로 인증을 거치다보니 시간을 들여서 인증 기능을 만들게 되었다. node.js로 프로그램을 만들어본 경험이 적어서 문서와 검색을 도움을 받아가면서 패스워드 관련 기능과 쿠키 기능들을 만들었다.

인증 성공해서 만들어지는 토큰을 스토어에 담아서 이후 이동되는 화면에서 사용하면서 낭비되는 요청을 최소화했다.

컨텐츠 관리

관리자와 노출되는 페이지에서 데이터가 연동되는데 스토어는 중요한 역할을 담당했다.

nuxt3를 설치하고 스토어 구성에 대하여 알아보면서 항상 사용하던 vuex는 더이상 개발에 집중을 안하는 인상을 받았다. (영어를 못하기 때문에 번역기로 돌린 문장의 뉘양스로 짐작뿐..)

pabloarts-007.webp

대안으로 나온게 Pinia인데 새로 시작해야겠구나.. 라고 생각하면서 작업에 시간이 더 걸릴거라는 불안감이 올라왔다.
하지만 타입스크립트 지원과 nuxt3 호환성을 고려해서 Pinia 사용은 피할 수 없어서 프로젝트에 적용하기 위하여 문서를 확인해보고 적용해보는데 생각 이상으로 좋았다.
mutations 과정이 빠져있으니 좀더 심플해지고 vuex에서도 가능했지만 여러개의 스토어 모듈을 만들어서 역할을 그룹지어 파일을 만들어 컴포넌트에서 필요한 요소만 불러서 사용할 수 있게 되었다. 아무래도 스토어 설정이 심플하다보니 부담없이 여러개의 스토어를 만들어 사용할 수 있었다.

단순히 state로 저장해서 꺼내 쓰는것뿐만 아니라 actionsgetters를 통하여 캡슐 내부에서 기능을 확장시켜 사용할 수 있다는점이 매력적이다. 물론 다른 상태관리 라이브러리도 모두 사용 가능하다! 하지만 Pinia가 더욱 인상적이라고 느껴진 이유는 스토어를 구현하는데 코드 가독성이 좋다는 점과 사용하기 편리하다는점이 여태까지 이걸 왜 사용을 안했지.. 라는 생각이 들게 만든다.

pabloarts-008-001.webp

pabloarts-008-002.webp

pabloarts-008-003.webp

pabloarts-008-004.webp

스토어를 결정하니 컨텐츠의 데이터를 관리하고 문제에 있어서 기능적으로 막혔던 문제를 수월하게 풀 수 있었다. 하나씩 동작하는것에 대하여 일일히 편집해서 업데이트 하는 방식보다 가장 끝자락에 있는 UI로 데이터를 계속 흘리는 형태로 유지하고 데이터를 변경하면 UI가 그대로 변하게 되는 형태로 구성하면 복잡한 UI라도 별도로 컨트롤러를 만들어 조정할 필요가 없어진다.
UI로 데이터 조작에 관해서 많은 생각을 바꿔야 수월하게 구현할 수 있었고, 여태까지 구현해본적이 없는 방식이라서 처음 아이디어를 떠올렸을때 대단히 흥분했다.

생각대로 구현이 되고 툴이 작동되어서 무척이나 기뻤다.
3뎁스까지 구성된 데이터도 있어서 과연 쉽게 구현할 수 있을까.. 하는 불안감이 굉장히 강했지만 허탈할 정도로 쉽게 구현되어서 사기같은 기분이 들 정도다. (이렇게 개발이 쉬워졌습니다. ㅠ)

UI로 데이터를 조작해서 저장을 node.js 영역에 요청하면 json 파일이 업데이트 하도록 만들고 수정된 json 데이터로 서비스에서 적용된다.
이런 데이터 구조는 보통 데이터베이스를 통했는데 이번에는 파일로 관리하니 프로젝트의 구성이 단순해지니 마음에 들었다.

다국어

다 만든 시점에서 다국어 지원을 한다는 말을 들어서 잠시 멘붕이 와서 잠시 고민했다가 일단 현재 한국어 버전만을 집중해서 마무리 짓고 다국어 기능은 다음 버전으로 나누어 생각하기로 했다.

제대로 다국어 처리를 작업해보는게 이번이 두번째다.
저번에 경험과 리서치를 통하여 어떻게 구현해야할지 고민을 해보는 시간을 가졌다. 먼저 큰 과제는 nuxt3에서 다국어 처리 모듈이 잘 작동하냐인데 다행히도 @intlify/nuxt3 모듈을 도움받아 기능 테스트에 성공했다.
이번에는 일반적인 내용에는 베트남어가 나오다가 데이터로 관리되는 요소에서는 한국어가 나온다면 뜬금없는 상황이 나오기 때문에 사이트 관리자 입장에서는 피곤하겠지만 데이터를 언어별로 분리하기로 했다. 특정 지역에 따라 내용이 2개가 되거나 4개가 될 수 있기 때문이다.

pabloarts-009.webp

기초적인 기능을 구현하고 언어가 변할때 쿠키로 언어를 저장하도록 기능을 만들었다.
html 코드가 만들어지기 전에 어떤 언어로 사용하는지 알아야 하기 때문에 백엔드에서 알아볼 수 있는 적절한 위치가 백엔드 영역의 쿠키여서 언어를 변경할때 업데이트하고 새로고침할때 쿠키에 저장된 언어어로 내용이 나오도록 만들었다.

기초적인 기능을 만들고 언어파일의 포맷을 완성하고 개발 매니저에게 포맷을 전달해주고 번역을 맡긴걸 적용해보고 조정해보면서 완성도를 높여간다.

마무리

관리자까지 다 만들고 데이터를 편집하고 적용하는걸 확인해보니 얼추 완성되었다는걸 느끼고 다국어 작업을 끝내니 정말 끝이라는걸 실감하게 된다.

주요한 부분을 다 만든 시점에 마지막으로 운영하는데 필요한 유틸리티 툴들을 만들어 보았다.
처음 설치할때 사용하는 셋업툴, 비밀번호를 검사하거나 변경하는 툴 등등.. 서비스를 운영하는데 필요한 기능들이 무엇이 있을까 생각해보고 하나씩 만들어 보았다.
커멘드라인 툴을 만들때 쉘 스크립트나 파이썬이나 node.js나 별반 차이없음을 깨닫는다.

웹 사이트의 규모가 큰편이 아니라서 부담가질 필요없이 운영하고 있는 서버에 바로 적용하고 컨텐츠 관리자에게 관리자 사용법을 알려주고 마무리 지었다.

겉으로 보이는 작업양은 적었지만 새로운 방식의 기능을 적용해보고 디자인을 제외한 모든 포지션을 담당하다보니 자연스럽게 손이 많이갔지만 상당히 의미있고 보람이 느껴지는 프로젝트가 되었다.