keccak.js Uncaught ReferenceError: Buffer is not defined

Viewed 1123

I have a little script in ReactJS :

import './App.css';
import { useState, useEffect } from 'react';
//Import de la librairie ethers (comme web3.js)
import { ethers } from 'ethers';
const { MerkleTree } = require('merkletreejs')
const keccak256 = require('keccak256');
const tokens = require('./tokens.json')

function App() {

  function isWhitelisted() {
    let tab = [];
    tokens.map(token => {
      tab.push(token.address);
    })
    const leaves = tab.map(v => keccak256(v));
    console.log(leaves);
    const tree = new MerkleTree(leaves, keccak256, { sort: true });
    const leaf = keccak256("0x7D8a1f6A5efc16E88FeF87E7745EAc2F5Cbc88D7")
    const proof = tree.getHexProof(leaf);
  }

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

export default App;

Sadly, I have this error when executing the script :

keccak.js:41 Uncaught ReferenceError: Buffer is not defined
    at Keccak.update (keccak.js:41)
    at keccak256 (keccak256.js:11)
    at App.js:16
    at Array.map (<anonymous>)
    at isWhitelisted (App.js:16)
    at HTMLUnknownElement.callCallback (react-dom.development.js:3945)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:3994)
    at invokeGuardedCallback (react-dom.development.js:4056)
    at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4070)
    at executeDispatch (react-dom.development.js:8243)

So the error is right there :

const leaves = tab.map(v => keccak256(v));

But I can't find a solution sadly, can you guys help me plz ? Thx !

4 Answers

Okay so I have found the error, when changing in the dependencies

"react-scripts": "5.0.0",

to

"react-scripts": "4.0.3",

it works, I really don't understand why.. if someone knows...

But downgrading react-scripts from 5.0.0 to 4.0.3 (Not to mention I don't like the idea of downgrading in first place) results in other problems: Node.js 17.0.1 Gatsby error - "digital envelope routines::unsupported ... ERR_OSSL_EVP_UNSUPPORTED"

Which was easily dealt with by adding "--openssl-legacy-provider"

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

But the next problem when you build:

$ npm run build
> xxx@0.1.0 build
> react-scripts --openssl-legacy-provider build

Creating an optimized production build...
Failed to compile.

./node_modules/framer-motion/dist/es/components/AnimatePresence/index.mjs
Can't import the named export 'Children' from non EcmaScript module (only default export is available)

In the end, I got pass by downgrading framer-motion to 4.1.7:

{
  "name": "darksecret",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@chakra-ui/react": "^2.0.0",
    "@emotion/react": "^11.9.0",
    "@emotion/styled": "^11.8.1",
    "@openzeppelin/contracts": "^4.6.0",
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.2.0",
    "@testing-library/user-event": "^13.5.0",
    "Buffer": "^0.0.0",
    "keccak256": "1.0.6",
    "merkletreejs": "0.2.31",
    "react": "^18.1.0",
    "react-dom": "^18.1.0",
    "react-scripts": "4.0.3",
    "web-vitals": "^2.1.4",
    "framer-motion" : "4.1.7"
  },
  "scripts": {
    "start": "react-scripts --openssl-legacy-provider start",
    "build": "react-scripts --openssl-legacy-provider build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }

So, that's how i got to bottom in the end. But as i said, I didn't like downgrading to begin with. Anyone with better approach please? I am new to React.

(Whoosh, made thru this but another couple hours wasted)

I didnt mention after I move the React app from linux to Window, I still faced another error "node.exe: bad option: --openssl-legacy-provider"

And also when deployed to Digitalocean:

[2022-05-26 01:29:36] Running custom build command: npm run build
[2022-05-26 01:29:37] 
[2022-05-26 01:29:37] > felinesoulmate_web@0.1.0 build
[2022-05-26 01:29:37] > react-scripts --openssl-legacy-provider build
[2022-05-26 01:29:37] 
[2022-05-26 01:29:37] /layers/heroku_nodejs-engine/nodejs/bin/node: bad option: --openssl-legacy-provider
[2022-05-26 01:29:37] building: exit status 9
[2022-05-26 01:29:37] ERROR: failed to build: exit status 1
[2022-05-26 01:29:51] 
[2022-05-26 01:29:51] For documentation on the buildpacks used to build your app, please see:
[2022-05-26 01:29:51]    Node.js: https://do.co/apps-buildpack-node
[2022-05-26 01:29:51] 
[2022-05-26 01:29:51]  ! Build failed (145)

omg I dont really like React

You don't need to downgrade react-scripts, just do the following: npm install --save buffer If it doesn't work, add this line in your react script and you should be fine: window.Buffer = window.Buffer || require("buffer").Buffer;

Buffer is a Nodejs library and does not exist in the browser

There are multiple ways to fix this.

The simplest way is to install it via npm and register it into the global variable.

  1. run npm install buffer

  2. in the main.js, add these lines.

import { Buffer } from "buffer/";
window.Buffer = window.Buffer || Buffer;

Another way is to use a polyfill.

Related