[React] public폴더와 src폴더

조아영·2024년 8월 30일

작업을 하며 "이 파일은 어떤 폴더에 넣어야 하지?"라는 고민을 하게 되었다.
특히, 이미지와 폰트 파일. 그래서 public폴더와 src폴더의 차이점과 특징을 알아보게 되었다.

📁 public

  • webpack으로 관리되지 않고, 원본이 dist 폴더에 복사된다. 그렇기 때문에 경량화(minify)되지 않고, content hash가 포함되지 않는다.
  • 경로가 잘못 되었거나, 파일이 존재하지 않을 경우 컴파일 단계에서 오류가 발생하지 않고, 사용자가 접근할 때 404 오류를 응답받게 된다.
  • 절대경로로 사용이 가능하다.

이럴경우 사용

  • build된 결과물에서 특정한 파일 이름이 필요한 경우(빌드 시 웹팩이 파일 이름을 바꾸지 않는다)
  • 수천개의 파일을 동적으로 참조해야 하는 경우
  • 번들링 된 코드 외에서 작은 스크립트를 포함하고 싶을 경우(압축이 필요없는 경우)
  • 웹팩과 호환되지 않는 라이브러리를 사용하는 경우
  • 사용 예시 : favicon, index.html 등

예시

// index.html
<meta property="og:image" content="/images/og.jpg" />
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon/favicon-16x16.png" />


// jsx
function App() {
    return <img src={`${process.env.PUBLIC_URL}/public/images/logo.png`} alt="Logo" />;
}

export default App;

주의사항

  • index.html에서 경로를 ./public/images/~~이 아닌 /images/~~로 사용 한다.

📁 src

  • 파일을 찾지 못하는 경우, 404 오류 대신 컴파일 단계에서 에러를 잡을 수 있다.
  • 추가 네트워크 요청을 피하기 위해 스크립트와 스타일시트가 축소되고 함께 번들된다.
  • content hash가 파일명에 포함되기 때문에 브라우저가 오래된 버전(파일 수정 전)의 파일을 캐싱하고 있는 경우를 고려하지 않아도 된다.(파일이 변경되었을 때만 hash값이 변경된다)
  • 서버 요청 횟수를 줄이기 위해 10,000 bytes 이하의 이미지는 path대신 data URL을 반환한다. (bmp, gif, jpg, jpeg, png 파일에만 적용, SVG 파일 제외)

이럴경우 사용

  • 코드와 밀접하게 연관되어 있는 경우(컴포넌트에서 사용하는 이미지 파일 등)
  • 빌드 과정에서 처리되어야 할 경우(이미지 파일의 크기를 줄이거나, 파일 이름을 변경이 필요할 경우)
  • 사용 예시 : index.js, css, 컴포넌트 파일 등

예시

// GlobalStyle.jsx
import PretendardRegularWoff2 from "../assets/fonts/Pretendard-Regular.subset.woff2";
import PretendardRegularWoff from "../assets/fonts/Pretendard-Regular.subset.woff";

const GlobalStyle = createGlobalStyle`
@font-face {
    font-family: "Pretendard";
    src: local(Pretendard-Regular), url(${PretendardRegularWoff2}) format("woff2"), url(${PretendardRegularWoff}) format("woff");
    font-weight: 400;
}`;

export default GlobalStyle;


// jsx
import logo from "../assets/images/logo.png";

function App() {
    return (
        <>
            // import 방식
            <img src={logo} alt="Logo" />
            // require 방식
            <img src={require("../assets/images/logo.png").default} alt="Logo" />
        </>
    );
}

export default App;

주의사항

  • 경로를 직접 입력하는 것이 아닌 importrequire해서 사용해야한다.

0개의 댓글