Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/little-numbers-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cloudflare/unenv-preset": patch
---

Revert "Drop `node:process` polyfill when v2 is available"
2 changes: 1 addition & 1 deletion packages/unenv-preset/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
},
"peerDependencies": {
"unenv": "2.0.0-rc.21",
"workerd": "^1.20250924.0"
"workerd": "^1.20250927.0"
},
"peerDependenciesMeta": {
"workerd": {
Expand Down
52 changes: 2 additions & 50 deletions packages/unenv-preset/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const nativeModules = [
];

// Modules implemented via a mix of workerd APIs and polyfills.
const hybridModules = ["console"];
const hybridModules = ["console", "process"];

/**
* Creates the Cloudflare preset for the given compatibility date and compatibility flags
Expand All @@ -72,7 +72,6 @@ export function getCloudflarePreset({
const http2Overrides = getHttp2Overrides(compat);
const osOverrides = getOsOverrides(compat);
const fsOverrides = getFsOverrides(compat);
const processOverrides = getProcessOverrides(compat);

// "dynamic" as they depend on the compatibility date and flags
const dynamicNativeModules = [
Expand All @@ -81,7 +80,6 @@ export function getCloudflarePreset({
...http2Overrides.nativeModules,
...osOverrides.nativeModules,
...fsOverrides.nativeModules,
...processOverrides.nativeModules,
];

// "dynamic" as they depend on the compatibility date and flags
Expand All @@ -91,7 +89,6 @@ export function getCloudflarePreset({
...http2Overrides.hybridModules,
...osOverrides.hybridModules,
...fsOverrides.hybridModules,
...processOverrides.hybridModules,
];

return {
Expand Down Expand Up @@ -125,7 +122,7 @@ export function getCloudflarePreset({
clearImmediate: false,
setImmediate: false,
console: "@cloudflare/unenv-preset/node/console",
...processOverrides.inject,
process: "@cloudflare/unenv-preset/node/process",
},
polyfill: ["@cloudflare/unenv-preset/polyfill/performance"],
external: dynamicNativeModules.flatMap((p) => [p, `node:${p}`]),
Expand Down Expand Up @@ -308,48 +305,3 @@ function getFsOverrides({
hybridModules: [],
};
}

/**
* Returns the overrides for `node:process` and `node:fs/promises`
*
* The native process v2 implementation:
* - is enabled starting from 2025-09-15
* - can be enabled with the "enable_nodejs_process_v2" flag
* - can be disabled with the "disable_nodejs_process_v2" flag
*/
function getProcessOverrides({
compatibilityDate,
compatibilityFlags,
}: {
compatibilityDate: string;
compatibilityFlags: string[];
}): {
nativeModules: string[];
hybridModules: string[];
inject: { process: string | false };
} {
const disabledV2ByFlag = compatibilityFlags.includes(
"disable_nodejs_process_v2"
);

const enabledV2ByFlag = compatibilityFlags.includes(
"enable_nodejs_process_v2"
);
const enabledV2ByDate = compatibilityDate >= "2025-09-15";

const isV2 = (enabledV2ByFlag || enabledV2ByDate) && !disabledV2ByFlag;

return isV2
? {
nativeModules: ["process"],
hybridModules: [],
// We can use the native global, return `false` to drop the unenv default
inject: { process: false },
}
: {
nativeModules: [],
hybridModules: ["process"],
// Use the module default export as the global `process`
inject: { process: "@cloudflare/unenv-preset/node/process" },
};
}
78 changes: 60 additions & 18 deletions packages/unenv-preset/src/runtime/node/process.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// The polyfill is only used with the process v1 native implementation
// process v2 implements all the APIs from workerd v1.20250924.0

import { hrtime as UnenvHrTime } from "unenv/node/internal/process/hrtime";
import { Process as UnenvProcess } from "unenv/node/internal/process/process";

Expand All @@ -19,47 +16,92 @@ export const getBuiltinModule: NodeJS.Process["getBuiltinModule"] =

const workerdProcess = getBuiltinModule("node:process");

// Workerd has 2 different implementation for `node:process`
//
// See:
// - [workerd `process` v1](https://github.com/cloudflare/workerd/blob/main/src/node/internal/legacy_process.ts)
// - [workerd `process` v2](https://github.com/cloudflare/workerd/blob/main/src/node/internal/public_process.ts)
// - [`enable_nodejs_process_v2` flag](https://github.com/cloudflare/workerd/blob/main/src/workerd/io/compatibility-date.capnp)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const isWorkerdProcessV2 = (globalThis as any).Cloudflare.compatibilityFlags
.enable_nodejs_process_v2;

const unenvProcess = new UnenvProcess({
env: globalProcess.env,
hrtime: UnenvHrTime,
// `hrtime` is only available from workerd process v2
hrtime: isWorkerdProcessV2 ? workerdProcess.hrtime : UnenvHrTime,
// `nextTick` is available from workerd process v1
nextTick: workerdProcess.nextTick,
});

// APIs implemented by workerd process in both v1 and v2
// APIs implemented by workerd module in both v1 and v2
// Note that `env`, `hrtime` and `nextTick` are always retrieved from `unenv`
export const { exit, features, platform } = workerdProcess;

// APIs that can be implemented by either `unenv` or `workerd`.
// They are always retrieved from `unenv` which might use their `workerd` implementation.
export const {
// Always implemented by workerd
env,
// Only implemented in workerd v2
hrtime,
// Always implemented by workerd
nextTick,
} = unenvProcess;

// APIs that are not implemented by `workerd` (whether v1 or v2)
// They are retrieved from `unenv`.
export const {
_channel,
_debugEnd,
_debugProcess,
_disconnect,
_events,
_eventsCount,
_handleQueue,
_maxListeners,
_pendingMessage,
_send,
assert,
disconnect,
mainModule,
} = unenvProcess;

// API that are only implemented starting from v2 of workerd process
// They are retrieved from unenv when process v1 is used
export const {
// @ts-expect-error `_debugEnd` is missing typings
_debugEnd,
// @ts-expect-error `_debugProcess` is missing typings
_debugProcess,
// @ts-expect-error `_exiting` is missing typings
_exiting,
// @ts-expect-error `_fatalException` is missing typings
_fatalException,
// @ts-expect-error `_getActiveHandles` is missing typings
_getActiveHandles,
// @ts-expect-error `_getActiveRequests` is missing typings
_getActiveRequests,
_handleQueue,
// @ts-expect-error `_kill` is missing typings
_kill,
// @ts-expect-error `_linkedBinding` is missing typings
_linkedBinding,
_maxListeners,
_pendingMessage,
// @ts-expect-error `_preload_modules` is missing typings
_preload_modules,
// @ts-expect-error `_rawDebug` is missing typings
_rawDebug,
_send,
// @ts-expect-error `_startProfilerIdleNotifier` is missing typings
_startProfilerIdleNotifier,
// @ts-expect-error `_stopProfilerIdleNotifier` is missing typings
_stopProfilerIdleNotifier,
// @ts-expect-error `_tickCallback` is missing typings
_tickCallback,
abort,
addListener,
allowedNodeEnvironmentFlags,
arch,
argv,
argv0,
assert,
availableMemory,
// @ts-expect-error `binding` is missing typings
binding,
channel,
chdir,
Expand All @@ -69,12 +111,11 @@ export const {
cpuUsage,
cwd,
debugPort,
disconnect,
dlopen,
// @ts-expect-error `domain` is missing typings
domain,
emit,
emitWarning,
env,
eventNames,
execArgv,
execPath,
Expand All @@ -88,26 +129,27 @@ export const {
getMaxListeners,
getuid,
hasUncaughtExceptionCaptureCallback,
hrtime,
// @ts-expect-error `initgroups` is missing typings
initgroups,
kill,
listenerCount,
listeners,
loadEnvFile,
mainModule,
memoryUsage,
// @ts-expect-error `moduleLoadList` is missing typings
moduleLoadList,
nextTick,
off,
on,
once,
// @ts-expect-error `openStdin` is missing typings
openStdin,
permission,
pid,
ppid,
prependListener,
prependOnceListener,
rawListeners,
// @ts-expect-error `reallyExit` is missing typings
reallyExit,
ref,
release,
Expand Down Expand Up @@ -136,7 +178,7 @@ export const {
uptime,
version,
versions,
} = unenvProcess;
} = isWorkerdProcessV2 ? workerdProcess : unenvProcess;

const _process = {
abort,
Expand Down
Loading
Loading