FrontEnd/React

[FrontEnd/React] craco 라이브러리 설치: CRA 환경에서 Webpack 환경 설정 방법(브라우저에서 Node.js 모듈 폴리필하기)

수빈2022 2024. 7. 12. 11:12
더보기

✅ 문제 상황 및 해결 아이디어 확인하기

문제상황
: React 애플리케이션에서 웹팩(Webpack) 빌드 에러 발생

CRA로 생성한 리액트 앱에서 자연어 처리를 위해 natural 라이브러리를 사용하려고 하니, url 모듈이나 util 모듈 등을 찾을 수 없다는 에러가 발생했습니다. 즉, node.js의 핵심 모듈에 대한 폴리필(polyfill)이 없어서 발생된 문제입니다.

*polyfill: 구형 브라우저 미지원 문법 등을 대응하기 위한 코드

 

문제상황 재연
: natural 라이브러리 설치 → 소스 코드에 라이브러리 import
npm install natural

위 명령어로 라이브러리를 설치한 뒤에, 소스 코드 내에 require('natural') 또는 import natural from 'natural'를 작성하면, 위의 에러가 발생합니다.

*natural 라이브러리가 아니더라도, 외부 모듈을 사용할 때 웹팩 빌드 에러가 발생되는 경우 아래를 따라 문제를 해결할 수 있습니다.

 

문제 해결 아이디어
: webpack.config 파일을 만들어 폴리필 정보를 입력
(*유의점: CRA 특징 상, croca를 이용해 webpack.config 파일을 만들어야 된다.)

 

CRA 특징

CRA(Create React App)는 one build dependency(빌드 과정과 프로젝트의 의존성을 간소화하기 위해 폴리필 설정을 최소화하는 방식)를 갖게 하기 위해 사용자에게 최소한의 기능만 제공합니다. 즉, 사용자는 Webpack, Babel, ESLint 등 간의 설정에 대해서 신경쓰지 않아도 됩니다.

*아래 포스팅에서 CRA에 대해 자세히 다루고 있으니 참고하시면 좋을 것 같습니다.

 

[React] create-react-app (CRA) 기초 정리 (Feat. 환경변수)

Create-React-App(CRA) 란? - 리액트 개발환경을 쉽게 구축해준다.(by 페이스북 리액트팀) - 대략 아래의 것들 + 알파가 자동으로 세팅된다. webpack(모듈+라이브러리 번들링) babel(jsx 컴파일) jest(테스트) esl

curryyou.tistory.com

 

 

웹팩의 필요성

웹팩은 자바스크립트 모듈 번들러로, 의존성이 있는 모듈을 하나로 묶는 기능을 제공합니다. 프로젝트 성격에 따라 외부 모듈을 추가해야 될 땐, 프로젝트에 사용하려는 모듈을 설치한 뒤 웹팩 설정 파일을 수정하면 됩니다.

 

CRA로 만든 프로젝트에서 craco를 사용하는 이유

하지만, CRA에서는 one build dependency를 지원하기 위해 웹팩 설정 파일을 사용자에게 제공하지 않는다고 했습니다. 그래서 프로젝트를 커스텀하길 바라는 사용자를 위해 기본적으로 eject 스크립트 기능을 제공합니다.

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

 

eject는 '꺼내다'라는 뜻으로, eject 스크립트를 수행하면 webpack, babel 등의 모든 설정과 모든 패키지 의존성을 CRA로부터 가져올 수 있습니다. 프로젝트에 웹팩이나 바벨 등의 설정파일이 생기지만 eject를 한 번 한 번 수행하면 모든 설정과 의존성을 개발자가 직접 관리해야 된다는 문제가 있습니다.

 

이럴 때는 CRA에서 제공하는 craco (Create React App Configuration Override) 또는 react-app-rewired 같은 도구를 사용하여 CRA가 관리하는 webpack 설정을 오버라이드하거나 확장할 수 있습니다. [craco 공식문서 바로가기]

 

*아래 포스팅에서 eject의 개념과 문제에 대해 자세히 다루고 있으니 참고하시면 좋을 것 같습니다.

 

Create-React-App에서 Eject사용안하기(customize-cra, react-app-rewired)

CRA를 쓰는 이유

medium.com

글이 길어질 것 같아 문제 상황 및 해결 방법에 대한 아이디어는 접은글로 작성했습니다.

