# CSS 파일 개별 추출

## CSS 파일 추출 플러그인 <a href="#css-file-extract-plugin" id="css-file-extract-plugin"></a>

[MiniCssExtractPlugin](https://www.npmjs.com/package/mini-css-extract-plugin) 플러그인은 CSS 파일을 별도 파일로 추출(extract) 합니다. CSS 코드가 포함된 JS 파일 별로 CSS 파일을 생성합니다. CSS 및 SourceMaps의 온 디멘드 로딩(On Demand Loading) 기능도 지원합니다.

{% hint style="info" %}
온 디멘드(On Demand)는 "요구가 있다면 언제든지"란 의미입니다. 즉, ODL은 "언제든지 요구할 때 로딩한다"는 의미로 이해할 수 있습니다.&#x20;

이 방법은 최적화에 사용됩니다. 전체 웹페이지의 리소스를 한 번에 로딩하는 것이 아니라, 사용자가 필요할 때까지 미뤄두다 원하는 시점(요구되는 순간)에 리소스를 로딩합니다. 대표적인 예로 인피니티(무한) 스크롤을 들 수 있습니다. 사용자가 스크롤 할 때 리소스를 "온 디멘드 로딩"합니다.
{% endhint %}

[mini-css-extract-plugin](https://www.npmjs.com/package/mini-css-extract-plugin) 패키지를 프로젝트에 설치한 후, Webpack 구성 파일을 열어 플러그인을 설정합니다.

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

```bash
npm i mini-css-extract-plugin -D
```

{% endtab %}

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

```javascript
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  plugins: [
    // 플러그인 인스턴스 생성
    new MiniCssExtractPlugin({
      // 플러그인 옵션 설정
      linkType: false, // 기본 값 'text/css'
    }
    })
  ],
  module: {
    rules: [
      {
        test: /\.css$/i,
        // CSS Loader → MiniCssExtractPlugin.loader 로더를 사용해 추출 
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      }
    ]
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="danger" %}
"style-loader"와 MiniCssExtractPlugin.loader를 함께 사용하면 안됩니&#xB2E4;*!*
{% endhint %}

## 모드 별, 플러그인 설정

mini-css-extract-plugin 플러그인은 JavaScript 파일 안에서 호출되는 스타일 코드를 [청크(Chunk)](https://en.wikipedia.org/wiki/Chunk_\(information\))에서 파일로 추출하므로 개발 중에는 플러그인을 사용하지 않는 것이 좋습니다. 즉, 개발이 끝난 후 배포 할 때 사용하면 좋습니다.

개발 모드에서는 CSS를 여러 번 수정하고 DOM에 \<style> 요소의 코드로 주입하는 것이 훨씬 빨리 작동하므로 "style-loader"를 사용하고, 배포 모드에서는 MiniCssExtractPlugin.loader를 사용하려면 다음과 같이 설정합니다.

{% hint style="warning" %}
이 설정은 [환경 변수 등록](https://yamoo9.gitbook.io/webpack/webpack/webpack-plugins/manage-env-variables) 후, 정상 작동합니다. **환경 변수 등록 후에 사용하여야 합니다*****!***
{% endhint %}

{% hint style="success" %}
아래 "스타일 로더 설정" 코드는 Sass, SCSS, CSS 파일을 모두 처리하도록 변경되었습니다.
{% endhint %}

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

```javascript
const webpack = require('webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

/* -------------------------------------------------------------------------- */

// 개발 모드 감지
const isDevMode = process.env.NODE_ENV.includes('dev')

/* -------------------------------------------------------------------------- */

// 개발,배포 모든 모드에서 사용되는 Webpack 플러그인 목록(배열)
const plugins = [
  new webpack.EnvironmentPlugin({
    NODE_ENV: 'development',
  }),
]

// 배포 모드인 경우 plugins에 배포용 플러그인 추가
if (!isDevMode) {
  plugins.push(
    new MiniCssExtractPlugin({
      linkType: false,
      filename: '[name].[contenthash].css',
      chunkFilename: '[id].[contenthash].css',
    })
  )
}

/* -------------------------------------------------------------------------- */

module.exports = {
  // 플러그인 설정
  plugins,
  module: {
    rules: [
      // 스타일 파일 로더
      {
        test: /\.(sa|sc|c)ss$/i,
        exclude: /node_modules/,
        use: [
          isDevMode ? 'style-loader' : MiniCssExtractPlugin.loader,
          'css-loader',
          'sass-loader',
        ],
      },
      // ...
    ],
  },
  // ...
}
```

{% endtab %}
{% endtabs %}

[빌드 명령](https://yamoo9.gitbook.io/webpack/webpack/manage-env-variables#build)을 실행하여 출력한 결과를 살펴보면, 개별 CSS 파일이 성공적으로 생성되었습니다.

![](https://1127883942-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MTbexhuB2p5ev8QaGgg%2F-MTj6yPhRL9k8H_J_G2B%2F-MTj8Nhx8ruZR9JXwfOD%2Fimage.png?alt=media\&token=ced27b13-2d74-4268-b4af-2219f70d98be)

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

{% embed url="<https://webpack.js.org/plugins/mini-css-extract-plugin/>" %}
