Vite 마이그레이션 실패

0
post-thumbnail
post-custom-banner

CRA에서 Vite로 마이그레이션

왜 마이그레이션 하려는건가 ?

CRA의 Dependencies

이번 회사에서 msw 라이브러리를 도입하고 msw를 package.json에서 devDependencies로 관리를 하여 해당 라이브러리가 빌드 되지 않도록 하였습니다.

그런데 간과한 사실 하나. CRA는 devDependencies에 있는 라이브러리까지 모두 빌드를 합니다.

물론 msw를 위한 mocking 코드들은 모두 분기처리를 하여 트리 쉐이킹을 한 상태라 번들링 되지 않았습니다.

하지만 devDependencies에 있는 라이브러리들이 불필요하게 빌드 시 함께 번들링되는 것이 무척이나 마음에 들지 않았습니다.
다른 개발환경에서 사용하는 라이브러리들 또한 그렇게 번들링될 걸 생각하니 머리가 간지럽기 시작합니다.

로컬 개발 환경 실행 및 빌드 속도

앞서 말한 CRA의 Dependencies가 무척이나 마음에 안드는게 1순위지만
다들 Vite Vite하는 이유 중 하나는 빠른 빌드 속도이지 않을까 합니다.

Vite 공식 문서에도 자랑을 하듯 Webpack의 몇 배는 빠르다는 장점을 가지고 있으니 마이그레이션을 안할 이유가 있나 싶습니다.


마이그레이션 중 만난 자잘한 상황

다른 환경변수.

msw를 사용하면서 development 상황에서만 msw를 사용해야하기 때문에 조건문에 리액트의 환경변수를 사용하여 주었습니다.

Vite은 import.meta.env라는 환경변수를 사용해주어야만 사용이 가능합니다.
혹은 기존에 쓰던 환경변수를 그대로 사용하려면 process.env.[환경변수명]으로 사용하여야합니다.

jsconfig 대신 vite.config

프로젝트에서 jsconfig를 사용하는데 사용 목적은 절대경로의 경로 설정을 위해서 사용을 했습니다.

타입스크립트를 사용하는 분들은 vite-tsconfig-paths라는 라이브러리를 설치해서 tsconfig를 연동시키는거 같아
저도 jsconfig를 찾던 와중 vite.config에서 자체적으로 경로설정이 가능하다는 사실을 알았습니다.

덕분에 jsconfig대신 vite.config를 사용하여 절대 경로를 수정했습니다.

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  resolve: {
    ...
    alias: [
      { find: "components", replacement: "/src/components" },
      { find: "page", replacement: "/src/page" },
    ],
    ...
  },
});

host와 port

마이그레이션한 Vite에서 npm dev로 실행 시 기본 port가 5713로 되어있었습니다.
이제껏 3000번 포트에 서버와 Proxy까지 맞추어놨기 때문에 3000번 포트로 변경해야했습니다.

뿐만아니라 갑작스럽게 localhost가 아닌 127.0.0.1 형태의 주소로 변경되었었는데

이는 nodeJs의 17v 이상부턴 ipv6 프로토콜을 우선적으로 연결하기 때문에 ipv4 프로토콜의 루프백 주소인 127.0.0.1 은 연결 되지 않았습니다.

이 또한 vite.config 파일 내부에서 수정을 할 수 있었습니다.

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  ...
  server: {
      host: "localhost",
  	  port: 3000
	}
  ...
});

이 밖에 package.json의 script 수정, 기존 CRA의 삭제 와 같은 마이그레이션을 이어나갔습니다.

Dynamic Import의 재앙 그리고 실패

먼저 프로젝트의 Route 방식을 설명드리겠습니다.

사용자는 특정 권한이 있어 권한에 해당되는 페이지만 볼 수 있습니다. (그 외의 페이지는 404 처리)
권한은 동적으로 DB에서 관리되며 추가, 삭제, 수정이 가능하기에 프론트에서 정적으로 관리할 수 없습니다.

사용자가 권한에 맞지 않는 페이지를 이동 시 404 페이지로 넘어갈 수 있도록 구현을 하였으나

특정 페이지를 들어갔다가 Redirect되는거는 보기 좀 그러니 애초에 Route를 사용자에게 맞게 주는게 맞지 않을까요 ?

라는 상사의 말씀에 Route 관리 또한 DB에 저장하여 관리하게 되었습니다.

이렇게 동적으로 Route를 관리하고 Code-Splitting을 위해 lazy를 사용하였습니다.
(프로젝트의 페이지가 300페이지 정도라 Code-Splitting 사용하여 최적화 하였습니다.)

Vite 공식문서에는 동적 import가 가능하다는 글이 적혀있어 문제가 없을거라 판단을 하고 진행을 하던 와중 에러가 나왔습니다.

The above dynamic import cannot be analyzed by vite. See https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations for supported dynamic import formats. If this is intended to be left as-is, you can use the /* @vite-ignore */ comment inside the import() call to suppress this warning.

해당 에러를 간단하게 설명하자면 Vite(Rollup)에서 사용하는 import의 형식에 맞게 사용하라는 뜻이였습니다.

분명 해당 문서를 읽고 코드를 작성했는데 무엇이 문제인지 찾아다녔습니다.

문제의 원인은 다음과 같습니다.

Vite는 ESModules 기반으로 빌드 타임에 모든 모듈 경로를 알아야합니다. Vite 공식 문서에서는 Dynamic Import가 가능하다고 설명되어 있지만 이는 런타임에 결정되는 동적 경로 대신 빌드 타임에 알 수 있는 경로에 대해서만 작동을 합니다.

따라서 DB에서 가져온 알 수 없는 경로의 동적 import는 사용할 수 없다는 것이였습니다.

반면 Webpack은 추가적인 번들 생성이 가능하고 필요 시점에 로드되기 때문에 동작이 되었던것입니다.


마지막으로...

요즘 Vite를 안쓰는 회사가 없을 정도로 주변에서 많이들 사용하시는 번들러입니다.

저 또한 Webpack과 비교했을 때 말도 안되게 빠른 실행 속도를 느꼈었습니다.

하지만 현재 프로젝트와는 맞지 않은 번들러라 생각이 들기에 아쉽게도 마이그레이션은 여기서 멈추게 되었습니다.
(이것만 하면 끝인데...)

그래도 부족했던 번들러에 대한 경험과 마이그레이션을 통해 한 단계 성장한거 같습니다.

감사합니다.

Reference

[NodeJs] localhost가 실행되었는데 127.0.0.1 에 접속되지 않는 경우
https://stirringdev.tistory.com/102
Vite 공식문서
https://ko.vitejs.dev/guide/


post-custom-banner

0개의 댓글