LINE에서 하루 만에 정적 웹 페이지 개발해서 배포하는 방법

LINE DEVELOPER DAY 2020에서 편해걸 님이 발표하신 How to quickly develop static pages in LINE 세션 내용을 옮긴 글입니다.

안녕하세요. 이번 글에서는 정적(static) 웹 페이지를 빠르게 개발하는 방법에 대해서 이야기하려고 합니다. 

 

개발에서 빌드, 배포까지 하루 만에! 

시작하기에 앞서 여러분들께 한 가지 질문을 드리겠습니다. 아래 보이는 화면은 LINE에서 최근에 진행했던 이벤트 페이지입니다. 언뜻 보시기에 이 페이지를 만드는 데 대략 얼마나 걸렸을 것이라고 예상하시나요?

같은 질문을 주위 개발자분들에게도 물어보았습니다. 대부분 3일에서 5일 정도 걸릴 것 같다고 답변해 주셨는데요. 실제로 이 이벤트 페이지를 개발한 엔지니어는 단 하루 만에 개발에서 빌드, 배포까지 마무리하셨습니다.

어떻게 이렇게 짧은 시간에 서비스를 개발하고 론칭할 수 있었을까요? 이번 글에서는 정적 웹 페이지를 이렇게 빠르게 개발하기 위해서 우리가 고민했던 내용을 하나하나 짚어볼 예정인데요. 먼저 이번 글을 이해하기 위해 필요한 배경지식을 간단하게 소개한 뒤 정적 웹 페이지를 만들면서 직면했던 문제들을 하나하나 들여다보고 이 문제들을 어떻게 개선할 수 있었는지에 대해서 이야기하겠습니다.

 

동적? 정적?

이번 글에서는 웹 페이지에 대한 개념을 비중 있게 다루기 때문에 웹 페이지에 대해 간략하게 짚고 넘어가겠습니다.

 

동적 웹 페이지

오늘날 여러분께서 많이 접하게 되는 웹 페이지는 많은 콘텐츠가 실시간으로 업데이트되는 웹 페이지입니다. 여기에 개인화 기능까지 추가되어 있다면 같은 웹 페이지라도 사용자마다 다른 화면이 보이는 경우도 많을 것입니다. 지금 아래 화면에 보이는 뉴스 페이지도 시간에 따라서 혹은 사용자의 관심사에 따라서 각 개인마다 다른 뉴스가 보일 텐데요. 이런 웹 페이지를 동적 웹 페이지라고 부릅니다.

동적 웹 페이지는 데이터를 가공해 각 사용자에게 맞춤형으로 화면을 보여주기 때문에 데이터베이스와 웹 애플리케이션 서버가 필요합니다. 클라이언트에서 요청을 보내면 웹 애플리케이션 서버에서 데이터베이스를 조회하거나 외부 서버에서 데이터를 읽어와 HTML을 렌더링합니다.

이렇게 서버가 동적으로 HTML을 생성하는 개념을 ‘서버 사이드 렌더링(server side rendering)’이라고 부릅니다.

동적 웹 페이지는 동적인 콘텐츠를 보여줄 수 있다는 장점이 있으나 매우 복잡하고 용량이 크며 동적 데이터를 보여주기 때문에 캐시를 사용하기도 쉽지 않습니다. 따라서 내용이 자주 바뀌지 않는 콘텐츠를 보여주는 서비스에는 적합하지 않다고 볼 수 있습니다.

 

정적 웹 페이지

동적 웹 페이지와는 달리 내용이 자주 바뀌지 않는 정적 콘텐츠를 보여줄 때는 바로 오늘의 주제인 정적 웹 페이지를 활용합니다. ‘플랫(flat) 페이지’ 혹은 ‘스테이셔너리(stationary) 페이지’라고도 부르는 이 개념은 최초의 웹 페이지를 생각하면 이해하기 쉽습니다.

정적 웹 페이지는 저장된 그대로 사용자에게 전달하는 웹 페이지로서 정적인 콘텐츠를 전달하기 때문에 별도의 웹 애플리케이션 서버가 필요하지 않습니다.

쉽게 말해서 클라이언트가 요청을 보내면 다음과 같이 서버에 저장되어 있는 HTML을 그대로 보내주는 구조입니다.

