Front-end/React

React CRACO 설정

zakklee 2023. 2. 9. 01:24
728x90

Mi.Ti. - Panoramic view of Craco. Basilicata. Italy.

 


 

React 프로젝트 생성시 CRA를 많이 사용합니다. React 프로젝트에 필요한 여러 번들 라이브러리 및 설정들을 알아서 해주어 편하기 때문입니다. 하지만 알아서 해준다는 이 장점이 단점이 되기도 합니다.

 

webpack config를 수정해야 하는 경우가 그렇습니다. CRA v5 (react-script v5) 이상부터 사용하는 webpack v5는 더 이상 nodejs 함수의 polyfill을 기본으로 제공하지 않습니다. 이 polyfill을 webpack config에 설정해주어야 합니다. (원칙상 nodejs를 사용하는 server-side의 패키지들은 backend에서 처리하고 frontend에서 받아서 쓰는 것이 맞습니다.)

 

CRA는 webpack 설정을 알아서 해주기 때문에 webpack config를 숨기고 있습니다. 이를 수정하기 위해서는 eject를 해야하는데 그러면 CRA를 쓰는 이유가 없어집니다. eject 하지 않고 config를 수정할 수 있도록 도와주는 패키지들로 react-app-rewired, customize-cra, craco 가 있습니다.

 

@craco/craco vs customize-cra vs react-app-rewired

이 중에서 지금까지 maintained되고, CRA v5를 지원하는 것은 craco 뿐 입니다. 그래서 craco를 사용하는 방법을 알아보겠습니다.


설치

공식 문서를 따라 설치를 진행합니다.

https://craco.js.org/docs/getting-started/

 

Getting Started | CRACO

The current CRACO version requires Create React App 5 (react-scripts 5.x.x). If using an older version of CRA, use the appropriate version of CRACO.

craco.js.org

 

devDependency로 설치해줍니다.

npm install --save-dev @craco/craco

 

프로젝트 root 경로에 config 파일인 craco.config.js를 생성해줍니다. 그리고 package.json의 scripts에서 react-scripts 부분을 craco로 대체해줍니다.

"scripts": {
-  "start": "react-scripts start"
+  "start": "craco start"
-  "build": "react-scripts build"
+  "build": "craco build"
-  "test": "react-scripts test"
+  "test": "craco test"
}

 

craco.config.js 설정

가이드에 따르면 이 상태에서 npm run start를 하면 실행이 된다고 합니다. 하지만 저는 craco.config.js가 비어있어서 오류가 발생했습니다. 그래서 webpack config override를 진행하면서 craco.config.js를 작성해줍니다.

 

예시로 uitl과 buffer를 polyfill 해보았습니다. util과 buffer를 devDependency로 설치해줍니다.

npm install --save-dev util buffer

그리고 craco.config.js를 다음과 같이 작성해줍니다.

const webpack = require("webpack");

module.exports = {
  webpack: {
    configure: (config, { env, paths }) => {
      config.resolve = {
        ...config.resolve,
        fallback: {
          util: require.resolve("util/"),
          buffer: require.resolve("buffer/"),
        },
      };
      config.plugins.push(
        new webpack.ProvidePlugin({
          Buffer: ["buffer", "Buffer"],
        })
      );
      return config;
    },
  },
};

 

사실 polyfill 하려는 기능마다 config 작성 방식이 다를 수 있습니다. 그래서 그때그때 구글링을 통해 동작하는 방식을 찾아보아야합니다. 위 예제에서도 util 같은 경우 resolve에만 추가해주면 되지만 buffer는 resolve와 plugins에 모두 추가해줘야합니다.

 

speed-measure-webpack-plugin 설정

webpack에 설정된 plugin과 loader들의 속도를 speed-measure-webpack-plugin 패키지를 사용하여 측정해볼 수 있습니다. 이를 통해 너무 느린 부분을 제거하거나 대체하여 최적화를 진행할 수 있습니다. devDependency로 설치해줍니다.

npm install --save-dev speed-measure-webpack-plugin

craco.config.js에 추가해줍니다.

const webpack = require("webpack");
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");

module.exports = {
  webpack: {
    configure: (webpackConfig, { env, paths }) => {
    	...
      const cssPluginIndex = webpackConfig.plugins.findIndex((e) => e.constructor.name === "MiniCssExtractPlugin");
      const cssPlugin = webpackConfig.plugins[cssPluginIndex];
      const exportConfig = new SpeedMeasurePlugin().wrap(webpackConfig);
      exportConfig.plugins[cssPluginIndex] = cssPlugin;

      return exportConfig;
    },
  },
};

위 코드를 보면 new SpeedMeasurePlugin().wrap(webpackConfig) 를 바로 return 하고 있지 않습니다. MiniCssExtractPlugin 이라는 css plugin을 임시 저장했다가 다시 적용하고 있습니다. 이렇게 해주지 않으면 해당 css plugin이 설치되어있지만 찾지 못하는 오류가 발생합니다. git issue로 등록되어있으며 사용한 해결 방법 링크합니다.

https://github.com/stephencookdev/speed-measure-webpack-plugin/issues/167#issuecomment-1318684127

 

"You forgot to add 'mini-css-extract-plugin' plugin" · Issue #167 · stephencookdev/speed-measure-webpack-plugin

Webpack 5 fails as soon as I smp.wrap() my config, with the following error: ERROR in ..../Error.scss Module build failed (from ../../node_modules/mini-css-extract-plugin/dist/loader.js): Error: Yo...

github.com

 

esbuild-loader 적용

최근에 esbuild가 webpack을 대체하는 번들러로 떠오르고 있습니다. 소개 내용을 보면 webpack보다 100배 빠르다고 합니다.

https://esbuild.github.io/

 

esbuild - An extremely fast bundler for the web

esbuild An extremely fast bundler for the web Above: the time to do a production bundle of 10 copies of the three.js library from scratch using default settings, including minification and source maps. More info here. Our current build tools for the web ar

esbuild.github.io

하지만 아직 v0에서 minor 버전만 업데이트하고 있는 수준으로 현업에서 사용하기에는 위험 부담이 있습니다. 이때 사용할 수 있는 것이 esbuild-loader입니다. webpack과 함께 사용하면서 esbuild의 장점을 가져갈 수 있습니다. craco에는 이를 위한 패키지가 craco-esbuild로 따로 있어서 설정이 매우 쉽습니다. 

https://github.com/pradel/create-react-app-esbuild/blob/main/packages/craco-esbuild/README.md

 

GitHub - pradel/create-react-app-esbuild: Use esbuild in your create-react-app for faster compilation, development and tests

Use esbuild in your create-react-app for faster compilation, development and tests - GitHub - pradel/create-react-app-esbuild: Use esbuild in your create-react-app for faster compilation, developme...

github.com

 

devDependency로 craco-esbuild를 설치해줍니다.

npm install --save-dev craco-esbuild

그리고 craco.config.js에서 plugins로 추가해주기만 하면됩니다.

// craco.config.js
const CracoEsbuildPlugin = require('craco-esbuild');

module.exports = {
  plugins: [{ plugin: CracoEsbuildPlugin }],
};
728x90