아래는 craro 설치 및 Webpack 설정 파일에서 node.js 모듈을 폴리필하는 방법입니다.


1. craco 패키지 설치

npm install @craco/craco @craco/types

 

TypeScript를 사용하지 않는다면 @craco/types는 빼도 됩니다.


2. craco 설정 파일 생성

 

프로젝트의 루트에 craco.config.js 파일을 생성합니다. 

module.exports = {
  // 과정 4에서 작성할 예정
};

3. package.json, tsconfig.json 수정

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

 

react-scripts를 craco로 변경합니다. eject는 변경하지 않고 그대로 둬도 되지만, 어차피 사용할 일 없는 스크립트라서 통일성을 위해 변경했습니다.

 

타입스크립트를 사용하는 경우, tsconfig.json도 수정해야 됩니다. 2번 과정을 선행할 경우 자동으로 변경되어 있겠지만, 그렇지 않는다면 include 안에 1번 과정에서 생성한 파일명을 적으면 됩니다.

  "include": [
    "src",
    "craco.config.js" // 추가
  ]

4. 모듈 설치 및 웹팩 설정 파일 수정

webpack.config.js가 아닌 craco.config.js에서 웹팩을 설정하기 위해선, webpack 모듈을 불러와야 됩니다.

const webpack = require('webpack');

 

아래 코드에 필요한 모듈을 작성하면 됩니다. 모듈 정보를 모른다면 아래 글을 계속 참고해주세요.

module.exports = {
  webpack: {
    configure: (webpackConfig) => {
      webpackConfig.resolve.fallback = {
        ...webpackConfig.resolve.fallback,
        // 필요한 모듈들 추가
      };
      return webpackConfig;
    },
  },
};

 

4.1. 폴리필 목록 기입

에러 메시지를 기반으로 natural 라이브러리와 관련된 모듈을 설치하고 설정 파일에 폴리필 정보를 기입하는 과정입니다. 관련 내용은 해당 포스팅 상단의 '✅ 문제 상황 및 해결 아이디어 확인하기'를 참고해 주세요.

 

에러 메시지에 폴리필을 추가하기 위해 fallback으로 추가해야 되는 구문과 설치 모듈 정보가 다 나와있습니다. polyfill 목록은 여러 개일 수 있으니 전부 참고해서 웹팩 설정 파일에 추가하고 모듈을 설치하면 됩니다.

// craco.config.js에 util 폴리필 기입
// ...
        "util": require.resolve("util/"),
// ...
# util 모듈 설치
npm install util

 

4.2. 미사용 모듈 명시

폴리필 정보와 관계 없이 단순히 모듈을 찾을 수 없다는 에러 메시지가 뜬다면, 해당 모듈을 사용하지 않겠다고 설정 파일에 명시만 하면 됩니다.

// craco.config.js에 net 모듈을 빈 모듈로 대체 기입
// ...
        "net": false,
// ...

 

4.3. craco.config.js 소스 코드 보기

natural 라이브러리에 대한 폴리필 정보입니다. 웹팩 설정 파일인 craco.config.js 작성했습니다.

const webpack = require('webpack');
const path = require('path');

module.exports = {
  webpack: {
    configure: (webpackConfig) => {
      webpackConfig.resolve.fallback = {
        ...webpackConfig.resolve.fallback,
        "url": require.resolve('url/'),
        "util": require.resolve("util/"),
        "crypto": require.resolve("crypto-browserify"),
        "buffer": require.resolve("buffer/"),
        "stream": require.resolve("stream-browserify"),
        "os": require.resolve("os-browserify/browser"),
        "path": require.resolve("path-browserify"),
        "process": require.resolve('process/browser'),
        "fs": false, // 'fs' 모듈을 빈 모듈로 대체
        "net": false, // 'net' 모듈을 빈 모듈로 대체
        "tls": false, // 'tls' 모듈을 빈 모듈로 대체
        "dns": false, // 'dns' 모듈을 빈 모듈로 대체
        // 필요한 모듈들 추가
      };
      return webpackConfig;
    },
  },
};

 

관련 모듈은 아래처럼 설치했습니다.

npm install url util crypto-browserify buffer stream-browserify os-browserify path-browserify process

감사합니다. :)

'FrontEnd > React' 카테고리의 다른 글

[FrontEnd/React] 리액트에서 개발 로그 만들기  (0) 2024.05.13