web3-onboard icon indicating copy to clipboard operation
web3-onboard copied to clipboard

[Bug]: walletconnect with vite runtime global/buffer not defined

Open syffs opened this issue 3 years ago • 5 comments

Current Behavior

using web3-onboard with SvelteKit, import of '@web3-onboard/walletconnect' is failing for on 2 points as browser errors:

  • "global is not defined": can fix it by adding this to vite.config.js, but it's creating other issues for libs which includes some global.js files, which then gets translated to globalThis.js and throw (@sentry/core in my case)
/** @type {import('vite').UserConfig} */
const config = {
	define: {
		global: 'globalThis' // <== here
	},
...
  • "Buffer is not defined": I do have polyfills but I guess they're not getting through for some reason
import nodePolyfills from 'rollup-plugin-polyfill-node';
/** @type {import('vite').UserConfig} */
const config = {
...
	build: {
		rollupOptions: {
			plugins: [
				// Enable rollup polyfills plugin
				// used during production bundling
				nodePolyfills()
			]
		}
	}
...

It seems that walletconnect faces the same kind of issue when standalone, but @web3-onboard/walletconnect doesnt include an UMD build to workaround it

Also weirdly, walletconnect does work through vite dev, but not once built.

Expected Behavior

dynamic import should be seamless.

Steps To Reproduce

using SvelteKit & vite, here is a similar setup

What package is effected by this issue?

@web3-onboard/walletconnect

Is this a build or a runtime issue?

Runtime

Package Version

2.1.2

Node Version

16.16.0

What browsers are you seeing the problem on?

Firefox, Chrome, Microsoft Edge

Relevant log output

Uncaught (in promise) ReferenceError: Buffer is not defined
    at Er (index-340e11d4.js:1:44728)
    at Ht (index-340e11d4.js:1:45066)
    at Module.dr [as generateKey] (index-340e11d4.js:1:76479)
    at sn._generateKey (index-340e11d4.js:1:74081)
    at sn.createSession (index-340e11d4.js:1:65154)
    at d.code (index-ad162ce8.js:1:2732)
    at new Promise (<anonymous>)
    at R.request (index-ad162ce8.js:1:2668)
    at Gp (index-b6702a51.js:106:13299)
    at he (index-b6702a51.js:203:6461)


### Anything else?

_No response_

### Sanity Check

- [X] If this is a build issue, I have included my build config. If this is a runtime issue, I have included reproduction steps and/or a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example).

syffs avatar Sep 21 '22 18:09 syffs

@syffs thank you for submitting an issue! Can you give this a try:

import { sveltekit } from '@sveltejs/kit/vite'
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'
import type { UserConfig } from 'vite'

const config: UserConfig = {
  plugins: [sveltekit()],
  optimizeDeps: {
    esbuildOptions: {
        // Node.js global to browser globalThis
        define: {
            global: 'globalThis'
        },
        // Enable esbuild polyfill plugins
        plugins: [
            NodeGlobalsPolyfillPlugin({
                buffer: true
            })
        ]
    }
}
}

export default config

Adamj1232 avatar Sep 21 '22 18:09 Adamj1232

@Adamj1232 thanks for the quick response!

I did try something similar following this. It's giving me the same error, I also tried including walletconnect manually to optimizeDeps (without success):

  optimizeDeps: {
		include: [
			'@web3-onboard/walletconnect',
			'@web3-onboard/core',
			'@web3-onboard/injected-wallets'
		],
  }

syffs avatar Sep 21 '22 20:09 syffs

This is a non-sense: but here is a workaround (client-side only):

	(window as any).global = globalThis;
	global.Buffer = global.Buffer || (await import('buffer')).Buffer;
	// global.process = global.process || (await import('process')).default; // coinbase
	const walletConnect = (await import('@web3-onboard/walletconnect')).default();

syffs avatar Sep 21 '22 23:09 syffs

This is a non-sense: but here is a workaround (client-side only):


	(window as any).global = globalThis;

	global.Buffer = global.Buffer || (await import('buffer')).Buffer;

	// global.process = global.process || (await import('process')).default; // coinbase

	const walletConnect = (await import('@web3-onboard/walletconnect')).default();

Hmmm very Interesting! Is this within your vite.config? If so can can you send your whole configuration over? Glad you got it working! cc @taylorjdawson 👀

Adamj1232 avatar Sep 22 '22 03:09 Adamj1232

This is a non-sense: but here is a workaround (client-side only):

	(window as any).global = globalThis;

	global.Buffer = global.Buffer || (await import('buffer')).Buffer;

	// global.process = global.process || (await import('process')).default; // coinbase

	const walletConnect = (await import('@web3-onboard/walletconnect')).default();

Hmmm very Interesting! Is this within your vite.config? If so can can you send your whole configuration over? Glad you got it working! cc @taylorjdawson 👀

It's not in my vite.config, it's directly in the file setting up web3-onboard and walletconnect. My vite.config has nothing out of the ordinary:

const config: UserConfig = {
	plugins: [
		development &&
			nodePolyfills({
				include: ['node_modules/**/*.js', new RegExp('node_modules/.vite/.*js')]
			}),
		sveltekit()
	],
	build: {
		chunkSizeWarningLimit: 1900,
		rollupOptions: {
			plugins: [
				// Enable rollup polyfills plugin
				// used during production bundling
				nodePolyfills()
			]
		},
		commonjsOptions: {
			transformMixedEsModules: true
		}
	}
};

I still fail to understand why it's working in dev but not once built for prod

syffs avatar Sep 22 '22 09:09 syffs

@syffs FYI I got it working using this config

import { defineConfig } from 'vite'

import react from '@vitejs/plugin-react'
import nodePolyfills from 'vite-plugin-node-stdlib-browser'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react(), nodePolyfills()],
  optimizeDeps: {
    exclude: ['@ethersproject/hash', 'wrtc'],
    include: ['js-sha3', '@ethersproject/bignumber']
  }
})

taylorjdawson avatar Oct 21 '22 22:10 taylorjdawson

This fixed my issue using svelte/vite

import Buffer from "buffer";

(window as any).global = globalThis;
global.Buffer = Buffer.Buffer;

ryespresso avatar Nov 07 '22 11:11 ryespresso

@syffs Closing for now, please feel free to re-open if you think that this issue is not resolved 👍🏾

taylorjdawson avatar Nov 08 '22 00:11 taylorjdawson