오늘은 React Vite TypeScript 환경에서 SPA 프로젝트 세팅하는 방법에 대한 이야기를 해보려고 한다. (feat. chatGBT)
내가 하고 싶은 것
현재 레거시 프로젝트는 Creat-React-App 으로 SPA 프로젝트가 만들어져 있다.
CRA는 번들러로 Webpack 을 사용하기 때문에 빌드 시 속도가 상대적으로 esbuild 보다 느리다.
그렇기 때문에 React Vite 환경에서 SPA 프로젝트로 마이그레이션을 시도하였다.
(이참에 JavaScript 도 TypeScript로 마이그레이션!)
방법
React Vite로 SPA를 만드는 경우가 많지 않나 보다... 구글링을 해도 내가 원하는 코드를 찾기가 어려웠다 ^_ㅜ
chatGBT에게 물어봤더니 아주 친절하게 답변을 해주었다.
Vite를 사용하여 React SPA를 만들고 싶다면 다음과 같은 순서를 따르면 된다.
1. 아래의 명령어를 실행하여 Vite를 글로벌하게 설치한다.
npm install -g vite
2. 프로젝트를 위한 새로운 폴더를 생성하고 폴더 안으로 이동한다.
3. 현재 폴더의 새로운 React Application을 만들기 위해 아래의 명령어를 실행한다.
ex) npx create-react-app newProject
npx create-react-app {프로젝트 이름}
4. node_modules
, package-lock.json
, yarn.lock
파일을 삭제한다.
5. package.json
파일에 들어간 뒤, scripts
부분을 다음과 같이 수정한다.
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview"
},
6. 아래의 명령어를 실행하여 dependencies를 설치한다.
npm install
7. 아래의 명령어를 실행하여 개발 서버를 실행한다.
npm run dev
React Application은 아래의 주소에서 접근 가능할 것이다.
http://localhost:3000
8. 프로젝트를 빌드한다면 Vite를 사용한 React SPA 빌드를 시작할 수 있다.
npm run build
npm run serve
문제 발생!
chatGBT 가 알려준 방법대로 따라하다보니 7번에서 문제가 발생했다.
1. 개발 서버를 열었을 때 http://localhost:3000
에서 접근이 불가능하고 http://localhost:5173/
에 개발서버가 열리고,
2. 다음과 같은 에러 화면이 뜨면서 콘솔창에는 crbug/1173575, non-JS module files deprecated.
에러가 발생했다.
non-JS module files deprecated 에러 해결 방법
아래는 chatGBT의 답변이다.
non-JS module files denovelated
오류 메시지는 CSS나 이미지 파일과 같은 non-JavaScript 모듈 파일의 처리와 관련된 Vite의 동작 변화와 관련이 있다.
이 문제는 Vite v2.x가 기본적으로 non-JavaScript 모듈을 지원하지 않는다는 사실과 관련이 있다. 대신 플러그인을 사용하여 이러한 유형의 파일을 처리해야 한다.
이 오류를 해결하려면 vite-plugin-react-pages
를 사용할 수 있다. 이 플러그인을 사용하면 JavaScript가 아닌 모듈을 JavaScript 파일로 직접 가져올 수 있는 방법을 제공하여 React 응용 프로그램에서 사용할 수 있다.
아래의 명령어를 통해 vite-plugin-react-pages
를 설치해보자.
npm install vite-plugin-react-pages
다음으로 프로젝트 root 경로에 vite.config.js
파일을 생성하여 다음과 같이 파일을 수정한다.
import reactPages from 'vite-plugin-react-pages'
export default {
plugins: [
reactPages()
],
}
이렇게 하면 Non-JS module files non-JS module files permitted
오류가 수정되고 React 응용 프로그램에서 non-JavaScript 모듈을 가져올 수 있다.
이 방법은 이 오류를 해결하는 여러 가지 방법 중 하나일 뿐이며, 특정 솔루션은 프로젝트의 설정 및 구성에 따라 달라질 수 있다.
🤔 이 절차를 따랐을 때 해결이 됐는가?
⚠️ 슬프게도 또 다른 오류가 발생하였다.
이번 오류는 개발 서버가 실행이 되지 않고 다음과 같은 에러가 발생하였다.
Error: Can't find an instance of @vitejs/plugin-react. You should apply this plugin to make mdx work.
Error: Can't find an instance of @vitejs/plugin-react. You should apply this plugin to make mdx work.
해결 방법
아래는 chatGBT의 답변이다.
오류 메시지 @vitejs/plugin-react의 인스턴스를 찾을 수 없습니다. 이 플러그인을 적용해야 mdx가 작동합니다.
는 Vite가 React 응용 프로그램에서 MDX(Markdown + JSX) 파일을 지원하는 데 필요한 @vitejs/plugin-react
플러그인을 찾을 수 없다는 사실과 관련이 있다.
아래의 명령을 실행하여 @vitejs/plugin-react
플러그인을 설치하자.
npm install @vitejs/plugin-react
그런 다음 플러그인을 가져와 vite.config.js
파일에 다음과 같이 추가해야 한다.
import reactPlugin from '@vitejs/plugin-react'
export default {
plugins: [
reactPlugin()
],
}
이렇게 하면 오류가 수정되고 React 응용 프로그램에서 MDX 파일을 사용할 수 있다.
MDX를 사용하려면 MDX 패키지와 babel 플러그인도 설치해야 한다.
npm install mdx @mdx-js/react
.babelrc 이나 babel.config.js 파일에 다음과 같이 수정한다.
{
"plugins": ["@mdx-js/babel-plugin-mdx"]
}
이렇게 하면 오류 메시지가 수정되고 React 응용 프로그램에서 MDX 파일을 사용할 수 있다.
🤔 과연 문제가 해결이 됐을까?
🥲 슬프게도 또 다시 non-JS module files denovelated
에러가 발생하였다...
위의 두 해결 방법을 사용하면 최종적으로 vite.config.js
파일이 다음과 같이 된다.
import reactPages from "vite-plugin-react-pages";
import reactPlugin from "@vitejs/plugin-react";
export default {
plugins: [
reactPages(),
reactPlugin(),
],
};
Vite 프로젝트에서 reactPages
와 reactPlugin
을 모두 사용하면 충돌이 발생하고 예기치 않은 동작이 발생할 수 있다.reactPages
및 reactPlugin
은 모두 React 애플리케이션의 기능을 향상시키도록 설계된 Vite 플러그인이다. 그러나 용도가 다르므로 함께 사용할 필요가 없을 수도 있다.reactPages
는 JavaScript가 아닌 모듈을 직접 JavaScript 파일로 가져올 수 있는 방법을 제공하여 React 응용 프로그램에서 사용할 수 있는 플러그인이다. React 구성 요소에서 CSS, 이미지 또는 기타 비 자바스크립트 파일을 가져오려는 경우 유용하다.
한편, 리액트 플러그인은 Vite에서 JSX 및 리액트 지원을 가능하게 하는 플러그인이다. 자바스크립트 파일에서 JSX와 React를 사용하고자 할 때 유용하다.
둘 다 사용할 필요는 없고, 필요에 따라 다르며, non-자바스크립트 파일만 가져오면 reactPages
만 사용하면 되고, JSX와 react만 사용하면 된다면 reactPlugin
만 사용하면 된다.
두 플러그인을 모두 사용하면 두 플러그인이 서로 다른 방식으로 동일한 파일을 처리하려고 하므로 충돌이 발생하고 예기치 않은 동작이 발생할 수 있다. 프로젝트에 가장 적합한 것을 사용하는 것이 가장 좋다.
여전히 어떤 플러그인을 사용할지 모르는 경우 각 플러그인의 설명서를 확인하여 해당 기능에 대한 자세한 정보를 얻은 다음 프로젝트에 가장 적합한 플러그인을 결정할 수 있다고 한다...
하지만 나는 두 에러가 다 일어나기 때문에 두 개를 다 사용해야 할 것 같은데... 같이 쓰면 에러가 난다고 하고 🥲🥲 정말 대략 난감한 상황이다...
우선 오늘 하루종일 트러블 슈팅한 내용을 적어놓고 계속 해서 분석해봐야겠다.
최종 방법
non-JS module files denovelated
오류 메시지는 index.html
의 위치와 관련이 있었다.
React Vite TypeScript 프로젝트 세팅을 했을 때는 개발 서버가 잘 열렸는데, CRA로 만들었을 때 개발 서버가 열리지 않는다.
해당 오류 메시지를 구글링해보면 대부분 네트워크를 확인해보라는 해결책이 나오지만, 나의 경우에는 알맞는 해결책이 아니라고 생각하여 CRA에서 Vite로 구성하는 방법 중 문제가 생겼다고 생각했다.
Vite 공식 사이트를 살펴보면 index.html이 public 폴더에 위치하지 않고 프로젝트 root 폴더에 있는 이유를 설명하고 있다.
Vite 공식 사이트
https://vitejs.dev/guide/#index-html-and-project-root
index.html and Project Root
One thing you may have noticed is that in a Vite project, index.html is front-and-central instead of being tucked away inside public. This is intentional: during development Vite is a server, and index.html is the entry point to your application.
Vite treats index.html as source code and part of the module graph. It resolves <script type="module" src="..."> that references your JavaScript source code. Even inline <script type="module"> and CSS referenced via <link href> also enjoy Vite-specific features. In addition, URLs inside index.html are automatically rebased so there's no need for special %PUBLIC_URL% placeholders.
Similar to static http servers, Vite has the concept of a "root directory" which your files are served from. You will see it referenced as <root> throughout the rest of the docs. Absolute URLs in your source code will be resolved using the project root as base, so you can write code as if you are working with a normal static file server (except way more powerful!). Vite is also capable of handling dependencies that resolve to out-of-root file system locations, which makes it usable even in a monorepo-based setup.
Vite also supports multi-page apps with multiple .html entry points.
Specifying Alternative Root
Running vite starts the dev server using the current working directory as root. You can specify an alternative root with vite serve some/sub/dir.
해석본
index.html and Project Root
Vite 프로젝트에서 당신이 알게 된 것 중 하나는 public 안에 감추어져 있는 것이 아니라 index.html
이 중심에 있다는 것입니다. 이것은 의도적인 것입니다. 개발 중에 Vite는 서버이며, index.html
은 애플리케이션의 진입점입니다.
Vite는 index.html
을 소스 코드로 간주하고 모듈 그래프의 일부로 취급합니다. 자바스크립트 소스 코드를 참조하는 <script type="module" src="...">
를 해결합니다. 이를 위해서는 내장 <script type="module">
과 <link href>
를 통해 참조되는 CSS도 Vite 특정 기능을 즐길 수 있습니다. 또한 index.html
내의 URL은 자동으로 재기준화되어 특별한 %PUBLIC_URL% placeholder가 필요 없습니다.
Vite는 정적 HTTP 서버와 비슷하게 "root 디렉토리"의 개념을 가지고 있어, 파일이 제공되는 곳으로 생각할 수 있습니다. 문서 중 다른 부분에서도 <root>
라는 표현으로 참조할 수 있습니다. 소스 코드에서의 절대 URL은 프로젝트 root를 기반으로 해석되어, 일반적인 정적 파일 서버와 같은 환경에서 작업하는 것 처럼 코딩이 가능합니다(그것보다 훨씬 강력한 기능을 가지고 있습니다!). Vite는 root 디렉토리 밖의 파일 시스템 위치에서 종속성을 해결할 수 있어, 모노레포 기반 구성에서도 사용 가능합니다.
Vite는 또한 .html
엔트리 포인트가 여러 개인 다중 페이지 앱도 지원합니다.
대체 루트 지정
vite 실행시 현재 작업 디렉토리가 root로 사용되는 개발 서버가 시작됩니다. vite serve some/sub/dir
으로 대체 루트를 지정할 수 있습니다.
또한, react-ts vite SPA 에 대한 자료도 많이 없고... 최근에 github에 예제를 요청하는 이슈도 확인할 수 있었다.
Vite 에서 index.html 위치를 public에 놓지 않기 때문에 SPA로 만드는 것이 적절치 않겠다고 생각했다.
index.html 을 프로젝트 root 에 놓거나, index.html을 public으로 뺄 거면 CRA 를 사용하는 방법을 해결을 해야겠다.
✔️ 최종적으로 index.html 위치를 프로젝트 위치로 이동시켰다. (CRA 사용 X)
참고 사이트
https://cathalmacdonnacha.com/migrating-from-create-react-app-cra-to-vite
https://github.com/single-spa/single-spa/issues/1042
'React' 카테고리의 다른 글
[Context vs Recoil] 컴포넌트 상태 관리 하기 (0) | 2023.02.23 |
---|---|
[React Vite] CRA에서 Vite로 마이그레이션(migration) 하기 (0) | 2023.01.31 |
[React] 렌더링 최적화 (1) | 2023.01.26 |
[React] 다음 주소 검색 사용하기 (with 모달 ) react-daum-postcode (0) | 2023.01.02 |
[React] Redux vs Recoil vs React Query (0) | 2022.10.06 |
Comment