Describe the bug
After upgrading from Vite+ 0.2.1 to 0.2.2, running vp build through the Vite Task runner changes process.env.NODE_ENV to the string "null".
A direct production build behaves correctly:
$ vp build
process.env.NODE_ENV: "production"
But the same build through vpr reports:
$ vpr build
process.env.NODE_ENV: "null"
This changes the generated import.meta.env values:
// vp build
{
DEV: false,
MODE: "production",
PROD: true,
}
// vpr build
{
DEV: true,
MODE: "production",
PROD: false,
}
This affects frameworks and plugins that rely on NODE_ENV === "production", including AnalogJS and Cloudflare Workers applications.
The expected behavior is for vpr build to preserve the production semantics of vp build.
Likely cause
This appears to be a contract mismatch between Vite and the Vite Task client.
Vite calls:
const nodeEnv = getEnv('NODE_ENV')
if (nodeEnv !== undefined) {
process.env.NODE_ENV = nodeEnv
}
The Vite Task N-API method returns Option<String>. An absent value is converted by napi-rs to JavaScript null, while the JavaScript wrapper documents the return value as string | undefined.
The null value passes Vite's !== undefined check. Assigning it to process.env.NODE_ENV coerces it to the string "null".
The regression became active with the runner-aware integration in Vite+ commit a9c7034b, which updated Vite Task from 5833b374 to 8daa9bb7.
Reproduction
https://github.com/why-reproductions-are-required/vite-plus-node-env-null-repro
Steps to reproduce
git clone https://github.com/why-reproductions-are-required/vite-plus-node-env-null-repro.git
cd vite-plus-node-env-null-repro
npm ci
npm run repro
The reproduction removes NODE_ENV from the parent environment, runs both build paths, prints the generated bundles, and asserts the differing DEV and PROD values.
System Info
$ vp env current
Environment:
Version 24.18.0
Source engines.node
Source Path /Users/mkyuan/git/github.com/why-reproductions-are-required/vite-plus-node-env-null-repro/package.json
Project Root /Users/mkyuan/git/github.com/why-reproductions-are-required/vite-plus-node-env-null-repro
Tool Paths:
node /Users/mkyuan/.vite-plus/js_runtime/node/24.18.0/bin/node
npm /Users/mkyuan/.vite-plus/js_runtime/node/24.18.0/bin/npm
npx /Users/mkyuan/.vite-plus/js_runtime/node/24.18.0/bin/npx
Package Manager:
Name npm
Version 11.18.0
Source devEngines.packageManager
Source Path /Users/mkyuan/git/github.com/why-reproductions-are-required/vite-plus-node-env-null-repro/package.json
Project Root /Users/mkyuan/git/github.com/why-reproductions-are-required/vite-plus-node-env-null-repro
Bin Path /Users/mkyuan/.vite-plus/package_manager/npm/11.18.0/npm/bin/npm
$ vp --version
vp v0.2.2
Local vite-plus:
vite-plus v0.2.2
Tools:
vite v8.1.2
rolldown v1.1.4
vitest v4.1.9
oxfmt v0.57.0
oxlint v1.72.0
oxlint-tsgolint v0.24.0
tsdown v0.22.3
Environment:
Package manager npm v11.18.0
Node.js v24.18.0 (engines.node)
Used Package Manager
npm
Logs
=== Direct build: vp build ===
process.env.NODE_ENV: "production"
configEnv: {"mode":"production","command":"build","isSsrBuild":false,"isPreview":false}
vite v8.1.2 building client environment for production...
console.log(JSON.stringify({
"BASE_URL": "/",
"DEV": false,
"MODE": "production",
"PROD": true,
"SSR": false
}));
=== Runner build: vpr build ===
$ vp build
process.env.NODE_ENV: "null"
configEnv: {"mode":"production","command":"build","isSsrBuild":false,"isPreview":false}
vite v8.1.2 building client environment for production...
console.log(JSON.stringify({
"BASE_URL": "/",
"DEV": true,
"MODE": "production",
"PROD": false,
"SSR": false
}));
Validations
Describe the bug
After upgrading from Vite+ 0.2.1 to 0.2.2, running
vp buildthrough the Vite Task runner changesprocess.env.NODE_ENVto the string"null".A direct production build behaves correctly:
But the same build through
vprreports:This changes the generated
import.meta.envvalues:This affects frameworks and plugins that rely on
NODE_ENV === "production", including AnalogJS and Cloudflare Workers applications.The expected behavior is for
vpr buildto preserve the production semantics ofvp build.Likely cause
This appears to be a contract mismatch between Vite and the Vite Task client.
Vite calls:
The Vite Task N-API method returns
Option<String>. An absent value is converted by napi-rs to JavaScriptnull, while the JavaScript wrapper documents the return value asstring | undefined.The
nullvalue passes Vite's!== undefinedcheck. Assigning it toprocess.env.NODE_ENVcoerces it to the string"null".The regression became active with the runner-aware integration in Vite+ commit
a9c7034b, which updated Vite Task from5833b374to8daa9bb7.Reproduction
https://github.com/why-reproductions-are-required/vite-plus-node-env-null-repro
Steps to reproduce
git clone https://github.com/why-reproductions-are-required/vite-plus-node-env-null-repro.git cd vite-plus-node-env-null-repro npm ci npm run reproThe reproduction removes
NODE_ENVfrom the parent environment, runs both build paths, prints the generated bundles, and asserts the differingDEVandPRODvalues.System Info
Used Package Manager
npm
Logs
Validations