theanh098
theanh098

Reputation: 43

How can I use Buffer, process in Vite app?

I'm using wagmi in typescript react app setup by Vite.

I got some issue ex:

"global is not defined", "buffer is not defined"

And I tried it again with some code in main.tsx:

import { Buffer } from 'buffer';
import process from 'process';

window.global = window;
window.Buffer = Buffer;
window.process = process;

But I still get some error ex: "Module "process" has been externalized for browser compatibility. Cannot access "process.versions" in client code."

Error will occur when I connect to coinbase or walletconnect connector.

My vite.config.ts

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
//import Buffer from 'buffer';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  server: {
    port: 5000,
  },
  resolve: {
    alias: [{ find: '@', replacement: '/src' }],
  },
  define: {
    // global: 'window',
    // Buffer: Buffer,
    // process: process,
  },
});

Upvotes: 4

Views: 8687

Answers (2)

Matija
Matija

Reputation: 166

Many people ask same question here, but I cannot find proper answer. However, I found out perfect answer a few days ago.

we sometimes encounter error "process is not defined" in vite app. That's because Vite does not automatically polyfill Node.js modules.

https://vitejs.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility

Answer is https://www.npmjs.com/package/vite-plugin-node-polyfills

it says

Since browsers do not support Node's Core Modules, packages that use them must be polyfilled to function in browser environments. In an attempt to prevent runtime errors, Vite produces errors or warnings when your code references builtin modules such as fs or path.

Solution:

  1. Install the package as a dev dependency.

npm install --save-dev vite-plugin-node-polyfills

  1. Add the plugin to your vite.config.ts file.

import { defineConfig, loadEnv  } from 'vite'
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'
import { nodePolyfills } from 'vite-plugin-node-polyfills'
import react from '@vitejs/plugin-react'

export default defineConfig(({ command, mode }) => {
  // Load env file based on `mode` in the current working directory.
  // Set the third parameter to '' to load all env regardless of the `VITE_` prefix.
  const env = loadEnv(mode, process.cwd(), '')
  return {
    plugins: [
      nodePolyfills(), // this is necessary to avoid "process is not defined issue"
      react()]
  }

})

You can customize it when you need

import { defineConfig } from 'vite'
import { nodePolyfills } from 'vite-plugin-node-polyfills'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    nodePolyfills({
      // To add only specific polyfills, add them here. If no option is passed, adds all polyfills
      include: ['path'],
      // To exclude specific polyfills, add them to this list. Note: if include is provided, this has no effect
      exclude: [
        'http', // Excludes the polyfill for `http` and `node:http`.
      ],
      // Whether to polyfill specific globals.
      globals: {
        Buffer: true, // can also be 'build', 'dev', or false
        global: true,
        process: true,
      },
      // Override the default polyfills for specific modules.
      overrides: {
        // Since `fs` is not supported in browsers, we can use the `memfs` package to polyfill it.
        fs: 'memfs',
      },
      // Whether to polyfill `node:` protocol imports.
      protocolImports: true,
    }),
  ],
})

I hope this will help everybody a lot. Good Luck

Upvotes: 3

flydev
flydev

Reputation: 5674

To get buffer and process working, do the following:

  1. install buffer and process: npm install buffer process

  2. edit index.html to add some js:

<!-- node // buffer-->
<script>window.global = window;</script>
<script type="module">
    import { Buffer } from "buffer/"; // <-- no typo here ("/")
    import process from "process";
   
    window.Buffer = Buffer;
    window.process = process;
</script>
  1. edit your vite.config.js to add resolve.alias options:
export default defineConfig({
  [...]

  resolve: {
    alias: {
      process: "process/browser"
    }
  }
})
  1. in your component, import buffer (note the /):
import { Buffer } from 'buffer/'

[...]

Live example on stackblitz, open your console devtools on the preview, and look at the Uint8Array debug line.

You can give a read to my old answer for further setup like for process, events or even crypto.

Upvotes: 3

Related Questions