공부한 내용

이 블로그 공부한 내용 카테고리 글

전체글 보기
공부한 내용 · 최종 수정
#ES5#ES6#JSP#jQuery#React#마이그레이션

ES5 패턴을 ES6+로 — 운영 중단 없이 옮긴 방법

JSP·jQuery 전산 화면에서 ES6+로 단계 이전한 뒤, React SPA를 iframe으로 붙여 확장해 나간 경험이다.

“ES6로 바꿉시다”는 말은 회의실에서는 쉬웠다.
실제로 손대는 곳은 JSP 안쪽이었다.

JSP 전산 화면이었던 것

  • 상단·좌측 메뉴는 공통 include로 묶여 있었다.
  • 본문 JSP에 조회 폼, 테이블, hidden 필드가 먼저 있고, 하단에 <script>가 이어졌다.
  • JS 파일이 분리돼 있어도, 최종 진입점은 JSP였다. 어떤 변수는 c:forEach, 어떤 값은 스크립틀릿으로 이미 박혀 나왔다.
  • jQuery로 이벤트를 걸고, AJAX로 전산 API를 때리는 구조가 반복됐다.

그래서 “프론트 프로젝트를 갈아엎자”보다, JSP 한 장씩 읽히게 만드는 일부터 시작했다.

JSP 안에서 먼저 한 일

  1. 스크립트 위치 정리: 인라인 <script>와 외부 .js 역할을 나눴다. JSP에는 “데이터 주입”만, 로직은 파일로.
  2. 전역 오염 줄이기: IIFE로 감싸고, 화면별 네임스페이스(window.ScreenXxx)를 고정했다.
  3. ES5 → ES6+는 화면 단위: 한 JSP를 고칠 때마다 그 화면이 쓰는 JS만 손댔다.

한 번에 빌드 체계를 넣지 않았다. 운영 중인 JSP 배포 리듬에 맞추는 게 우선이었다.

우선 바꿨던 패턴 (JSP에 붙는 JS 기준)

ES5 / 레거시ES6+JSP·운영 관점
varconst / let스크립틀릿과 섞인 스코프 버그 감소
function() {} 콜백화살표 함수 (this 필요 시 유지)이벤트 핸들러 짧게
.then 체인async/awaitAJAX 에러 처리 한곳으로
응답 필드 나열구조 분해서버 JSON 매핑 단순화
문자열 +템플릿 리터릴로그·알림 메시지 정리

한 배포에 한 패턴이었다. JSP diff와 JS diff를 같이 리뷰받기 쉬웠다.

JSP에서 특히 조심한 것

  • 서버가 내려준 값 (${...}, hidden input)은 건드리지 않고, 읽기만 명확히 했다.
  • document.ready 안에서 DOM을 다시 찾는 순서를 바꾸지 않았다.
  • 공통 include 순서가 바뀌면 다른 화면이 깨질 수 있어서, include 체인은 마지막에 건드렸다.

“모던해 보이게”보다 JSP + JS 합쳐서 동일 동작이 기준이었다.

검증 (전산 운영 기준)

  • 같은 조건으로 조회·저장·승인 흐름을 다시 탔다.
  • 금액·날짜·권한 체크가 바뀌지 않았는지 담당자와 같이 봤다.
  • 네트워크 탭에서 요청 URL·파라미터 개수가 이전과 같은지 확인했다.
  • 운영 시간대를 피하고, 문제 시 이전 JS 파일로 되돌릴 경로를 남겼다.

그다음: React SPA를 iframe으로 붙였다

ES6+로 읽기 쉬운 JS를 쌓아 두니, 이 화면만 새 UI로라는 요구가 들어왔다.
당시 선택은 기존 JSP는 그대로 두고, React SPA를 iframe으로 삽입하는 방식이었다.

왜 iframe이었는가

  • JSP 레이아웃·메뉴·세션은 그대로 두고, 바뀌는 영역만 격리할 수 있었다.
  • React 쪽 배포와 JSP 배포를 분리할 수 있었다.
  • 문제가 나면 iframe src만 이전 버전으로 돌리거나, 빈 JSP 블록으로 막을 수 있었다.
  • 팀이 익숙한 전산 URL·권한 체계를 유지한 채, 신규 UI만 실험할 수 있었다.

