| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
- 자바스크립트
- CSS
- next.js
- 모던 자바스크립트 딥 다이브
- useRef
- 알고리즘
- 패스트캠퍼스
- styled-components
- JavaScript
- 입문
- MegabyteSchool
- GIT
- 공식문서
- useMemo
- 리액트
- Github
- 이벤트
- react
- 메가바이트스쿨
- 국비지원교육
- 프론트엔드
- 비전공자
- 자료구조
- 개발 공부
- 내일배움카드
- 모던 딥 다이브 자바스크립트
- 프로그래머스
- 개발자취업부트캠프
- 코딩테스트
- TypeScript
- Today
- Total
개발 기록 남기기✍️
[React] create-react-app 프로젝트에서 이미지 파일 로드하기 본문
CRA로 React 프로젝트를 시작하면 폴더 구조가 public, src로 나뉘어져 있는 것을 확인할 수 있다.
각 폴더의 역할은 무엇이고, 이미지 파일은 어느 폴더에서 관리하는 것이 좋을까?
또 jsx 파일 내에서 이미지 파일을 로드하는 방법은 무엇일까?
📁 public
- 정적 파일을 관리하는 폴더 (index.html을 비롯한 html 파일, img 등)
- webpack에 의해 관리되지 않는다. 파일이 후처리(post-process) 되거나 경량화(minify)되지 않고, build시 파일 원본이 그대로 build폴더에 복사된다.
- public 폴더에 접근하기 위해서는 PUBLIC_URL 환경변수를 사용해야한다.
(<img src={process.env.PUBLIC_URL + '/banner.png'} /> ) - 경로가 잘못 되었거나 파일이 없을 경우 컴파일 단계에서 에러가 발생하지 않고, 404 에러가 발생한다.
- css 파일이 아닌 jsx 파일에서만 public 폴더의 이미지를 로드할 수 있다.
📂 src
- 개발하면서 작업하는 파일을 관리하는 디렉토리 (index.js, 그 외 리액트 컴포넌트 같은 js 파일, css 파일 등)
- 파일을 찾지 못하는 경우, 컴파일 단계에서 에러를 잡을 수 있다.
- import할 경우, 참조할 수 있는 경로(path) 문자열을 출력한다.
- 서버 요청 횟수를 줄이기 위해 10,000 bytes 이하의 이미지는 path대신 data URL을 반환한다.
(bmp, gif, jpg, jpeg, png 파일에만 적용, SVG 파일 제외)
이 때, 파일 크기 기준(10,000 byte)은 IMAGE_INLINE_SIZE_LIMIT 환경변수로 설정을 변경할 수 있다.
🧐 public 폴더는 어느 때에 사용할 수 있을까?
- 특정 이름을 가진 파일이 필요할 때
- 이미지 파일이 수천 개 있어서 경로를 동적으로 참조해야 할 때
- 번들링 된 코드 밖에서 pace.js 같은 작은 스크립트를 포함하고 싶을 때
- webpack과 호환되지 않는 라이브러리를 사용해야 할 때 (<script> 태그로 라이브러리를 포함해야 할 때)
🖼️ jsx 파일 내에서 이미지 로드하기
📁 public
function App() {
return (
<img
src={`${process.env.PUBLIC_URL}/banner.png`}
className='site-banner'
alt='banner'
/>
);
}
export default App;
이미지 파일을 public 폴더에 저장하면 src="/banner.png" 처럼 절대 경로로 작성하면 된다.
유의해야 할 점은 리액트로 만든 html 페이지를 배포할 때 yousunzoo.com 경로에 배포하면 아무런 문제가 없지만 yousunzoo.com/into/ 같은 경로에 배포하면 파일을 찾을 수 없다고 나온다.
그래서 리액트 공식 사이트는 예제 코드처럼 절대 경로 앞에다가 process.env.PUBLIC_URL을 붙여주는 것을 권장한다. 그럼 어떤 경로에서도 문제 없이 해당 파일이 잘 출력되는 것을 확인할 수 있다.
📁 src
src에서 이미지를 로드하는 방법은 두 가지가 있다.
첫 번째) import
import banner from './banner.png';
function App() {
return (
<img src={banner} className='site-banner' alt='site banner' />
);
}
export default App;
webpack을 사용하면 이미지 파일을 import하여 사용할 수 있다.
사용하려는 모든 이미지를 파일 최상단에서 import하여 사용하는 동기적인 방법으로 webpack이 이미지 파일을 번들에 포함시킨다.
파일을 못찾을 경우 compile 에러가 발생하여 코드를 작성할 때 수정할 수 있다.
두 번째) require
function App() {
return (
<img src={require('./img/banner.png').default} className='site-banner' alt='site banner' />
);
}
export default App;
node.js 환경이기 때문에 require로 문서 어디서나 파일을 불러올 수 있다. 이 방법을 사용하면 inline으로 src의 이미지 파일경로를 바로 지정할 수 있다.
require를 사용하면 객체 형태로 값이 리턴되기 때문에, 뒤에 default를 붙여서 경로가 문자열 형태 그대로 인식되게 만들어줘야 한다.
🖼️ 번외) css 파일 내에서 이미지 파일 로드하기
css파일에서 public 폴더에 접근하려고 하면 에러가 발생한다.
css파일에서 절대경로를 설정하면 src폴더를 기준으로 경로를 찾기 때문에 src폴더 내에서는 해당 파일을 찾을 수 없다.
src 폴더에 있는 이미지를 로드하려면, src 폴더를 기준으로 경로를 찾기 때문에 절대경로와 상대경로 둘 다 써도 무방하다.
background: url("./img/banner.png");
background: url("img/banner.png");
🧐 번외) Vite로 생성한 프로젝트에서 이미지 경로 불러오기
Vite로 생성한 프로젝트에서 img src를 작성하려면 기본적으로 import를 통해 파일 경로를 가져오지만, 다음과 같은 방법도 있다.
첫 번째) new URL
new URL을 사용하여 이미지 파일을 받아올 수 있다.
new URL('./banner.png', import.meta.url).href
import.meta.url은 현재 모듈의 url을 보여주는 기능이다. URL 생성자와 함께 사용하면 정적 파일의 전체 URL을 확인할 수 있게 된다.
위 코드는 로컬에서는 문제 없이 작동하지만, build 시에는 asset 폴더에 포함이 되지 않는다는 문제점이 있다.
import.meta.url은 브라우저와 Node.js 간 서로 다른 의미를 갖기 때문에, 이 패턴은 서버-사이드 렌더링(SSR)에 Vite를 사용하는 경우 동작하지 않는다. 또한 서버 번들은 클라이언트 호스트의 URL을 미리 결정할 수 없다.
두 번째) public 폴더에서 로드하기
🧐 public 폴더는 어느 때에 사용할 수 있을까?
- robots.txt와 같이 소스 코드에서 참조되지 않는 에셋
- 해싱 없이 항상 같은 이름을 갖는 에셋
- 또는 URL을 얻기 위해 굳이 import 할 필요 없는 에셋
public 내의 파일들은 개발 시에는 / 경로에, 빌드 시에는 dist 폴더에 위치하게 된다.
public 디렉터리에 위치해 있는 에셋을 가져오고자 하는 경우, 항상 절대 경로로 가져와야만 한다.
( public/icon.png 에셋은 소스 코드에서 /icon.png으로 접근이 가능.)
public 디렉터리에 위치한 에셋은 JavaScript 코드로 가져올 수 없다.
세 번째) require-transform
vite-plugin-require-transform
A plugin for vite that convert from require syntax to import that compat for es module.. Latest version: 1.0.9, last published: a month ago. Start using vite-plugin-require-transform in your project by running `npm i vite-plugin-require-transform`. There a
www.npmjs.com
📚 참고
- https://create-react-app.dev/docs/using-the-public-folder/#adding-assets-outside-of-the-module-system
- https://velog.io/@rimo09/React-Create-react-app-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EC%97%90%EC%84%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EA%B2%BD%EB%A1%9C%EB%A5%BC-%EC%84%A4%EC%A0%95%ED%95%98%EB%8A%94-4%EA%B0%80%EC%A7%80-%EB%B0%A9%EB%B2%95
- https://vitejs-kr.github.io/guide/assets.html
'Front-End > React' 카테고리의 다른 글
| [React] Context API란 무엇인가 (0) | 2023.03.10 |
|---|---|
| [React] useRef란 무엇인가 (0) | 2023.03.07 |
| [React] 공식문서 정리 - 주요 개념(2) (0) | 2023.02.02 |
| [React] 공식문서 정리 - 주요 개념(1) (0) | 2023.02.01 |
| Styled-Component(4) - Animation and Pseudo Selectors (0) | 2022.12.09 |