다소 원시적으로 보이는 개념이지만 단순하기 때문에 얻을 수 있는 장점이 있습니다. 첫 번째로 동적인 요소가 없기 때문에 데이터베이스가 필요 없어서 환경을 구성하고 구축하기가 굉장히 쉽습니다. 두 번째로 단순하게 문서로만 구성되므로 HTML만 전송하면 되기 때문에 서버 간 통신이 거의 없어 전송 속도가 매우 빠릅니다. 세 번째로 동적 웹 페이지에서는 의미 있는 첫 화면, 즉 First Meaningful Paint를 보기까지 오래 걸리는 반면에 정적 웹 페이지에서는 HTML을 바로 보내주기 때문에 의미 있는 첫 화면을 굉장히 빨리 볼 수 있습니다. 마지막으로 동적인 데이터를 다루는 동적 웹 페이지는 데이터가 수시로 바뀌기 때문에 데이터를 캐시하는데 보수적일 수밖에 없지만 정적 웹 페이지에서는 정적인 데이터를 다루다 보니 캐시를 매우 공격적으로 활용할 수 있습니다.

따라서 정적 웹 페이지는 정적인 데이터를 빠르게 보여주는 서비스에 많이 사용합니다. LINE에서도 브랜드 사이트나 이벤트 페이지 등을 만들 때와 같은 용도로 다양한 서비스에서 많이 사용하고 있으며, 프로젝트가 많아지면서 정적 웹 페이지에 대한 수요도 점점 증가하고 있습니다.

 

문제는 ‘반복’

여기까지 잘 따라오셨다면 그럼 지금 도대체 무엇이 문제인지 의문이 드시는 분들이 계실 겁니다. 여기서 키워드는 바로 반복입니다. 앞에서 말씀드렸듯 정적 웹 페이지에 대한 수요는 꾸준히 늘어나고 있습니다. 제품 사이트와 같이 규모가 큰 페이지에서부터 이벤트나 약관 같은 간단한 페이지까지 종류도 매우 다양합니다. 반면 페이지를 만들 개발자와 시간은 굉장히 한정되어 있고 이에 따라 필연적으로 리소스 부족 문제가 발생하는데요. 이를 해결하기 위해 더 적은 인원으로 더 많은 페이지를 만들어 낼 수는 없는 것일까요? 

 

정적 웹 페이지 개발 과정

먼저 우리는 문제를 명확하게 하기 위해서 정적 웹 페이지를 개발하는 과정을 들여다보았습니다.

정적 웹 페이지의 구조는 단순하지만 만드는 과정은 전혀 단순하지 않습니다. 개발 환경을 설정하고 디자인을 구현하는 마크업 작업을 해야 하고 필요한 인터렉션이 있다면 JavaScript 작업도 추가로 필요합니다. 이와 같은 과정을 거쳐 프런트엔드 영역에서 소스 코드를 작성하고 나면 작성한 소스 코드를 그대로 배포하면 되느냐, 그렇지 않습니다. HTML과 CSS, JavaScript는 최적화를 위해 난독화 또는 미니파이(minify) 과정을 거칩니다. 만약 다국어 처리가 필요하다면 템플릿을 치환하는 과정도 필요하겠죠. 이런 부분이 빌드 영역에 속합니다. 마지막으로 빌드한 번들을 배포하는 과정까지 개발자가 담당하는데요. 배포할 웹 서버를 설정해야 하고, TLS(Transport Layer Security) 지원 작업도 필요하겠죠. 도메인을 설정하거나 서비스 특성에 맞게 캐싱하는 전략도 개발자가 세워야 합니다.

저 역시 수많은 정적 웹 페이지를 만들면서 위와 같은 과정을 많이 겪었는데요. 자세히 들여다보면 생각보다 반복되는 작업이 굉장히 많습니다. 반복된다는 것은 형태가 정해져 있다는 것이고, 이는 곧 자동화할 수 있다는 것을 의미합니다. 이런 반복 과정을 체계화해서 자동화하면 적은 자원으로 많은 정적 웹 페이지를 만들 수 있지 않을까요? 

 

LandPress 프로젝트 – 반복 작업 줄이기!

먼저 문제를 명확하게 하기 위해서 ‘반복 작업을 자동화해 줄여 나가는 것’을 비전으로 정했는데요. 이 비전에 따라 세 가지목표를 적어 보았습니다.

