# public 디렉토리

`public` 디렉토리는 정적(static) 에셋을 관리할 때 사용합니다. 일반적으로 `src` 디렉토리에서 에셋을 사용하는 것이 권장됩니다. 다음은 `src` 에서 에셋을 관리할 때 유용한 경우입니다.

* 스타일, 스크립트가 축소, 번들되어 네트워크 요청 횟수를 줄일 수 있습니다.
* 누락 된 스타일, 스크립트 파일이 있을 경우, 404 오류 또는 컴파일 오류를 발생시킵니다.
* 출력 파일 이름에 콘텐츠 해시가 포함되어 브라우저에서 이전 버전을 캐싱하는 것을 방지할 수 있습니다.

## 유용한 경우 <a href="#useful-cases" id="useful-cases"></a>

하지만 외부 CSS, JavaScript 웹용 라이브러리는 개발 과정 중에 직접 수정할 일이 없으므로 정적 에셋으로 처리하는 것이 보다 효율적입니다. `public` 디렉토리 내부 파일은 Webpack에 의해 관리되지 않습니다. 빌드 과정에서 그대로 `build` 디렉토리에 복사될 뿐입니다.

{% tabs %}
{% tab title="public 디렉토리" %}

```python
public/
├── assets/
│   ├── favicon.png
│   ├── logo192.png
│   ├── logo512.png
│   └── og-image.jpg
├── index.html
├── manifest.json
└── robots.txt
```

{% endtab %}
{% endtabs %}

public 디렉토리의 에셋을 src 디렉토리 내부 파일에서 참조하려면 [환경 변수](https://yamoo9.gitbook.io/learning-react-app/tip-and-references/create-react-app/add-env)를 사용합니다.

{% tabs %}
{% tab title="ReactComponent.js" %}

```jsx
// public 디렉토리의 에셋 가져오기 유틸리티
function getPublicAsset(path) {
  return `${process.env.PUBLIC_URL}/${path}`
}

function HomeLink(props) {
  // 유틸리티 활용
  return (
    <h1 className="homeLink">
      <a href={getPublicAsset('')}>
        <img src={getPublicAsset('assets/logo192.png')} alt="" />
        {props.children}
      </a>
    </h1>
  )
}
```

{% endtab %}
{% endtabs %}

정적 HTML에서 `public` 에셋에 접근하려면 `%PUBLIC_URL%`을 사용합니다. `src` 또는 `node_modules` 디렉토리의 파일을 정적 에셋으로 사용하고자 한다면 파일을 복사해 public 디렉토리에 붙여넣기 합니다.

{% tabs %}
{% tab title="public/index.html" %}

```markup
<link rel="icon" href="%PUBLIC_URL%/assets/favicon.png" />
```

{% endtab %}
{% endtabs %}

`public` 디렉토리는 일반적으로 사용이 권장되지 않지만, 다음의 경우 해결 방법으로 유용합니다.

* 빌드 출력 시, 특정 이름을 가진 파일이 필요한 경우: [`manifest.webmanifest`](https://developer.mozilla.org/en-US/docs/Web/Manifest)
* 수 많은 이미지를 사용해야 하며, 해당 경로를 동적으로 참조해야 하는 경우
* [pace](https://codebyzach.github.io/pace/) 라이브러리와 같이 크기가 작은 스크립트를 포함 하려고 하는 경우
* Webpack과 호환되지 않아 `<script>`로 포함해야만 하는 경우

## 유용하지 않은 경우 <a href="#not-useful-cases" id="not-useful-cases"></a>

`public` 디렉토리 에셋을 사용하는 방식은 다음의 단점을 가지므로 사용 시 유의해야 합니다.

* `public` 디렉토리 내부 파일은 압축, 번들링 되지 않습니다.
* 누락 된 파일이 있을 경우 컴파일 과정에서 호출되지 않으며 404 오류를 발생시킵니다.
* 출력 파일 이름에 콘텐츠 해시가 포함되지 않아, 브라우저에서 이전 버전을 캐싱하므로 \
  파일이 변경될 때 마다 파일 이름을 변경해야 합니다.
