아이웨딩(회사) React(CSR) -> NextJS 전환 작업

SangminL96·2022년 6월 17일
0

전환 이유

  1. 기존 회사사이트는 php로 개발되어 있고 SEO가 각 페이지별로 잘 적용되어 있었습니다.
    NextJS의 장점인 SEO를 적극 활용.
  2. NextJS를 들어본 사람은 누구나 알고있는 SSR
  3. 가장 큰 이유! 기존 회사사이트 React(CSR) 폴더 구조와 불필요한 컴포넌트가 너무 많아 사이트 초기 렌더링 속도가 너무 느렸습니다.
    (크롬네트워크3G적용후 홈페이지 로드시 약15초가 걸림..)
    초기 사이즈를 줄이고자 lazy import 다 적용을 해도 초기 설계가 잘못 됐는지 큰 변화가 없었다.
    결국 코드 전체 리팩토링을 생각을 했고 리팩토링 하는 기회에 NextJS로 전환하자고 생각하였다.
  4. 리덕스와, useSWR, react-query등 (전)개발자가 공부하면서 개발한 사이트라 너무 여러가지 라이브러리가 존재했고
    하나로 통일이 필요했습니다.

전환 작업 시작

사실 NextJS를 전환하는 작업을 저와 같이 입사한 팀원과 사이트의 심각성을 느껴 개인적으로 기존 사이트 작업를 한뒤
시간이 남을 때 마다 작업을 하였다.
저는 생각보다 전환 작업이 쉬울거라고 생각하였고 2~3일이면 전부 전환이 가능하다고 생각했다.
하지만 기존 코드가 너무 불필요하게 컴포넌트가 많이 분리되어 있고 규칙성도 존재하지않아서 여기저기 다 엮여 있었기 때문에
1주일정도 시간이 걸렸던거 같습니다.

전환 작업 쉽게 빠르게 하기

일단 CSR의 라우트 주소를 전부 NextJS /page 폴더에 복사 붙여넣기를 했습니다.
다른 코드들은 잘모르겠지만 저희는 /page 페이지에 만든 경로 파일에는
다른 로직 하나없이 오직 SSR,SEO,로직컴포넌트Index 기능만 하도록 하였다.

/component/main폴더 MainIndex.tsx를 생성해 UI컴포넌트와 여러 로직들을 모아둡니다.
이런식으로 진행을 하면 기존의 있던 많은 코드들을 어느정도 끌고와서 사용이 가능합니다.

전환하면서 어려웠던점

  1. 일단.. 기존 코드에 window, document등 useEffect나 여러 로직에 사용되어 있었습니다.
    NextJS는 클라이언트 로드가 되기전에 해당 이벤트를 사용하면 에러가 발생하기 때문에 하나하나 다 찾아내서 변경 해주었습니다.
  1. 이미지, 링크이동(Link), router query, params등 모두 문법이 다르기 때문에 찾아내서 바꿔주었습니다.
  1. undefined 에러시 정확히 어디서 어떻게 나왔는지 알수가 없음.
  1. CSS 깨짐.(SSR때문에 CSS깨짐 현상)
    해결방법
    • const RequestTitle = dynamic(() => import('../components/RequestTitle'), { ssr: false });
  1. 기존 리덕스, react-query 코드를 useSWR로 전부 통일(개인적으로 이작업이 굉장히 힘들었습니다.)
  1. ecosystem.config.js 배포 파일실행시 스크립트 next start 사용시 배포가 안되는 문제
    해결방법(커스텀 server.js를 만들어 스크림트에 script: 'server/app.js' 실행)
    const { parse } = require('url');
    const express = require('express');
    const next = require('next');
    const cors = require('cors');
    const env = process.env.NODE_ENV || 'development';
    const port = parseInt(process.env.PORT, 10) || 6800;
    const app = next({ dev: env === 'development' });
    const handle = app.getRequestHandler();
    app.prepare().then(() => {
     const server = express();
     server.use(cors());
     server.get('*', (req, res) => {
       handle(req, res, parse(req.url, true));
     });
     server.listen(port, err => {
       if (err) throw err;
       console.info(`> Ready on port ${port}`);
     });
    });
    ``
  1. 저희 사이트는 웹뷰기반 어플리케이션도 존재 했기 때문에 디바이스별 체크하는 라이브러리를 사용했습니다.
    SSR로 인해 해당 라이브러리가 잘 작동이 안되었고 직접 UserAgent를 이용해 체크하는 로직 생성후 모두 바꿔주었습니다.
App.getInitialProps = async (appContext: AppContext) => {
  const userAgent = appContext?.ctx?.req ? await appContext?.ctx?.req?.headers?.['user-agent'] : navigator?.userAgent;
  const mobile = (await userAgent?.indexOf('Mobi')) > -1 ? true : false;
  const app = (await userAgent?.indexOf('IWAPP')) > -1 ? true : false;
  const iPhone = (await userAgent?.indexOf('iPhone')) > -1 ? true : false;
  const Android = (await userAgent?.indexOf('Android')) > -1 ? true : false;
};

전환 마무리

전환하면서 어려운점도 많고 생각보다 고쳐야할 부분이 너무 많아 포기를 할까 생각했지만 꾸준히 점심시간에도 작업하였다.
5일정도를 거쳐 전부 다 전환하였고 배포후에 사이트 로드 속도를 확인하니 3g 네트워크 환경에서도 약3~4초 정도로 엄청나게 줄었습니다.
SSR로 인해 SEO로 적용하기 쉽고 속도도 빨라지고 배포시 빌드 컴파일 속도가 빨라지고 전반적으로 다 빨라졌다.

스타트업 회사를 경험하다가 어느정도 환경이 가추어진 회사로 입사하고 나니 기존에 있는 코드가 너무 지저분해 보여 나름 큰 작업을 결심하였다.
세상에 깔끔한 코드는 없다고 어디선가 들었지만 리팩토링은 꼭 필요하다고 생각이 들고 폴더구조도 깔끔해지고 컴포넌트들도 많이 줄어드니
지저분한 책상을 오랜만에 치운 기분이 들었다.

profile
안녕하세요

0개의 댓글