첫 번째는 앞에서 언급했던 반복되는 작업들을 자동화해서 개발자들의 노력과 시간을 줄이는 것입니다. 두 번째는 단축한 프로세스를 바탕으로 필요한 태스크를 잘 정리해서 정형화하는 작업을 진행하기로 했습니다. 이렇게 절차를 정형화해 놓으면 누가 작업을 하든 헤매지 않고 이른바 ‘삽질하는 시간’을 줄여서 빠르게 개발할 수 있도록 도와줄 수 있을 것이라고 생각했습니다. 마지막 목표는 보다 효율적인 커뮤니케이션입니다. 실제 서비스를 론칭할 때는 개발자뿐 아니라 기획자와 디자이너, 프로젝트 매니저 등 다양한 사람들과 함께 협업하게 되는데요. 이 과정에서 서로 커뮤니케이션하는 비용이 생각보다 굉장히 많이 듭니다. 이때 표준 포맷을 이용해서 협업 부서 간 불필요한 커뮤니케이션을 최소화하면 보다 빠르게 서비스를 만들 수 있을 것이라고 생각했습니다.

LandPress

목표를 명확하게 정리했으니 프로젝트에 이름도 붙여야겠죠. 내부적으로 공모도 하면서 이런저런 이름을 많이 고민해 봤는데요. 정적 웹 페이지를 빠르게 만들어 낼 수 있다는 의미를 담고 있으면서 주위에서 많이 사용하는 용어를 차용해 ‘LandPress’라고 이름을 붙였습니다. 자, 이제 이름까지 정했으니 앞에서 정리한 표를 다시 한 번 보겠습니다.

표를 보며 자동화할 수 있는 부분을 살펴봤는데요. 아무래도 직접 만들 때 번거롭고 귀찮았던 부분이 제일 먼저 눈에 들어왔습니다. 바로 개발 환경을 설정하는 과정과 번들링하는 과정이었습니다.

 

개발 환경 설정과 번들링 자동화

이 문제를 어떤 플랫폼으로 해결할 것인가를 굉장히 많이 고민했습니다. 처음 만드는 것이기도 했고, PoC(Proof of Concept) 단계로 생각했기 때문에 ‘가볍고 익숙한 도구로 만들어 보자’라는 생각이 들어서 CLI(Command Line Interface)로 만들었습니다. CLI라는 용어를 처음 들어보신 분도 계실 텐데요. 간단히 말해서 터미널을 이용해서 사용자와 컴퓨터가 상호작용하는 방식을 의미합니다. 사용자가 키보드를 통해 작업 명령을 문자열 형태로 입력하고 출력 역시 문자열 형태로 나오는 구조입니다.

개발한 도구의 기능을 정리하면 다음과 같습니다.

  • ES5 코드를 ES6 코드로 변경해 주는 트랜스파일 기능
  • 코드 보안을 위해 코드를 암호화하는 난독화 기능
  • 코드 크기를 줄여주는 미니파이 기능
  • 다국어로 치환해 정적 HTML을 생성해 주는 기능
  • 간단하게 배포할 수 있는 기능
    • 스토리지를 직접 세팅하고 배포하는 번거로운 작업을 피할 수 있도록 CDN과 연동해 명령어 하나로 원하는 서버에 배포할 수 있도록 설계
  • 로컬 환경 개발을 위한 서버 제공
    • 개발하면서 변경 사항을 바로 확인할 수 있도록 핫 모듈 리플레이스먼트(Hot Module Replacement) 기능을 함께 제공

CLI는 프런트엔드 개발자가 많이 사용하는 Node.js 런타임을 이용해 사내 프라이빗 NPM을 통해 설치할 수 있도록 개발했습니다.

명령어 콘셉트는 아주 심플하게 잡았습니다.

프로젝트를 생성하고 싶다면 init 명령어를 사용해 프로젝트를 스캐폴딩(scaffolding)할 수 있습니다. 개발 서버를 실행하고 싶다면 dev 명령어를 사용해 핫 모듈 리플레이스먼트가 적용된 개발 웹 서버를 실행할 수 있습니다. 가장 귀찮았던 빌드 과정은 build 명령어만 사용하면 자동으로 번들링될 수 있도록 설계했습니다. 이쯤 되면 배포가 궁금하실 텐데요. 배포는 사내에서 Verda라고 부르는 클라우드 플랫폼을 통해서 이루어집니다. Verda에는 정적 파일을 호스팅하기 위한 오브젝트 스토리지가 있습니다. 번들링된 파일은 CLI를 통해 Verda 오브젝트 스토리지로 전송된 후 호스팅됩니다.

