ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 리액트 18 > 17 마이그레이션하기
    React.js & Next.js 2022. 8. 23. 22:42

    목차

    1. 마이그레이션 이유
    2. 기본 패키지 구조
    3. 패키지 제거하기
    4. 패키지 설치하기
    5. index.js 코드 변경하기
    6. 결과
    7. 레퍼런스

    마이그레이션 이유

    CRA(Create React App)로 패키지를 초기화하는 경우, 가장 최신 버전인 18 버전을 설치하게 된다.

    현재 우리 서비스의 리액트 버전은 17이고, 사용하고 있는 라이브러리들이 18 버전에 맞춘 마이그레이션이 진행되지 않았다.. lock 파일의 라이브러리 별 의존성 문제가 있기 때문에 쉽게 버전업을 못하고 있는 상황이기 때문에, 사용하고자 하는 라이브러리가 리액트 17 버전에서도 문제가 없는지 확인하기 위해 18 버전의 리액트를 17 버전으로 마이그레이션 한다.

    따라서 CRA로 빠르게 패키지를 초기화한 이유 17 버전으로 마이그레이션 한 후 사용하는 방법을 적어보고자 한다.

    기본 패키지 구조

    일반적으로 CRA를 통해 패키지를 초기화하는 경우 package.json의 구조는 다음과 같다

    {
      "name": "2022_05_25",
      "version": "0.1.0",
      "private": true,
      "dependencies": {
        "@testing-library/jest-dom": "^5.16.4",
        "@testing-library/react": "^13.2.0",
        "@testing-library/user-event": "^13.5.0",
        "react": "^18.1.0",
        "react-dom": "^18.1.0",
        "react-scripts": "5.0.1",
        "web-vitals": "^2.1.4"
      },
      "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
      },
      "eslintConfig": {
        "extends": [
          "react-app",
          "react-app/jest"
        ]
      },
      "browserslist": {
        "production": [
          ">0.2%",
          "not dead",
          "not op_mini all"
        ],
        "development": [
          "last 1 chrome version",
          "last 1 firefox version",
          "last 1 safari version"
        ]
      }
    }

    패키지 제거하기

    react / react-dom / react-scripts / web-vitals의 버전을 리액트 17 버전에 맞춰 낮출 것이다

    $ npm uninstall react react-dom react-script web-vitals

    이후 자신이 원하는 버전에 맞춰 설치한다

    패키지 설치하기

    $ npm install react@17.0.2   
    $ npm install react-dom@17.0.2
    $ npm install react-router-dom@6.0.1
    $ npm install react-scripts@4.0.3
    $ npm install web-vitals@1.1.2

    설치 이후 node_modules와 의존성 파일 (package-lock.json / yarn.lock)을 제거한 이후 다시 설치한다

    (캐시 또한 비워주면 혹시 모르는 오류를 방지할 수 있다)

    $ rm -rf node_modules
    $ rm -f package-lock.json / rm -f yarn.lock
    
    $ npm cache clean --force
    $ npm install

    index.js 재설정하기

    만약 성급하게 패키지 설치 이후 바로 실행한다면 터미널에서 react-dom/client을 찾을 수 없습니다 와 같은 오류를 만날 것이다.

    에러코드에서 설명해주듯이 index.js 파일에서 react-dom/client 모듈을 찾을 수 없기 때문에 발생한 문제다.

    react-dom/client 는 18 버전에 새로 생긴 모듈이다. 18 버전부터는 이 모듈을 이용해 DOM을 렌더링 한다. 따라서 17 버전의 초기화된 index.js 코드로 18 버전의 코드를 대체한다.

    React 18 버전의 CRA(creat-react-app)

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import './index.css';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>
    );
    
    // If you want to start measuring performance in your app, pass a function
    // to log results (for example: reportWebVitals(console.log))
    // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
    reportWebVitals();

    React 17 버전의 CRA 사용 시 초기 index.js 코드

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    
    ReactDOM.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>,
      document.getElementById('root')
    );
    
    // If you want to start measuring performance in your app, pass a function
    // to log results (for example: reportWebVitals(console.log))
    // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
    reportWebVitals();

    **둘의 차이는?**

    1. React 17 버전의 경우 react-dom에서 ReactDOM을 import 하는데 반해, React 18 버전의 경우 react-dom/client 에서 ReactDom을 import 한다. 따라서 버전을 내린 이후 그대로 사용할 경우 ReactDom을 찾을 수 없다는 에러를 만나게 될 것이다
    2. React 17 버전의 경우 ReactDom.render 메서드를 통해 바로 렌더링 하는 반면에 React 18 버전의 경우 ReactDom.createRoot()로 public에 생성된 정적 index.html 파일의 root를 잡고 이렇게 생성한 인스턴스(root)를 이용하여 render를 하는 것을 볼 수 있다

    레퍼런스 (참고 자료)

    https://bobbyhadz.com/blog/react-module-not-found-cant-resolve-react-dom

    https://curryyou.tistory.com/468

    댓글

Designed by Tistory.