블록체인

[dapp] react에서 web3js 정상적으로 사용하기

멍개. 2022. 8. 28. 08:14

최신 리액트 버전에서 web3를 사용할 때 다음과 같이 에러가 발생합니다.

// src/App.js

import Web3 from 'web3'; // 에러발생 지점

function App() {

  const onClickHandler = async () => {

    const web3 = new Web3(
      window?.web3?.currentProvider //  메타마스크 프로바이더
      || 'http://localhost:8545'
    );
    const accounts = await web3.eth.requestAccounts();
    console.log(accounts)
    const tx = await web3.eth.sendTransaction({
      from: accounts[0],
      to: '0xAd46355359aE32263EaFE152a408D9D620844eda',
      value: web3.utils.toWei('1', 'ether'),
      data: ''
    })
    console.log(tx)
  }

  return (
    <div className="App">
      <button onClick={onClickHandler}>Send</button>
    </div>
  );
}

export default App;

web3를 import하는 지점에서 에러가 발생합니다.

최신 CRA에서 정상적으로 폴리필이 동작하지 않아 생기는 문제입니다.

 

$ npx create-react-app [프로젝트 이름]

$ npm install web3 web3-utils

추가 의존성 설치

$ npm install --save-dev react-app-rewired crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer process

웹팩 오버라이딩 하기

config-overrides.js

const webpack = require('webpack');

module.exports = function override(config) {
    const fallback = config.resolve.fallback || {};
    Object.assign(fallback, {
        "crypto": require.resolve("crypto-browserify"),
        "stream": require.resolve("stream-browserify"),
        "assert": require.resolve("assert"),
        "http": require.resolve("stream-http"),
        "https": require.resolve("https-browserify"),
        "os": require.resolve("os-browserify"),
        "url": require.resolve("url")
    })
    config.resolve.fallback = fallback;
    config.plugins = (config.plugins || []).concat([
        new webpack.ProvidePlugin({
            process: 'process/browser',
            Buffer: ['buffer', 'Buffer']
        })
    ])
    return config;
}

package.json script 수정

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

다시 실행하면 정상적으로 동작하는 모습을 볼 수 있습니다.