CLI를 통해 개발 환경 설정과 번거로운 번들링 과정을 자동화했습니다. 하지만 CLI는 로컬에서 빌드와 배포를 진행하기 때문에 사용자 환경에 쉽게 영향 받고 배포 이력을 관리하는 것도 용이하지 않습니다.

무엇보다 프로덕션 번들을 로컬에서 빌드한다면 사용자의 개발 환경에 영향을 받는다는 문제가 가장 컸습니다. 다수의 프로젝트를 동시에 관리하기에도 한계가 있었습니다. 따라서 저희는 보다 편하게 개발할 수 있는 방법을 고민했는데요. 그 결과가 바로 대시보드입니다.

 

대시보드 도입

CLI는 로컬 환경에서 동작하기 때문에 환경에 따른 한계가 명확했습니다. 저희는 이 한계를 플랫폼으로 확장시켜서 외부로 구현해 해결하고자 했습니다. 또한 백엔드 서버와 데이터베이스를 함께 구축해서 CLI에서 제공하지 못했던 다양한 기능도 추가해 보기로 결정했습니다. 아래 보이는 화면은 앞서 말씀드린 이슈를 보완해 만든 대시보드 결과물입니다. CLI를 만들 때와 같이 어떻게 하면 쉽고 간단하게 배포할 수 있을지에 주안점을 두고 설계했습니다. 

사용자는 대시보드에서 간단한 네 가지 단계를 거쳐 소스 코드를 배포할 수 있습니다. 첫 번째 단계입니다. 기존에는 로컬에서 소스 코드를 바로 빌드했지만 대시보드에서는 GitHub 엔터프라이즈에 올라간 소스 코드를 참조할 수 있도록 만들었습니다. 아래 화면에서 Connect to Github 버튼이 보이실 텐데요. 해당 버튼을 누르면 OAuth 인증을 통해서 GitHub 엔터프라이즈와 연동할 수 있습니다.

두 번째 단계입니다. OAuth 인증을 통해서 GitHub의 권한을 몇 가지 얻어올 수 있는데요. 얻어온 권한을 바탕으로 GitHub 저장소에서 어떤 오거나이제이션의 어떤 리포지터리를 배포할 것인지 선택할 수 있습니다. 또 어떤 브랜치로 소스 코드를 배포할 수 있을지도 선택할 수 있습니다.

세 번째 단계에서는 프로젝트 빌드 정보를 입력합니다. 도메인을 비롯해서 빌드에 사용할 Node.js 버전이나 빌드 명령어, 환경 변수, 캐시를 얼마나 어떤 시간으로 설정할 것인지, 어떤 페이지에 캐시를 적용할 것인지를 입력할 수 있습니다.

마지막 단계에서 Deploy 버튼을 누르면 앞에서 입력한 빌드 정보를 바탕으로 소스 코드를 읽어와서 빌드를 시작합니다.

빌드가 완료되면 지정된 CDN에 자동으로 배포를 진행합니다. 내부 구조를 좀 더 자세히 들여다보도록 하겠습니다.

배포 버튼을 누르면 LandPress 서버에서는 GitHub 정보와 빌드 명령어, 환경 변수, 캐시 설정과 같은 빌드에 필요한 정보를 Jenkins 클러스터로 전달합니다. Jenkins 클러스터는 전달받은 정보를 바탕으로 Docker를 이용해 이미지를 생성합니다. 생성된 이미지를 바탕으로 컨테이너를 실행하는데요. 각각의 빌드 환경은 컨테이너로 분리되어 있기 때문에 환경의 영향을 받지 않고 빌드할 수 있습니다. 구축된 컨테이너 안에서 빌드를 완료한 후 완성된 번들을 Verda 오브젝트 스토리지로 전송하면 모든 과정이 완료됩니다.

 

빌드와 배포 자동화

앞서 개발한 프로세스에서 큰 부분을 차지하는 요소가 빌드랑 배포였는데요. 빌드와 배포하는 행위도 자동화할 수 있지 않을까 고민했고, 고민 끝에 웹훅(webhook)을 이용하면 개선할 수 있을 것 같다는 아이디어를 얻었습니다.

