CRACO

eject 명령 없이 CRA확장

CRACO(Create React App Configuration Override)는 Create React App 구성을 덮어쓸 수 있도록 도와줍니다.

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

패키지 설치

@craco/craco 패키지를 프로젝트에 설치합니다.

npm i -D @craco/craco

package.json

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

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

craco.config.js

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

.
├── node_modules/
├── craco.config.js # CRACO 구성 파일
└── package.json
module.exports = {
  // ...
}

// 또는

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

CRACO 구성

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

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
  ]
}

[플러그인] sass sourcemap

Sass 소스맵을 활성화 하려면 CRACO의 overrideWebpackConfig 함수를 사용해 Webpack 구성을 덮어써야 합니다. Sass 소스맵을 활성화 하는 CRACO 플러그인 파일을 아래와 같이 만든 후 작성합니다.

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
  }
}

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

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

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

[플러그인] alias

craco-alias 플러그인은 Webpack, Jest의 별칭을 등록하는데 유용합니다. 플러그인을 사용하려면 설치합니다.

npm i -D craco-alias

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

const cracoAliasPlugin = require('craco-alias')

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

[플러그인] favicons

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

npm i -D craco-favicons

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

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,
          }
        }
      }
    }
  ]
}

[플러그인] image optimizer

craco-image-optimizer-plugin 플러그인은 image-webapck-loader 플러그인을 활용하여 모든 이미지를 최적화 처리합니다. 플러그인을 사용하려면 설치합니다.

npm i -D craco-image-optimizer-plugin

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

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,
        }
      }
    }
  ]
}

커스텀 템플릿

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

Last updated

Was this helpful?