React 프로젝트에서 이미지를 사용할 때 이미지가 public 폴더에 있는지, src 폴더에 있는지, 또는 jsx 파일에서 사용하는지, css에서 사용하는지에 따라 경로 설정하는 방법을 구분하고자 한다.

📂 public

  • public 폴더는 webpack 에 의해 관리되지 않고, 대신 원본이 build 폴더에 복사된다. (minify되지 않고, content hash가 포함되지 않는다.)

  • public 폴더에 접근하기 위해서는 PUBLIC_URL 환경변수를 사용해야 한다.

  • 경로가 잘못 되었거나 파일이 없는 경우 컴파일 단계에서 에러가 발생하지 않고, 404에러가 발생한다. 🚫

  • CRA 문서에서 다음과 같은 경우에만 public 폴더에서 관리하는 것이 유용하고, 이외에는 src 폴더 관리를 추천한다.

    • manifest.webmanifest 처럼 build된 결과물에서 특정한 파일 이름이 필요한 경우

    • 수천개의 이미지 파일을 동적으로 참조해야 하는 경우


📂 src

  • 파일을 찾지 못하는 경우, 컴파일 단계에서 에러를 잡을 수 있다. ✅

  • import 할 경우 참조할 수 있는 경로(path) 문자열을 출력한다.

  • content hash가 파일명에 포함되기 때문에 브라우저가 오래된 버전(파일 수정 전)의 파일을 캐싱하고 있는 경우를 고려하지 않아도 된다. (파일이 변경되었을 때만 hash값이 변경된다.) ✅

  • 서버 요청 횟수를 줄이기 위해 10,000 bytes 이하의 이미지는 path 대신 data URL을 반환한다.

    • bmg, gif, jpg, jpeg, png 파일에만 적용, SVG 파일 제외

    • 이 때, 파일 크기 기준(10,000 byte)은 IMAGE_INLINE_SIZE_LIMIT 환경변수로 설정을 변경할 수 있다.

Copy
import logo from './src_assets/logo.svg';

function App() {
  return (
    <>
      <img src={require('./src_assets/logo.svg').default} className="App-logo" alt="React" />
      <img src={logo} className="App-logo" alt="React" />
    </>
  );
}

differents


JSX에서 이미지 경로 설정

1. public 폴더에 있는 이미지

Copy
function App() {
  return (
    <img
      src={`${process.env.PUBLIC_URL}/public_assets/logo512.png`}
      className="App-logo"
      alt="React"
    />
  );
}

export default App;

파일을 못찾을 경우 컴파일 에러는 발생하지 않고 이미지가 깨진다.

public 폴더에 있는 이미지를 jsx에서 사용할 경우 공식문서에서는 환경변수의 PUBLIC_URL을 사용하라고 나와있지만 단순히 /이미지경로, 이미지경로 이런식으로 지정해도 잘 불러왔다.

Copy
// 즉, 아래 3가지 경로 모두 가능하다.
src={`${process.env.PUBLIC_URL}/public_assets/logo512.png`}
src="/public_assets/logo512.png"
src="public_assets/logo512.png"

2. src 폴더에 있는 이미지 (import)

Copy
import logo from './src_assets/logo192.png';

function App() {
  return <img src={logo} className="App-logo" alt="React" />;
}

export default App;

webpack을 사용하면 CSS 파일을 import 하는것처럼 이미지 파일을 import하여 사용할 수 있다.

파일 최상단에서 사용하는 모든 이미지를 import 하여 사용하는 동기적인 방법으로 webpack이 이미지 파일을 번들에 포함시킨다.

파일을 못찾을 경우 compile에러가 발생하여 코드를 작성할 때 수정할 수 있다.

Copy
// 이미지 경로 불러오기
import logoPath from './src_assets/logo192.png';

// 이미지 src 설정
<img src={logoPath} />;

3. src 폴더에 있는 이미지 (require)

Copy
function App() {
  return <img src={require('./src_assets/logo192.png').default} className="App-logo" alt="React" />;
}

export default App;

node.js 환경이기 때문에 require 로 문서 어디서나 파일을 불러올 수 있다. 이 방법을 사용하면 inline으로 src의 이미지 파일경로를 바로 지정할 수 있다.

처음에 모든 이미지 파일을 import 하지 않아도 되기 때문에 편리해보인다.

Copy
<img src={require('./src_assets/logo192.png').default} />

CSS에서 이미지 경로 설정

1. public 폴더에 있는 이미지

Failed to compile ./src/App.css (./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-4-1!

CSS 파일에서 public 폴더에 접근하려고 하면 위와 같은 에러가 발생한다.

CSS 파일에서 절대 경로를 설정하면 src 폴더를 기준으로 경로를 찾기 때문에 src 폴더 내에서는 해당 파일을 찾을 수 없다는 에러이다.


2. src 폴더에 있는 이미지

절대경로를 src 폴더를 기준으로 하기 때문에 아래처럼 상대경로, 절대경로 모두 사용 가능하다.

Copy
background: url('./src_assets/logo192.png');
background: url('src_assets/logo192.png');

❓ 절대 경로 설정 시 루트 폴더 기준

  • jsx 파일에서 절대경로는 public 폴더를 기준으로 한다.

  • css 파일에서 절대경로는 src 폴더를 기준으로 한다.


출처

Create-react-app 프로젝트에서 이미지 경로를 설정하는 4가지 방법

Copy