로컬에서 작업한 소스 코드를 GitHub 엔터프라이즈 리모트 저장소에 푸시합니다. 푸시가 완료되면 GitHub에서는 등록된 LandPress 백엔드로 웹훅을 트리거합니다. LandPress에서는 소스 코드를 받아와서 빌드한 다음 CDN에 배포합니다. 물론 푸시뿐 아니라 GitHub에서 제공하는 웹훅 이벤트에 따라서 여러 조건으로 응용할 수도 있습니다. 이를 통해 CI/CD 개념을 구현했습니다.

 

프런트엔드 개발자의 시간과 노력도 절약

LandPress를 통해서 빌드와 배포까지 자동화하고 난 뒤, 마지막으로 프런트엔드 작업할 때 들어가는 개발자의 시간과 노력도 절약할 수는 없을지 생각해 보았습니다. 프런트엔드 작업은 요구 사항이 워낙 다양하고 비즈니스 로직도 천차만별이라 언뜻 보기에 개발자 없이 작업하는 건 불가능해 보이는데요. 그렇다면 도대체 어떻게 해야 이 작업량을 줄일 수 있을까요?

 

정적 웹 페이지 콘텐츠의 특성

정적 웹 페이지는 주로 정적인 데이터를 사용자에게 전달하는 용도로 많이 사용합니다. 그렇다면 전달하는 데이터, 즉 콘텐츠가 중요한데요. 우리는 이 콘텐츠라는 개념에 조금 더 집중해보기로 했습니다. 앞서 언급한 것처럼 정적 웹 페이지는 정적인 데이터를 다루기 때문에 데이터베이스가 따로 존재하지 않습니다. 따라서 새로운 정보를 추가할 때는 불가피하게 소스 코드를 수정해야 해서 간단한 값이나 오타를 수정할 때도 개발자의 공수가 필요합니다.

그렇다면 ‘콘텐츠 영역을 추상화해서 소스 코드와 분리하면 되지 않을까?’하는 생각이 자연스럽게 드는데요. 콘텐츠 데이터를 분리해 클라이언트가 요청했을 때 보내주도록 바꿔 버리면 동적 웹 페이지와 다를 바가 없어서 앞서 말씀드렸던 캐시와 같은 정적 웹 페이지만의 장점이 희석됩니다. 그렇다면 어떻게 분리하면 좋을까요? 여러 가지 방법이 있을 텐데요. 해결 방법 중 하나를 소개하겠습니다.

 

JAM 스택

JAM 스택이라고 혹시 들어본 분 계실까요? JAM 스택은 JavaScript와 API, 그리고 마크업(Markup)만으로 구성된 웹 기술 스택을 줄여서 부르는 용어입니다. 우리가 알고 있는 다이내믹 페이지와 개념은 비슷하지만 조금 다릅니다. 좀 더 자세히 뜯어볼까요?

JAM 스택에서는 클라이언트에 대한 모든 처리를 JavaScript에 위임합니다. 여기서 JavaScript가 처리하는 내용은 주로 동적인 기능을 의미합니다. 또한 모든 기능 및 비즈니스 로직은 재사용 가능한 API로 추상화합니다. 다양한 기능들이 API로 추상화되지만 여기서는 콘텐츠 측면에 좀 더 집중해 보겠습니다.

 

헤드리스 CMS

우리는 정적 웹 페이지를 만들 때 필요한 데이터를 결국 분리된 외부 환경에서 가져와야 했습니다. 이때 JAM 스택에서 주로 사용하는 것이 ‘헤드리스(headless) CMS’입니다. ‘헤드리스’란 직역하면 머리가 없다는 뜻인데요. 여기서 머리란 콘텐츠를 보여주는 뷰(view) 부분을 의미합니다. 따라서 헤드리스 CMS는 뷰를 제외하고 콘텐츠만 관리하는 시스템, 즉 콘텐츠 관리에 집중한 시스템을 의미합니다. 이해를 돕기 위해서 저희가 내부적으로 사용하는 헤드리스 CMS를 예시로 들겠습니다. 아래 이미지는 내부적으로 사용하는 Strapi라는 프레임워크입니다. 왼쪽 화면처럼 사용자가 원하는 스키마를 추가해서 콘텐츠에 사용하는 데이터 필드를 자유롭게 구성할 수 있습니다.

설계한 스키마를 바탕으로 아래 오른쪽 화면과 같이 콘텐츠를 작성할 수 있는 GUI를 제공합니다. 사용자는 이 GUI를 통해서 콘텐츠를 작성하고 구조를 저장할 수 있습니다.

