Vite 'global is not defined'

48.6k views Asked by At

I'm creating a project using Vite with vanilla-ts, at one point I had to use the readdir method from the fs-extra package, but it created an error saying process is not defined, some suggested I place this code in my vite-config.ts file:

import { defineConfig } from 'vite'

export default defineConfig({
  define: {
    'process.env': {}
  }
})

That fixed the initial error but created a new one that read global is not defined, more research and by adding 'global': {} on the define object, like before fixed the error but created another one saying Cannot read properties of undefined (reading 'substr')

Code used:

import { readdirSync } from 'fs-extra';

const folders = readdirSync('./', { withFileTypes: true })
  .filter(dir => dir.isDirectory);

Vite version: ^2.9.5

FS-Extra version: ^9.0.13

12

There are 12 answers

1
basarat On

You are most likely using Vite for a frontend project. fs-extra (file access) / global (nodejs global) are not something that exist in the browser (frontend).

Fix

Use a backend project and export an API that you can then use from the Vite / frontend to make file system changes on the server.

2
Albert On

Omg, thank you, Patrick Hübl-Neschkudla !

What worked for me was to define global: 'window', this way, libraries depending on global.something worked (eg lodash used global.isFinite() which was throwing errors) – Patrick Hübl-Neschkudla Sep 13, 2022 at 8:27

I was struggling with this issue for 2 hours and finally found the solution from you.

For me, the issue was, AWS Authenticator needed to use Buffer package that required 'global' to be defined on vite config, while I also had Phaser package that was declaring global.somethingsomething in its main phaser.js code.

With the 'global' defined in vite config, running 'npm run build' failed when compiling phaser, saying there is unexpected token at the part it declares 'global: blah blah'.

When I don't define 'global' in vite config, then 'npm run build' would NOT fail, but the AWS Authenticator will fail to work and throw console.error, saying 'global' was not defined in Buffer.

Setting

define: {global: 'window'}

in vite.config solved this issue.

0
Sebastian Paduano On

Found this solution in Github. AWS SDK uses 'global' for some things. This is why it happens. Just use it on your index.html on your React project.

<!-- your index.html -->
<script>
/**
 * this is a hack for dragula
 * error: global is not defined
 */
var global = global || window
</script>
1
Ashe On
import react from '@vitejs/plugin-react';
import path from 'path';
export default defineConfig(({ mode }): UserConfig => {
 const isProduction = mode === 'production';
 const config: UserConfig = {
   plugins: [react()],
   build: {
     outDir: 'build',
     sourcemap: 'inline',
   },
   resolve: {
     alias: {
       '@': path.resolve(__dirname, 'src'),
     },
   },
 };
 if (!isProduction) {
   config.define = {
     'process.env': {},
     global: {},
   };
 }
 return config;
});
0
Shawn On

Referencing https://gist.github.com/FbN/0e651105937c8000f10fefdf9ec9af3d, I realized that:

  1. the issue seemed esbuild-specific
  2. I could fix it with:
export default defineConfig({
    optimizeDeps: {
      esbuildOptions: {
        define: {
          global: 'globalThis'
        }
      }
    }
  })
0
Thabiso Mohatlane On

The solution that worked for me, is by adding the below code to main.js or index.js.

declare global {
  interface Window {
    global: any;
  }
}

if (typeof window !== "undefined") {
  window.global = window;
}

12
Yairopro On

The problem is because vite doesn't define a global field in window as webpack does. And some libraries relies on it since webpack is much more older than vite.

Just insert at the very start, before any library import:

// init.js
window.global ||= window;

A good way to have the above code before any import is to write in new file, let's call it init.js, and import it as first.

// in index.js or main.js file

import "./init"
// import your app and libraries after... 
import App from './App'
import ...

✅ You're good to go !


About other answers saying to set the define in Vite configuration

WARNING
Because it's implemented as straightforward text replacements without any syntax analysis, we recommend using define for CONSTANTS only.
For example, process.env.FOO and APP_VERSION are good fits. But process or global should not be put into this option. Variables can be shimmed or polyfilled instead.

From Vite official documentation

0
hamdi islam On

setting an empty global inside your vite config can break other libraries such as react-pdf, so the best and easiest way is to add it to your index.html file as follows:

<script>
    if (global === undefined) {
      var global = window;
    }
  </script>
0
Aleksander K On

Sometimes we have 2 errors related to varialble global

1: global is not define
2. _global is not define

When we encountered these 2 errors in vite.js, we can resolve by: `

export default defineConfig({
  build: {
    sourcemap: true,
  },
  define: {
    _global: {},
  },
  plugins: [react(), EnvironmentPlugin(['VITE_APP_TEXT'])],
  publicDir: 'public',
  resolve: {
    alias: [{ find: '@', replacement: resolve(__dirname, 'src') }],
  },
  server: {
    host: true,
    port: 3000,
  },
})

and updateindex.html` by:

if (typeof window !== "undefined") {
    window.global = window;
}
4
Dominik Bisiakowski On

another solutions:

  export default defineConfig({
    define: {
      global: {},
    },
  })

But be careful: For example, process.env.FOO and APP_VERSION are good fits. But process or global should not be put into this option. Variables can be shimmed or polyfilled instead.

source: https://vitejs.dev/config/shared-options.html#define

2
Amir M. Mohamadi On

As mentioned here, I defined the global in my vite.config.ts file, it worked for development, but build had error.

1- Fix the development error:

Simply, I added that global conditionally because having it for production causes builds getting failure.

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";

export default defineConfig(({ mode }) => {
  const config = {
    plugins: [react()],
    define: {} as any,
  };

  if (mode === "development") {
    config.define.global = {};
  }

  return config;
});

2- Fix the production error:

In my case was a React app, I added the snippet below at the top of the main.tsx file:

window.global ||= window;
0
Kolawole Elijah On

This solved the issue for me..

Inside my vite.config.js, I added this

// ...every other thing, 
define: {
    global: {},
    "process.env": {}
  }

the final file was

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  define: {
    global: {},
    "process.env": {}
  }
});