# CRACO

**CRACO**(**C**reate **R**eact **A**pp **C**onfiguration **O**verride)는 Create React App 구성을 덮어쓸 수 있도록 도와줍니다.

![](/files/-MUvRgQl_qnfqht1fryO)

CRA `eject` 명령을 사용하지 않고도 프로젝트 루트 위치에 `craco.config.js` 파일을 추가한 다음 ESLint, Babel, PostCSS, Sass 구성 등을 사용자 입맛에 맞게 수정할 수 있어 유용합니다.

## 패키지 설치 <a href="#install-package" id="install-package"></a>

[@craco/craco](https://www.npmjs.com/package/@craco/craco) 패키지를 프로젝트에 설치합니다.

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

```bash
npm i -D @craco/craco
```

{% endtab %}
{% endtabs %}

## package.json

NPM 스크립트 명령이 CRACO를 사용하도록 `start`, `build`, `test` 명령을 변경합니다.

{% tabs %}
{% tab title="package.json" %}

```bash
"scripts": {
  "start": "craco start",
  "build": "craco build",
  "test": "craco test",
  "eject": "react-scripts eject"
}
```

{% endtab %}
{% endtabs %}

## craco.config.js

CRACO 구성 파일을 프로젝트 루트 위치에 생성합니다.

```bash
.
├── node_modules/
├── craco.config.js # CRACO 구성 파일
└── package.json
```

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

```javascript
module.exports = {
  // ...
}

// 또는

module.exports = ({env}) => {
  return {
    // ...
  }
}
```

{% endtab %}
{% endtabs %}

## CRACO 구성 <a href="#config-craco" id="config-craco"></a>

`craco.config.js` 파일 구성은 다음과 같은 구조로 작성합니다. 모든 내용을 작성할 필요는 없고 덮어쓰기 하고 싶은 구성만 추가하면 됩니다.

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

```javascript
const {
  when,
  whenDev,
  whenProd,
  whenTest,
  ESLINT_MODES,
  POSTCSS_MODES,
} = require('@craco/craco')

module.exports = {
  reactScriptsVersion: 'react-scripts' /* 기본 값 */,
  style: {
    css: {
      loaderOptions: {
        // CSS 구성 옵션 
        // 참고: https://github.com/webpack-contrib/css-loader
      }
    },
    sass: {
      loaderOptions: {
        // Sass 구성 옵션 
        // 참고: https://github.com/webpack-contrib/sass-loader
      }
    },
    postcss: {
      mode: 'extends' /* (기본 값) */ || 'file',
      plugins: [],
      env: {
        autoprefixer: {
          // autoprefixer 옵션 
          // https://github.com/postcss/autoprefixer#options
        },
        stage: 3 /* 참고: https://cssdb.org/#staging-process */,
        features: { /* 참고: https://preset-env.cssdb.org/features */ },
      },
      loaderOptions: {
        // postcss-loader 구성 옵션
        // 참고: https://github.com/postcss/postcss-loader
      }
    },
  },
  
  eslint: {
    enable: true /* 기본 값 */,
    mode: 'extends' /* 기본 값 */ || 'file',
    configure: {
      // eslint 구성 옵션
      // https://eslint.org/docs/user-guide/configuring
    }
    pluginOptions: {
      // eslint 플러그인 구성 옵션
      // 참고: https://github.com/webpack-contrib/eslint-webpack-plugin#options
    }
  },
  
  babel: {
    presets: [],
    plugins: [],
    loaderOptions: {
      // babel-loader 구성 옵션
      // 참고: https://github.com/babel/babel-loader
    }
  },
  
  typescript: {
    enableTypeChecking: true /* 기본 값 */,
  },
  
  webpack: {
    alias: {},
    plugins: {
      // 플러그인 배열
      add: [],
      // 플러그인 생성자 이름 배열("StyleLintPlugin", "ESLintWebpackPlugin")
      remove: [] 
    },
    configure: {
      // webpack 구성 옵션
      // 참고: https://webpack.js.org/configuration
    }
  },
  
  jest: {
    babel: {
      addPresets: true /* 기본 값 */,
      addPlugins: true /* 기본 값 */,
    },
    configure: {
      // Jest 구성 옵션 
      // 참고: https://jestjs.io/docs/en/configuration
    }
  },
  
  devServer: {
    // devServer 구성 옵션 
    // 참고: https://webpack.js.org/configuration/dev-server/#devserver
  },
  
  plugins: [
    // CRACO 플러그인
    // 참고: https://bit.ly/3reUqet
  ]
}

```

{% endtab %}
{% endtabs %}

## \[플러그인] sass sourcemap <a href="#sass-sourcemap" id="sass-sourcemap"></a>

Sass 소스맵을 활성화 하려면 CRACO의 [overrideWebpackConfig](https://github.com/gsoft-inc/craco/blob/master/packages/craco/README.md#overridewebpackconfig) 함수를 사용해 Webpack 구성을 덮어써야 합니다. Sass 소스맵을 활성화 하는 CRACO 플러그인 파일을 아래와 같이 만든 후 작성합니다.

{% tabs %}
{% tab title="plugins/sass-sourcemap.js" %}

```javascript
module.exports = {

  // Webpack 구성 파일 덮어쓰기 설정
  overrideWebpackConfig: ({
    webpackConfig,
    cracoConfig,
    pluginOptions,
    context: { env, paths },
  }) => {
  
    // 탐색 함수
    function traverse(obj, callback) {
      if (Array.isArray(obj)) {
        obj.forEach((item) => traverse(item, callback))
      } else if (typeof obj === 'object' && obj !== null) {
        Object.keys(obj).forEach((key) => {
          if (obj.hasOwnProperty(key)) {
            callback(obj, key)
            traverse(obj[key], callback)
          }
        })
      }
    }
    
    // Webpack 구성 파일 탐색
    traverse(webpackConfig, (node, key) => {
      // key 값이 loader 이고
      if (key === 'loader') {
        // node[key] 값이 sass-loader, postcss-loader, css-loader인 경우
        if (
          node[key].indexOf('sass-loader') !== -1 ||
          node[key].indexOf('postcss-loader') !== -1 ||
          node[key].indexOf('css-loader') !== -1
        ) {
          // node의 options 값이 존재하면
          if (node.options) {
            // node.options 소스맵 활성화
            node.options.sourceMap = true
          }
        }
      }
    })
    
    // Webpack 구성 파일 내보내기
    return webpackConfig
  }
}
```

{% endtab %}
{% endtabs %}

`craco.config.js` 파일에 sass-sourcemap 플러그인 파일을 불러와 CRACO 플러그인 아이템으로 설정합니다.

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

```javascript
const sassSourcemapsPlugin = require('./plugins/sass-sourcemap')

module.exports = {
  plugins: [
    { plugin: sassSourcemapsPlugin },
  ],
}
```

{% endtab %}
{% endtabs %}

## \[플러그인] alias

[craco-alias](https://github.com/risenforces/craco-alias) 플러그인은 Webpack, Jest의 별칭을 등록하는데 유용합니다. 플러그인을 사용하려면 설치합니다.

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

```bash
npm i -D craco-alias
```

{% endtab %}
{% endtabs %}

`craco.config.js` 파일에 craco-alias 플러그인 파일을 불러와 CRACO 플러그인 아이템으로 설정합니다.

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

```javascript
const cracoAliasPlugin = require('craco-alias')

module.exports = {
  plugins: [
    {
      plugin: cracoAliasPlugin,
      options: {
        // 'tsconfig', 'options'(기본 값) 중 선택
        source: 'jsconfig', 
        // './' (기본 값)
        baseUrl: './src', 
        // 디렉토리 별칭 등록 {} (기본 값)
        aliases: {
          '@components/*': ['components/*', 'components']
        },
        // 디버깅 false(기본 값) → debug: false 
      }
    }
  ]
}
```

{% endtab %}
{% endtabs %}

## \[플러그인] favicons

[craco-favicons](https://github.com/rickysullivan/craco-favicons) 플러그인은 [favicon-webpack-plugin](https://github.com/jantimon/favicons-webpack-plugin) 플러그인을 활용하여 파비콘(favicons)을 자동 생성하므로 유용합니다. 플러그인을 사용하려면 설치합니다.

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

```bash
npm i -D craco-favicons
```

{% endtab %}
{% endtabs %}

`craco.config.js` 파일에 craco-favicons 플러그인 파일을 불러와 CRACO 플러그인 아이템으로 설정합니다.

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

```javascript
const cracoFaviconsPlugin = require('craco-favicons')

module.exports = {
  plugins: [
    {
      plugin: cracoFaviconsPlugin,
      // 제공된 모든 옵션은 favicons-webpack-plugin에 전달됩니다.
      // 참고: https://bit.ly/30dWLdX
      options: {
        logo: './src/assets/images/app-logo.svg',
        inject: true,
        prefix: 'static/icons/',
        favicons: {
          icons: {
            android: { offset: 10 },
            appleIcon: { offset: 10 },
            coast: false,
            yandex: false,
            appleStartup: { offset: 10 },
            firefox: false,
            windows: false,
          }
        }
      }
    }
  ]
}
```

{% endtab %}
{% endtabs %}

## \[플러그인] image optimizer

[craco-image-optimizer-plugin](https://github.com/kkulbae/craco-image-optimizer-plugin) 플러그인은 [image-webapck-loader](https://www.npmjs.com/package/image-webpack-loader) 플러그인을 활용하여 모든 이미지를 최적화 처리합니다. 플러그인을 사용하려면 설치합니다.

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

```bash
npm i -D craco-image-optimizer-plugin
```

{% endtab %}
{% endtabs %}

`craco.config.js` 파일에 플러그인 파일을 불러와 CRACO 플러그인 아이템으로 설정합니다.

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

```javascript
const imageOptimizerPlugin = require('craco-image-optimizer-plugin')

module.exports = {
  plugins: [
    {
      plugin: imageOptimizerPlugin,
      // 제공된 모든 옵션은 image-webpack-plugin에 전달됩니다.
      // 참고: https://github.com/tcoopman/image-webpack-loader#usage
      options: {
        mozjpeg: {
          progressive: true,
          quality: 65,
        },
        optipng: {
          enabled: false,
        },
        pngquant: {
          quality: [0.65, 0.9],
          speed: 4,
        },
        gifsicle: {
          interlaced: false,
        },
        webp: {
          quality: 75,
        }
      }
    }
  ]
}
```

{% endtab %}
{% endtabs %}

## 커스텀 템플릿 <a href="#custom-template" id="custom-template"></a>

필요하다면 CRACO 설정이 반영된 커스텀 템플릿을 다운로드 받아 사용할 수 있습니다.

{% embed url="<https://www.npmjs.com/package/cra-template-ko-craco>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yamoo9.gitbook.io/learning-react-app/tip-and-references/create-react-app/craco-eject.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