아래 화면은 앞에서 저장한 데이터를 바탕으로 실제로 렌더링한 화면입니다.

이처럼 헤드리스 CMS를 이용해 콘텐츠의 구조를 설계하고 설계에 맞춰 콘텐츠를 작성한 뒤 제공할 수 있습니다. 그렇다면 화면, 즉 뷰는 어떤 방식으로 렌더링했을까요?

 

SSG

마크업을 만드는 방법 즉, 렌더링하는 방법은 굉장히 다양합니다. HTML을 직접 작성하거나, 프리 마커와 같은 템플릿 엔진을 이용할 수도 있는데요. JAM 스택에서는 jekill이나 NexTGatsby와 같은 SSG(Static Site Generator)를 주로 이용합니다.

SSG를 이용하면 빌드 타임에 데이터를 가져와서 HTML을 렌더링할 수 있는데요. 앞서 언급했듯이 미리 작성된 HTML은 웹 애플리케이션의 서버 리소스를 사용할 필요가 없고 CDN을 통해 캐시한 후 배포하기 때문에 매우 빠른 속도로 사용자에게 전달할 수 있습니다. JAM 스택을 이용해서 정적 사이트를 생성하는 프로세스를 간략하게 표현해 봤습니다.

SSG에서 필요한 데이터 즉, 콘텐츠를 요청하면 헤드리스 CMS에서 요청한 콘텐츠를 내려받아 빌드합니다.

 

LandPress + JAMStack

우리는 이 JAM 스택이라는 개념을 LandPress와 조합하면 시너지를 낼 수 있지 않을까 고민했는데요. 빌드와 배포 기능은 이미 개발했으므로 SSG와 헤드리스 CMS 아키텍처에 좀 더 집중해 보기로 했습니다. 

SSG의 경우 CLI로 많이 제공되기 때문에 이슈가 많이 없었으나 헤드리스 CMS의 경우 서버와 데이터베이스가 필요하기 때문에 서비스마다 새로 설정하는 과정이 굉장히 번거롭고 노력이 많이 들었습니다. 따라서 어떻게 하면 서비스별로 헤드리스 CMS를 제공할 수 있을지 많이 고민했는데요. 그 해답을 Docker에서 찾았습니다.

 

헤드리스 CMS + Docker

Docker는 애플리케이션을 소프트웨어 컨테이너 안에 배치해서 독립적으로 실행할 수 있게 합니다. 또한 내부 레이어를 통해 포트도 나눌 수 있어서 Docker가 제격이라고 생각했습니다. 우리는 서비스에 필요한 커스텀 헤드리스 CMS 이미지를 제작하고 Docker에서 여러 컨테이너로 실행해서 독립적으로 CMS를 제공할 수 있는 환경을 구축했습니다.

그렇게 구축한 프로덕트의 이름을 ‘LandPress Content’라고 이름 붙였는데요. 사용자가 아래 우측 상단에 보이는 Create Project 버튼을 눌러서 헤드리스 CMS를 동적으로 생성할 수 있게 했습니다. 

생성된 CMS는 앞서 개발한 LandPress의 배포 시스템과 연동해서 빌드 배포를 진행해 바로 CDN까지 배포할 수 있도록 설계했습니다.

전체적인 시퀀스 다이어그램을 설명하겠습니다. 처음에 사용자가 헤드리스 CMS를 통해 콘텐츠를 작성합니다.

콘텐츠가 작성되면 헤드리스 CMS에서는 LandPress의 훅을 트리거합니다.

LandPress에서는 새로운 콘테츠가 작성됐다는 것을 인지하고 GitHub에서 소스 코드를 패치해 가져옵니다.

받아온 소스 코드 정보를 바탕으로 빌드 타임에 헤드리스 CMS에서 콘텐츠 데이터를 가져옵니다.

마지막으로 콘텐츠 데이터를 기반으로 번들링한 후에 CDN으로 배포하면 전체 과정이 마무리됩니다.

 

개발 기간을 단축시켜주는 템플릿 에코 시스템

이제 개발자는 새로운 콘텐츠를 추가할 때마다 소스 코드를 수정할 필요가 없습니다. 그런데 여기까지 진행해보니 뭔가 아쉬운 느낌이 들었습니다. 기존에 우리가 만들어 놓은 소스 코드를 재활용해서 개발 기간을 좀 더 단축시킬 수는 없을지 고민했습니다.

