# Webpack 호환성

## 브라우저 호환성 <a href="#browser-compatibility" id="browser-compatibility"></a>

Webpack은 [ES5 호환이 가능한 모든 브라우저](https://kangax.github.io/compat-table/es5/)를 지원합니다 (IE8 이하 미지원). Webpack은 [Promise](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise)를 사용해 모듈을 불러 옵니다([`import()`](https://webpack.js.org/guides/code-splitting/#dynamic-imports), [`require.ensure()`](https://webpack.js.org/guides/code-splitting/#dynamic-imports)). Promise를 지원하지 않는 브라우저(IE 미지원)에서 사용하려면 모듈을 로드하는 코드 작성 전에 [폴리필(Polyfill)](https://ko.wikipedia.org/wiki/%ED%8F%B4%EB%A6%AC%ED%95%84_\(%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D\))을 로드해야 합니다.

{% tabs %}
{% tab title="패키지 설치" %}

```bash
npm i core-js regenerator-runtime unfetch
```

{% endtab %}

{% tab title="src/polyfills/index.js" %}

```javascript
import 'core-js/stable'
import 'regenerator-runtime/runtime'
import 'unfetch'
```

{% endtab %}

{% tab title="webpack.config.js" %}

```javascript
module.exports = {
  entry: {
    polyfills: './src/polyfills/index.js',
    main: './src/index.js'
  },
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: '[name].js'
  },
  // ...
}
```

{% endtab %}
{% endtabs %}

{% hint style="danger" %}
Babel v7.4.0부터 [@babel/polyfill](https://babeljs.io/docs/en/babel-polyfill) 패키지는 사용되지 않습니다. 대신 ECMAScript 기능을 대체하는 [core-js/stable](https://github.com/zloirock/core-js),  제너레이터 함수 기능을 대체하는 [regenerator-runtime/runtime](https://github.com/facebook/regenerator/blob/master/packages/regenerator-runtime/runtime.js)을 사용합니다.
{% endhint %}

`polyfills.bundle.js` 파일이 필요한 브라우저 환경에서 조건부 로드하기 위해 폴리필이 필요한 환경인지 검사하는 간단한 테스트를 수행합니다. 필요한 환경 임이 감지되면 동적으로 폴리필 파일을 불러와 사용하게 됩니다.

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

```markup
<!-- 오래된 브라우저 감지 스크립트 → 폴리필 조건부 로드 -->
<script src="./dist/detect.polyfills.js"></script>

<!-- 메인 모듈 -->
<script src="./dist/main.js"></script>
```

{% endtab %}

{% tab title="src/polyfills/detect.js" %}

```javascript
// 모던 브라우저 감지
const isModern = 'fetch' in window && 'assign' in Object

// 모던 브라우저가 아닌 경우
if (!isModern) {
  // 동적으로 <script> 요소 생성
  const scriptNode = document.createElement('script')
  // <script> 요소 속성 설정
  scriptNode.async = false
  scriptNode.src = './polyfills.js'
  // <head> 요소 안쪽 뒤에 삽입 (로딩)
  document.head.appendChild(scriptNode)
}
```

{% endtab %}

{% tab title="webpack.config.js" %}

```javascript
module.exports = {
  entry: {
    'main': './src/index.js',
    'polyfills': './src/polyfills/index.js',
    'detect.polyfills': './src/polyfills/detect.js'
  },
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: '[name].js'
  },
  // ...
}
```

{% endtab %}
{% endtabs %}

[빌드 명령](https://yamoo9.gitbook.io/webpack/webpack-plugins/manage-env-variables#build)을 실행하여 출력한 결과는 다음과 같습니다.

![](https://1127883942-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MTbexhuB2p5ev8QaGgg%2F-MTj5Ae4vdpsXU5_NwnV%2F-MTj6L334HCHjG4e4xIJ%2Fimage.png?alt=media\&token=d2919c4b-f594-467c-98b1-ab3388375675)

#### 브라우저 캐싱 <a href="#browser-caching" id="browser-caching"></a>

[브라우저 캐싱](https://ko.wikipedia.org/wiki/%EC%9B%B9_%EC%BA%90%EC%8B%9C)은 애플리케이션 속도를 향상시켜 유용합니다. 하지만 개발 중에는 브라우저에 저장된 캐시로 인해 변경사항이 바로 반영되지 않아, 개발자에게 혼란을 야기할 수 있습니다. 그러므로 파일 이름에 임의의 md4-hash 코드를 추가해 개발 중 빌드 될 때 마다 매번 새로운 파일 이름이 설정되도록 하여 "개발 중 브라우저 캐싱 문제"를 해결할 수 있습니다.

{% tabs %}
{% tab title="webpack.config.js" %}

```javascript
module.exports = {
  output: {
    path: path.resolve(__dirname, './dist'),
    // 빌드(컴파일, 번들링 등) 결과 파일 브라우저 캐싱(Cachinig)
    filename: 'main.[contenthash].js'
  }
}
```

{% endtab %}
{% endtabs %}

md4 캐시 코드가 추가된 파일 이름 결과는 다음과 같습니다.

![](https://1127883942-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MTbexhuB2p5ev8QaGgg%2F-MTo6iC33r67p-PNZeP6%2F-MTo71TYn_foO6oIYB5l%2Fimage.png?alt=media\&token=c0c37537-dd82-4fd8-9d59-a9eec099e0f2)

## 플랫폼 호환성 <a href="#environment" id="environment"></a>

Webpack v5는 Node.js 버전 `10.13.0` 이상에서 실행됩니다.

{% embed url="<https://nodejs.org/ko/>" %}

## 참고 <a href="#reference" id="reference"></a>

{% embed url="<https://webpack.js.org/guides/shimming/#loading-polyfills>" %}

{% embed url="<https://webpack.js.org/concepts/under-the-hood/#output>" %}

{% embed url="<https://babeljs.io/docs/en/babel-polyfill/>" %}

{% embed url="<https://github.com/developit/unfetch#installation>" %}
