Skip to content

🍕 Fix Kiln plugins under Vite: client env redirect, bootstrap order, init error reporting#252

Merged
jjpaulino merged 5 commits into
masterfrom
jordan/kiln-init-diagnostics
May 29, 2026
Merged

🍕 Fix Kiln plugins under Vite: client env redirect, bootstrap order, init error reporting#252
jjpaulino merged 5 commits into
masterfrom
jordan/kiln-init-diagnostics

Conversation

@jjpaulino
Copy link
Copy Markdown
Member

@jjpaulino jjpaulino commented May 28, 2026

Summary

Three related changes that make Kiln plugins (Pyxis image picker, Agora product picker, …) and other env-reading client code behave under the Vite pipeline the same way they did under Browserify:

  • Client env redirect (lib/cmd/vite/scripts.js): define process.envwindow.process.env so client reads resolve to the runtime-hydrated object (.clay/_env-init.js populates it from window.kiln.preloadData._envVars, gated by client-env.json). process.env.NODE_ENV stays a build-time literal so guards still tree-shake. No build-time values are inlined.
  • Bootstrap-first load order (lib/cmd/vite/index.js): in edit mode, emit the bootstrap (env-init) module script before the kiln edit entry so window.process.env is hydrated before plugin code reads it.
  • Guarded plugin init (lib/cmd/vite/generate-kiln-edit.js): wrap the site Kiln plugin initializer in sync + async error handling and emit a structured error payload (name, message, stack, optional code/nested cause) so edit-mode init failures are explicit instead of silent.

Why

Under Vite, @rollup/plugin-commonjs rewrites a CJS module's bare process.env into a build-time-empty stub (literally var pVt = {}), so process.env.PYXIS_HOST || '…' always collapsed to the fallback — silently breaking every Kiln plugin / universal service that reads env. They worked under Browserify because its transformEnv plugin rewrites process.envwindow.process.env. This PR reproduces that behavior in Vite (a redirect, not an inline), ensures the env object is hydrated before plugins run, and surfaces any remaining init failures.

Deliberately a redirect, not build-time inlining: the Docker image build is bare, and inlining from the build env would bake non-allowlisted secrets (e.g. CORAL_GRAPHQL_TOKEN) into the public bundle. The runtime object is allowlist-gated, so client-env exposure stays identical to Browserify.

Test plan

  • npx jest lib/cmd/vite — 14 suites, 193 tests pass
  • npx eslint on all six changed files — clean
  • esbuild transform check: every process.env.X (incl. non-allowlisted secrets) compiles to window.process.env.X; NODE_ENV folds to a literal; no secret literal appears in output
  • Verified on QA: Pyxis image picker + Agora product picker load and save correctly on Vite-enabled sites

Note for reviewers / merge

The commit history is winding: an intermediate experiment added build-time env inlining (Inline client process.env vars…, Match Browserify env handling…) that the final commit (Simplify Vite client env to a pure window.process.env redirect) removes entirely. Please squash-merge — the net diff is exactly the three changes above.

Made with Cursor

Wrap site Kiln plugin initialization in structured sync/async error handling so edit-mode plugin boot failures are surfaced with clear error details instead of silently failing during startup.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coveralls
Copy link
Copy Markdown

coveralls commented May 28, 2026

Coverage Status

coverage: 87.084% (+0.2%) from 86.85% — jordan/kiln-init-diagnostics into master

Ensure edit mode module scripts are ordered so bootstrap/env globals initialize before kiln plugin code executes.

Co-authored-by: Cursor <cursoragent@cursor.com>
@jjpaulino jjpaulino self-assigned this May 28, 2026
jjpaulino and others added 3 commits May 28, 2026 20:45
CJS modules that read process.env.X at load time compile to an empty
`var pVt = {}` stub under @rollup/plugin-commonjs, so reads like
process.env.PYXIS_HOST resolve to undefined and never reach the
runtime-hydrated window.process.env. This silently broke every Kiln
plugin / universal service that reads env at module eval (pyxis, agora,
glaze, …) — they worked in the legacy pipeline only because dotenv-webpack
inlined those reads as string literals.

Extend buildDefines() to inline client-facing process.env vars via Vite's
define map, mirroring dotenv-webpack. The var list comes from
client-env.json (the same browser surface amphora-html already forwards to
window.process.env), with a cold-build fallback to all valid env keys so a
fresh CI checkout still inlines. define only substitutes referenced tokens,
so an over-inclusive list never leaks an unreferenced secret into the bundle.

Add focused unit tests for inlining, the cold-build fallback, and the
invalid-identifier filter.

Co-authored-by: Cursor <cursoragent@cursor.com>
…fallback

buildClientEnvDefines now reproduces the legacy dotenv-webpack
({ path: './.env', systemvars: true }) behaviour and adds a runtime safety
net so the Vite pipeline stops regressing where the build env is bare:

- Layer 1 (Browserify parity): overlay ./.env with the build process env and
  inline every NON-EMPTY process.env.<VAR> as a string literal — exactly what
  the old pack pipeline shipped (a local container build started with env_file
  bakes the real values in).
- Layer 2 (runtime catch-all): define process.env -> window.process.env so any
  var the build can't see (the bare Docker image build) resolves to the object
  .clay/_env-init.js hydrates from window.kiln.preloadData._envVars instead of a
  pVt={} stub.

Fixes the Vite-only image/product picker break: the prior build-time inline
baked "" for client vars (the Docker build has no PYXIS_HOST/AGORA_HOST), and
master's `window.process.env.X = process.env.X` then clobbered the hydrated
value with "". Empty/absent vars now fall through to the runtime read, turning
that line into a harmless self-assign. process.env.NODE_ENV stays a literal so
guards still tree-shake.

Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the build-time inlining layer (and the .env reader) that was added for the
Browserify-parity experiment. The Docker image build is bare, so inlining never
contributed in prod; the runtime redirect (process.env -> window.process.env,
hydrated from preloadData._envVars and gated by client-env.json) is what
actually fixes the Kiln pickers under Vite.

This matches the legacy Browserify transformEnv plugin (lib/cmd/compile/scripts.js)
exactly — it rewrites process.env to window.process.env and inlines nothing — and
removes the latent risk of baking non-allowlisted secrets (e.g. CORAL_GRAPHQL_TOKEN)
into the public bundle on any env-present build. process.env.NODE_ENV stays a
build-time literal so guards still tree-shake.

Co-authored-by: Cursor <cursoragent@cursor.com>
@jjpaulino jjpaulino changed the title 🍕 Add Kiln plugin init diagnostics for Vite 🍕 Fix Kiln plugins under Vite: client env redirect, bootstrap order, init error reporting May 29, 2026
@jjpaulino jjpaulino merged commit 8c5adb6 into master May 29, 2026
6 checks passed
@jjpaulino jjpaulino deleted the jordan/kiln-init-diagnostics branch May 29, 2026 03:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants