필자의 올해 목표 중 하나는 오랜기간 조금씩 진행해왔던 제니퍼 뷰서버 플랫폼화를 마무리하는 것이었다. 기획했던 플랫폼 요소는 여러가지가 있지만 그 중에서도 제니퍼 화면을 독립적인 개발환경에서 구현할 수 있게 하는 기능이 제일 중요했다. 그래서 생각해낸 것이 서버 환경은 스프링부트로 심플하게 구성하고, 모던한 프론트엔드 개발을 위해 모듈 번들러로 웹팩을 선택했다. 관련해서는 필자가 쓴 “Webpack+SpringBoot 기반의 프론트엔드 개발 환경 구축하기”를 참고하자.
새로 갖춰진 개발환경에서 기존의 제니퍼 뷰서버 플러그인 중 일부를 테스트 삼아 마이그레이션 해보니까 나름 신선하더라. 기존의 JSP 템플릿에 마크업과 공존하고 있던 자바스크립트 코드는 ES6 스펙에 맞춰서 수정하고, 모듈 별로 분리를 하고나니 필자가 사용하고 있는 IntelliJ IDEA의 정적 코드 분석이나 메소드 힌트 같은 기능들을 제대로 활용할 수 있게 되었다. 요즘 같은 세상에서는 너무 당연한 것이지만 수년간 쌓아온 레거시란 벽은 이미 넘을 수 없을만큼 높아진 상태였다.
필자는 지난 8월에 “레거시(Legacy) 시스템에 웹팩 개발환경 적용하기”를 쓰면서 언젠가는 실무에 꼭 적용해보겠다는 다짐 을 했었다. 그리고 얼마지나지 않아 여유 일정이 생겼고, 더 이상 미룰 수 없는 일이기에 바로 시작했다.
(1) 마이그레이션 대상 선택하기
제니퍼 화면은 크게 메인 대시보드와 사용자정의 대시보드, 리얼타임, 분석, 통계, 관리, 보고서 템플릿, 사용자 메뉴로 나눌 수 있다. 참고로 사용자정의 대시보드와 보고서 템플릿은 화면 단위가 아니라 컴포넌트 단위의 기능으로 복잡하게 얽혀있어서 마이그레이션 대상에서 제외했다. 다음은 제니퍼에서 제공하는 타입 별 화면 개수이다.
메인 대시보드 6종, 리얼타임 8종, 분석 21종, 통계 6종, 관리 44종
제니퍼는 한달에 최소 두번 이상의 마이너 버전이 릴리즈 되는 온-프레미스(On-premise) 제품이다보니 문제가 되는 버전이 고객사에 설치되면 되돌리기가 쉽지 않다. 서비스형 제품처럼 피드백이 즉각적으로 나타나진 않지만 수없이 많은 과거 버전들 속에서 다양한 문제에 직면하게 된다. 필자는 지난 수년간 수많은 고객사에 설치되어 어느 정도 안정성이 확보된 85종의 화면들을 마이그레이션 해야한다.
(2) 목표 설정하기
모든 일의 시작은 목표를 잘 정하는 것이다. 너무 당연한 말이지만 일의 규모가 크거나 앞에서 말한 것처럼 이미 검증된 일을 뒤엎고 새로운 것을 적용하는 일은 진행하는 사람이나 직책자 또는 구성원들에게 큰 부담을 안겨준다. 그래서 필자는 다음과 같은 목표를 정하고, 일의 당위성을 확보하기 위한 논리를 정리했다.
- 유닛 테스트와 스냅샷 테스트가 가능해야 함
- 툴에서 디버깅이 가능한 코드를 개발할 수 있어야 함
- 화면 단위로 프레임워크나 라이브러리를 자유롭게 사용할 수 있어야 함
- 마이그레이션 된 화면과 기존의 화면이 모두 잘 동작해야 함
4번에 대해 조금 더 설명을 하자면 한번에 모든 화면을 마이그레이션 할 수 있다면 정말 좋겠지만 현실적으로 불가능한 일이기 때문에 새로 갖춰진 개발환경에서는 기존의 화면과 마이그레이션 된 화면이 모두 잘 동작해야 한다.
(3) 기술 스펙 정하기
목표 설정이 끝났으니 이제는 새로 갖춰질 개발환경의 기술 스펙을 정해야 한다. 본문에서는 각각의 기술 스펙에 대한 설명은 생략하겠으며, 서론에서도 언급한 필자가 작성한 글을 참고하면 도움이 될 것이다.
- 모듈 번들러 : webpack 4
- 개발환경 서버 : webpack-dev-server
- JavaScript 컴파일러 : babel 6
- JavaScript 프레임워크 : vuejs 2
- CSS 컴파일러 : sass
- 테스트 도구 : jest
- 기타 : eslint, prettier
(4) 레이어 기반의 화면 정리하기
목표와 기술 스펙이 정해졌으니 현재 시점에서 바로 본론으로 넘어가야 하는데, 뜬금없이 레이어 기반의 화면에 대한 설명을 보게 되서 당혹스럽겠지만 제니퍼는 언제 어디서든 관리 화면을 띄울 수 있도록 레이어 기반으로 구현되었다.
즉, 마이그레이션 대상 화면의 절반이 레이어 기반인 것이다. 필자의 계획은 화면 단위(URL 별)로 엔트리를 설정하고, 공통 모듈을 제외한 아웃풋 파일들을 화면 별 디렉토리 안에 생성해두려고 했었다. 하지만 관리 화면들이 레이어 기반이기 때문에 시작부터 큰 난관에 부딪치게 되었다.