JSP 쪽에서 한 일 (대략)

<%-- 기존 조회 영역은 유지, 신규 영역만 분리 --%>
<div id="legacy-summary">...</div>
<div id="spa-mount" style="min-height: 480px;">
  <iframe
    id="ledger-spa"
    src="/spa/ledger-app/index.html"
    title="차세대 원장"
    style="width:100%; border:0;"
  ></iframe>
</div>
<script>
  (function () {
    var frame = document.getElementById('ledger-spa');
    // 초기 파라미터: hidden / data-attribute 에서 읽어 postMessage 로 전달
    frame.addEventListener('load', function () {
      frame.contentWindow.postMessage(
        { type: 'INIT', shopId: document.getElementById('shopId').value },
        window.location.origin
      );
    });
  })();
</script>
  • JSP가 초기 컨텍스트(매장, 기준일, 권한 플래그) 를 넘기고
  • iframe 안 React가 조회·상세·수정 UI를 담당하게 나눴다.
  • 저장·승인처럼 민감한 건 처음엔 기존 JSP API를 그대로 호출하게 두었다.

확장해 나간 순서

  1. 조회 전용 한 메뉴만 iframe으로 교체
  2. postMessage로 탭 전환·리로드·에러 토스트 연동
  3. iframe 높이 resize (내용 길이에 맞춤)
  4. 점진적으로 등록·수정까지 SPA로 이동 (API는 Spring Boot 쪽으로 이관)
  5. 익숙해지면서 iframe 없이 라우트 단위 전환을 검토 (아직 진행 중인 화면도 있음)

한 번에 SPA로 갈아타지 않았다. JSP 위에 얹고 → 영역을 넓히는 순서였다.

지금 돌아보면 (당시 결론)

  • ES6+ 정리는 “문법 업그레이드”가 아니라, JSP 전산을 다음 단계로 넘길 준비였다.
  • iframe React는 임시 땜질이 아니라, 운영을 끊지 않는 이관 통로에 가까웠다.
  • 레거시는 분석부터에서 적었던 읽기 순서가 없었으면, iframe 경계도 못 잡았을 것이다.

새 기술(React)을 빨리 쓰고 싶은 마음과, 운영 전산을 멈출 수 없다는 현실. 그 사이에서 내가 택한 답은 덮어쓰기가 아니라 얹고 넓히기였다. 한 번에 갈아엎는 멋진 그림보다, 매 배포마다 되돌릴 수 있는 작은 전진이 결국 더 멀리 갔다.

솔직히 아쉬운 것 (개선점)

  • iframe 방식은 상태 공유·SEO·스크롤/포커스 처리에서 한계가 분명했다. postMessage 규약이 늘어날수록 관리 비용도 같이 늘었다.
  • ES6+로 정리한 화면과 아직 ES5인 화면이 공존해, 한동안 두 스타일을 동시에 유지보수해야 했다.
  • 검증을 “담당자와 같이 보기”에 많이 의존했다. 자동 회귀 테스트가 약해, 사람이 빠지면 검증 품질도 흔들렸다.

앞으로 나가야 할 방향

  1. iframe으로 격리했던 화면을 라우트 단위 통합(같은 SPA 내 라우팅) 으로 단계적으로 끌어올린다. 이미 일부는 진행 중이다.
  2. 저장·승인 같은 민감 흐름의 API를 Spring Boot 쪽으로 완전 이관하고, JSP는 점차 “데이터 주입”에서도 손을 뗀다.
  3. 핵심 흐름(조회·저장·승인)에 E2E 회귀 테스트를 붙여, 이관할 때마다 사람이 일일이 확인하지 않아도 되게 만든다.
  4. 남은 ES5 화면의 이관 우선순위를 변경 빈도·장애 이력 기준으로 매겨, 감이 아니라 데이터로 순서를 정한다.

JSP 안에서 버텼던 시간이 있어서, React를 덮어쓰기가 아니라 확장으로 붙일 수 있었다. 다음 단계는 그 “확장”의 임시 통로(iframe)를 걷어내고, 정식 구조로 수렴시키는 일이다.

#ES5#ES6#JSP#jQuery#React#마이그레이션

이 블로그 공부한 내용 카테고리 글

전체글 보기