near-api-js
near-api-js copied to clipboard
Buffer is not defined
Describe the bug i use vite to hold near-api-js
Uncaught (in promise) ReferenceError: Buffer is not defined bytesJsonStringify account.js:27 viewFunction account.js:365 DexViewFunction FT.ts:39 getUserRegisteredTokens FT.ts:66 useTokens useToken.ts:9 React 5 unstable_runWithPriority scheduler.development.js:468 React 3 workLoop scheduler.development.js:417 flushWork scheduler.development.js:390 performWorkUntilDeadline scheduler.development.js:157 js scheduler.development.js:180 js scheduler.development.js:644 __require2 chunk-ENMAWK7U.js:36 js index.js:6 __require2 chunk-ENMAWK7U.js:36 React 2 __require2 chunk-ENMAWK7U.js:36 js React __require2 chunk-ENMAWK7U.js:36react-dom:1 account.js:27:4
Expected behavior no error
Screenshots If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
- OS: [e.g. MacOS]
- Version [e.g. 22]
Additional context start project with vite
The issue is that Buffer is automatically polyfilled in Browserify, but Vite doesn't use near-api-js
browser bundle, nor does it bundle at all in development (it's best feature). The downside is that Node.js libraries have to be polyfilled manually. I'm not saying whether or not near-api-js
should address this issue, but just offering a workaround.
To get it to work, I had to do:
yarn add --dev buffer @rollup/plugin-inject
main.ts (entrypoint)
import { Buffer } from 'buffer'
globalThis.Buffer = Buffer;
import { createApp } from 'vue'
import App from './App.vue'
...
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import inject from '@rollup/plugin-inject'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
inject({ Buffer: ['buffer', 'Buffer'] }),
vue()
]
})
Altering either one of main.ts
or vite.config.ts
should be sufficient, but when altering only main.ts
, I would bet a Buffer is not defined
error after logging in with NEAR. When altering only vite.config.ts
, the app wouldn't load and the error was that buffer
has no export Buffer
. It took both to make it work.
following on from @rhythnic's comment above. i had to do the following to get it working in a standard create-react-app project
npm i Buffer
then add in index.js
import { Buffer } from "buffer"; global.Buffer = Buffer;
See related earlier issue and PR: https://github.com/near/near-api-js/issues/747 and see also https://stackoverflow.com/q/70296914/470749
This also happens if you try to bundle your app with esbuild and --format=esm
.
$ esbuild src/index.ts --bundle --outfile=dist/index.mjs --format=esm --minify
> node_modules/safe-buffer/index.js:3:21: error: Could not resolve "buffer" (use "--platform=node" when building for node)
3 │ var buffer = require('buffer')
╵ ~~~~~~~~
The reason why it tries to bundle buffer
module from Node comes from the js-sha256 dependency, which has this 'unsafe eval' line: https://github.com/emn178/js-sha256/blob/master/src/sha256.js#L84
Esbuild recognizes this and tries to bundle it.
Maybe it would be an idea to switch to another sha256 dependency? It seems to be unmaintained and the respective issue on their side is open for a long time: https://github.com/emn178/js-sha256/issues/26
Just a temp solution
install buffer
npm/yarn install buffer
In the index.ts file, add the following code.
import * as buffer from "buffer";
// issue of near-api-js
// https://github.com/near/near-api-js/issues/757
(window as any).Buffer = buffer.Buffer;
This is not work production build.
I found a fix that fixed the Buffer error for me.
https://github.com/vitejs/vite/discussions/2785
npm add node-stdlib-browser
npm add -D vite-plugin-node-stdlib-browser
// vite.config.js
import { defineConfig } from 'vite'
import nodePolyfills from 'vite-plugin-node-stdlib-browser'
export default defineConfig({
// other options
plugins: [nodePolyfills()]
})
Hope this helps
Just resolved this error in a CRA. Follow this link: resolve buffer error in create-react-app
@gtsonevv we should check if this issue is still relevant now that we've replace js-sha256