Skip to content

nodejs_compat + vite-plugin + require(node package) does not work with Vite 8 #11948

@sapphi-red

Description

@sapphi-red

What versions & operating system are you using?

System:
OS: Windows 11 10.0.26100
CPU: (32) x64 AMD Ryzen 9 9950X 16-Core Processor
Memory: 12.45 GB / 31.06 GB
Binaries:
Node: 24.12.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.22 - C:\Program Files\nodejs\yarn.CMD
npm: 11.6.2 - C:\Program Files\nodejs\npm.CMD
pnpm: 10.28.0 - C:\Program Files\nodejs\pnpm.CMD
bun: 1.3.3 - C:\Users\green\AppData\Local\Microsoft\WinGet\Links\bun.EXE
Deno: 2.6.4 - C:\Users\green\AppData\Local\Microsoft\WinGet\Links\deno.EXE
npmPackages:
@cloudflare/vite-plugin: ^1.21.0 => 1.21.0
wrangler: ^4.59.2 => 4.59.2

Please provide a link to a minimal reproduction

https://github.com/sapphi-red-repros/vite8-cloudflare-plugin-node

Describe the Bug

require(node builtin module) (e.g. require('crypto')) does not work with vite-plugin even if nodejs_compat is enabled when using Vite 8.

The output with Vite 7 is like:

import { EventEmitter } from "node:events";
import require$$0 from "buffer";
import require$$3 from "stream";
import require$$5 from "util";
import require$$1 from "crypto";

// uses require$$\d

But the output with Vite 8 is like:

var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) {
	if (typeof require !== "undefined") return require.apply(this, arguments);
	throw Error("Calling `require` for \"" + x + "\" in an environment that doesn't expose the `require` function.");
});
// ....
var require_safe_buffer = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var buffer = __require("buffer");
	var Buffer = buffer.Buffer;

This difference comes from the fact that Rolldown does not covert external require to an import to avoid semantics change (docs).

Since CF workers does not have require defined, this __require throws an error when called (Calling `require` for "buffer" in an environment that doesn't expose the `require` function.).

While users can use the esmExternalRequirePlugin like

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { esmExternalRequirePlugin } from 'vite'
import { builtinModules } from 'node:module'
import { cloudflare } from '@cloudflare/vite-plugin'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    react(),
    cloudflare(),
    esmExternalRequirePlugin({
      external: [/^node:/, ...builtinModules],
    }),
  ],
})

, it is not obvious why it's safe to convert require to import for users. This may also break the unenv support.

I think Vite doesn't have enough knowledge to handle this automatically on Vite side, but I'm open to doing so if possible.

Please provide any relevant error logs

No response

Metadata

Metadata

Labels

vite-pluginRelating to the `@cloudflare/vite-plugin` package

Type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions