Skip to content

fix: switch plugins to CJS output to fix SEA binary plugin loading#436

Merged
theoephraim merged 4 commits intomainfrom
fix/plugin-cjs-sea-loading
Mar 18, 2026
Merged

fix: switch plugins to CJS output to fix SEA binary plugin loading#436
theoephraim merged 4 commits intomainfrom
fix/plugin-cjs-sea-loading

Conversation

@theoephraim
Copy link
Member

@theoephraim theoephraim commented Mar 18, 2026

Summary

  • All 7 plugins now build as CJS (`dist/plugin.cjs`) instead of ESM
  • The SEA binary's plugin loader now uses `new Function` to execute CJS plugin code in the main runtime context (instead of `node:vm` with a Proxy sandbox, which crashed on Node.js C++ lazy initializers like `DOMException`, or dynamic `import()` which doesn't work in SEA builds)
  • Non-SEA path switches from dynamic `import()` to `createRequire()`
  • Binary build now passes `--no-compile-autoload-dotenv` and `--no-compile-autoload-bunfig` to prevent Bun from pre-loading the user's `.env` files into the binary's own `process.env` — without this, function calls like `if(true, a, b)` in `.env.local` would be captured as literal strings instead of being resolved
  • Smoke test fixture plugins converted to CJS; new binary smoke tests verify plugin loading and that `.env.local` function calls are properly resolved

Fixes #411

Test plan

  • Binary smoke tests pass: `cd smoke-tests && bun run vitest run tests/binary-plugin.test.ts tests/binary.test.ts`
  • Build all plugins: `bun run --filter "@varlock/*-plugin" build` — all output `dist/plugin.cjs`
  • Build binary: `bun run --filter varlock build:binary`
  • Test with a real plugin against the binary (GSM, AWS, or Infisical)

🤖 Generated with Claude Code

The standalone binary's plugin loader was using regex to rewrite ESM
`import { x as y }` to CJS destructuring, which broke on aliased imports
(e.g. `import { Buffer as Buffer$1 }` → invalid `const { Buffer as Buffer$1 }`).

All plugins now build as CJS via tsup. The SEA loader is replaced with a simple
node:vm execution using a standard CJS context (require, module, exports,
__dirname, __filename) — no transformation needed. The non-SEA path also switches
from dynamic import() to createRequire().

Smoke test fixture plugins are converted to CJS, and a new binary smoke test
verifies all real monorepo plugins load without SyntaxErrors.

Fixes #411

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Mar 18, 2026

🦋 Changeset detected

Latest commit: 08a994f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
varlock Minor
@varlock/aws-secrets-plugin Major
@varlock/azure-key-vault-plugin Major
@varlock/bitwarden-plugin Major
@varlock/google-secret-manager-plugin Major
@varlock/infisical-plugin Major
@varlock/pass-plugin Major
@varlock/1password-plugin Major
@varlock/astro-integration Major
@varlock/nextjs-integration Major
@varlock/vite-integration Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 18, 2026

Open in StackBlitz

varlock

npm i https://pkg.pr.new/varlock@436

@varlock/astro-integration

npm i https://pkg.pr.new/@varlock/astro-integration@436

@varlock/nextjs-integration

npm i https://pkg.pr.new/@varlock/nextjs-integration@436

@varlock/vite-integration

npm i https://pkg.pr.new/@varlock/vite-integration@436

@varlock/1password-plugin

npm i https://pkg.pr.new/@varlock/1password-plugin@436

@varlock/aws-secrets-plugin

npm i https://pkg.pr.new/@varlock/aws-secrets-plugin@436

@varlock/azure-key-vault-plugin

npm i https://pkg.pr.new/@varlock/azure-key-vault-plugin@436

@varlock/bitwarden-plugin

npm i https://pkg.pr.new/@varlock/bitwarden-plugin@436

@varlock/google-secret-manager-plugin

npm i https://pkg.pr.new/@varlock/google-secret-manager-plugin@436

@varlock/infisical-plugin

npm i https://pkg.pr.new/@varlock/infisical-plugin@436

@varlock/pass-plugin

npm i https://pkg.pr.new/@varlock/pass-plugin@436

commit: 08a994f

@socket-security
Copy link

socket-security bot commented Mar 18, 2026

theoephraim and others added 2 commits March 18, 2026 01:18
Remove the SEA/non-SEA branch — node:vm works in both environments.
Also removes isSEABuild() which is no longer needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add --no-compile-autoload-dotenv and --no-compile-autoload-bunfig to the
bun build --compile command so the binary does not pre-load .env files from
the user's project directory into its own process.env before varlock starts.

Without this, Bun would inject .env.local values as literal strings into
process.env, which env-graph.ts captures as overrideValues — causing function
calls like if(true, a, b) to be returned as-is instead of being resolved.

Also adds a binary smoke test that verifies .env.local function calls are
properly resolved rather than passed through as literal strings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Member

@philmillman philmillman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm once those test failures are resolved

@theoephraim theoephraim merged commit eaf6c10 into main Mar 18, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: Standalone brew binary cannot load plugins — Bun 1.3.9 runInContext fails to parse ESM import aliases

2 participants