Buffer is not defined in React-vite

Buffer is not defined after migrating from CRA(create react app)

Screenshot of error

"vite": "^2.7.12"

I try to add plugins, add define for Buffer, but it's not work.

const viteConfig = defineConfig({
/*    define: {
        "Buffer": {}
    },*/
    plugins: [reactRefresh(), react()],
    build: {
        rollupOptions: {
            input: {
                main: resolve('index.html'),
            },
        },
    },
    clearScreen: false
});

Upvotes: 35

Views: 41688

Answers (8)

Ida Amit
Ida Amit

Reputation: 1687

Add the following to vite.config.ts

import inject from '@rollup/plugin-inject'

export default defineConfig({
.......
    build: {
      rollupOptions: {
        plugins: [
          inject({ Buffer: ['buffer', 'Buffer'] })]
      }
    }
})

In addition, you need to

npm install --save  buffer

You can use it by

const encodedString = Buffer.from(myString).toString('base64');

The import { Buffer } from 'buffer' command is no needed

Upvotes: 0

sable
sable

Reputation: 504

The easiest solution I found was to install vite-plugin-node-polyfills (npm, repo).

npm i -D vite-plugin-node-polyfills

Below is a basic version of the config file, vite.config.js, using this plugin:

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

export default defineConfig({
  plugins: [nodePolyfills()]
})

The current accepted answer recommends @esbuild-plugins/node-globals-polyfill, which is outdated according to its repository, while the replacement suggested there, esbuild-plugin-polyfill-node, doesn't work for vite (see issue here).

Upvotes: 37

Rob van der Leek
Rob van der Leek

Reputation: 1828

A solution that worked for me when migrating from CRA to Vite, is to use a browser library for buffer support (instead of relying on a Node polyfill):

npm i buffer
import {Buffer} from 'buffer';
...
Buffer.from(...

Upvotes: 2

John
John

Reputation: 11429

I'm using vite (4.2.1) and near-api-js (2.1.0). I stumbled upon this github thread, which contained these vite config settings

In order to make the near api work for my project, I added these settings to vite.config.ts:

import { defineConfig } from 'vite';
// added below polyfills to make near-api-js work with vite
// npm install --dev @esbuild-plugins/node-globals-polyfill
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill';
// npm install --dev @esbuild-plugins/node-modules-polyfill
import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill';

fs.rmSync('dist', { recursive: true, force: true }); // v14.14.0

export default defineConfig({
  plugins: [],
  build: {
    commonjsOptions: {
      include: [],
    },
  },
  optimizeDeps: {
    disabled: false,
    esbuildOptions: {
      // Enable esbuild polyfill plugins
      plugins: [
        NodeGlobalsPolyfillPlugin({
          process: true,
          buffer: true,
        }),
        NodeModulesPolyfillPlugin(),
      ],
    },
  },
});

Upvotes: 1

Felix Niemeyer
Felix Niemeyer

Reputation: 408

Николай Сычев solution didn't work for me at first.

Instead, I succeeded by simply

  1. installing buffer as a dev dependency yarn add buffer (use npm equivalent if you use npm)

  2. and then adding it to the global scope in the index.html like this:

<html lang="en">
  <head>
    <script type="module">
      import { Buffer } from "buffer";
      window.Buffer = Buffer;
    </script>   
   ...

It also works for similar dependencies like process which you'd import in the index.html like this:

      import process from "process";
      window.process = process; 

Update

For a different project I needed util, which required process. The above suggested method didn't suffice in that case.

Instead I found out that @esbuild-plugins (for vite dev) and rollup-plugin-polyfill-node (for vite build) would successfully provide all these nodejs packages.

Here is a full vite.config.ts that works for me:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'
import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill'
import rollupNodePolyFill from 'rollup-plugin-polyfill-node'

export default defineConfig({
  plugins: [vue()],
  base: '', 
  optimizeDeps: {
    esbuildOptions: {
      // Node.js global to browser globalThis
      define: {
        global: 'globalThis'
      },
      // Enable esbuild polyfill plugins
      plugins: [
        NodeGlobalsPolyfillPlugin({
          buffer: true, 
          process: true,
        }), 
        NodeModulesPolyfillPlugin() 
      ]
    }
  }, 
  build: {
    rollupOptions: {
      plugins: [
        rollupNodePolyFill()
      ]
    }
  }
})

Be careful to use rollup-plugin-polyfill-node which is an updated and maintained fork of rollup-plugin-node-polyfills.

Upvotes: 26

David H&#233;rault
David H&#233;rault

Reputation: 73

Another approach is:

npm i -D rollup-plugin-polyfill-node

Then update vite.config.ts with the following:

import nodePolyfills from 'rollup-plugin-polyfill-node'
rollupOptions: {
  plugins: [
    // ...plugins
    nodePolyfills(),
  ],
  // ...rollupOptions
},

Upvotes: 1

Goutham J.M
Goutham J.M

Reputation: 2194

For me the above configuration did not work, I had to make changes in 3 files , in vite.config.ts , index.html and adding packages

1.Install Packages

yarn install process util buffer events
yarn add @esbuild-plugins/node-modules-polyfill

2.Update vite.config

import GlobalPolyFill from "@esbuild-plugins/node-globals-polyfill";
import react from "@vitejs/plugin-react";
import { resolve } from "path";
import { defineConfig } from "vite";

export default defineConfig({
    plugins: [react()],
    optimizeDeps: {
        esbuildOptions: {
            define: {
                global: "globalThis",
            },
            plugins: [
                GlobalPolyFill({
                    process: true,
                    buffer: true,
                }),
            ],
        },
    },
    resolve: {
        alias: {
            process: "process/browser",
            stream: "stream-browserify",
            zlib: "browserify-zlib",
            util: "util",
        },
    },
});

3.Update index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <link rel="icon" type="image/svg+xml" href="/src/assets/images/favicon.svg" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Vite App</title>
  <script>
    window.global = window;
  </script>
  <script type="module">
    import process from "process";
    import EventEmitter from "events";
    import {Buffer} from "buffer";
    window.Buffer = Buffer;
    window.process = process;
    window.EventEmitter = EventEmitter;
  </script>
</head>

<body>
  <div id="root"></div>
  <script type="module" src="./src/index.js"></script>
</body>
</html>

Upvotes: 6

Install this library

@esbuild-plugins/node-globals-polyfill

and add this in your vite.config.js

export default defineConfig({
    // ...other config settings
    optimizeDeps: {
        esbuildOptions: {
            // Node.js global to browser globalThis
            define: {
                global: 'globalThis'
            },
            // Enable esbuild polyfill plugins
            plugins: [
                NodeGlobalsPolyfillPlugin({
                    buffer: true
                })
            ]
        }
    }
})

add this libary import to your vite.config.js

import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'

Upvotes: 43

Related Questions