SSG에서는 기존에 만들어진 컴포넌트를 재활용할 수 있도록 템플릿 생태계를 제공하고 있습니다. 이 아이디어에서 영감을 받아 재사용할 수 있는 방법이 있지 않을까 고민해 봤는데요. 랜딩 페이지나 이벤트 페이지, 약관 페이지 같은 경우에는 포맷이 정형화돼 있다는 점에 착안해서 템플릿과 CMS를 번들로 제공하면 어떨까 생각했습니다. 많이 사용하는 패턴을 표준화해서 템플릿으로 등록하고, 사용자가 템플릿을 선택하면 선택한 템플릿을 바탕으로 미리 정리해 놓은 스키마가 있는 헤드리스 CMS를 인스턴스로 만들어서 바로 콘텐츠를 작성하고 배포까지 할 수 있도록 제공하는 것을 시나리오로 생각해 봤습니다. 

또한 기존에 만들었던 UI를 컴포넌트화하는 방법을 고안해 봤습니다. 현재 사용하고 있는 헤드리스 CMS에서는 동적으로 컴포넌트를 정의해 추가할 수 있는 기능이 존재하는데요. 이에 따라 사용자가 컴포넌트를 배치해 입맛에 맞게 페이지를 구성할 수 있도록 지원해 볼 예정입니다. 예를 들어 설명해 보겠습니다. 아래 화면 하단의 빨간색 네모 박스에 보이는 버튼들이 제가 미리 정의해 놓은 컴포넌트들입니다. 예시로 버튼과 콘텐츠, 텍스트, 이미지 컴포넌트를 만들어 봤습니다.

사용자는 추가하고 싶은 컴포넌트를 클릭해 페이지에 추가하면 됩니다. 실제로 컴포넌트를 추가해 샘플로 페이지를 만들어 봤습니다. 아래 화면 상단에 보이는 주황색이 미디어 컴포넌트이고 하단에 보이는 파란색과 초록색이 콘텐츠 컴포넌트입니다.

버튼 컴포넌트와 콘텐츠 컴포넌트도 추가해 봤습니다. 컴포넌트를 추가한 순서에 맞게 화면이 렌더링되는 모습을 보실 수 있습니다. 이미 만든 컴포넌트의 순서도 자유롭게 변경 가능합니다.

이처럼 다양한 컴포넌트를 용도에 맞게 미리 정해 놓으면 사용자가 요구 사항에 맞게 자유롭게 페이지를 구성할 수 있습니다. 아래 이벤트 페이지도 컴포넌트를 조합해 빠르게 만들 수 있었습니다.

이제 어떻게 위 이벤트 페이지를 빠르게 만들 수 있었는지 이해가 되셨나요? 위 그래프는 앞서 소개한 ‘미스 콘테스트’라는 이벤트 페이지를 개발할 때 필요한 인력을 간략하게 나타낸 표입니다. 

LandPress 없이 개발할 때는 대략 5일 정도가 필요했지만, LandPress를 이용하면서 많은 부분이 자동화돼 개발에 필요한 인력이 5분의 1 정도로 줄었습니다.

이 밖에도 LINE에서 운영하는 많은 페이지들을 앞서 언급한 기술 스택을 이용해 빠르게 개발했고 앞으로도 개발할 예정입니다. 기존에는 이 많은 작업이 모두 개발자의 손을 거쳐야 했지만 이젠 LandPress를 이용해서 클릭 몇 번 만으로 번거로운 작업을 자동으로 진행할 수 있습니다.

 

마치며

저희들의 궁극적인 목표는 개발자의 개입 없이 다양한 요구 사항을 충족하는 정적 사이트를 만드는 것입니다. 아직 개선해야 할 부분이 굉장히 많이 있지만 하나씩 하나씩 해결해 나가다 보면 언젠간 가능할 날이 올 것이라고 믿고 있습니다. 

마지막으로 말씀드리고 싶은 게 있는데요. 저는 오픈 소스 프로젝트를 만들거나 참여하는 것에 관심이 많으며 현재 주로 React 커뮤니티에서 활동하고 있습니다. 관심 있으신 분은 GitHub을 통해 같이 의견을 나눌 수 있으면 정말 좋을 것 같습니다(GitHub ID: @hg-pyun). 아래에서 발표 영상도 확인하실 수 있습니다. 긴 글 읽어주셔서 감사합니다.