Skip to content

feat: shared env#756

Merged
magne4000 merged 5 commits into
mainfrom
magne4000/shared-env
Jun 9, 2026
Merged

feat: shared env#756
magne4000 merged 5 commits into
mainfrom
magne4000/shared-env

Conversation

@magne4000

@magne4000 magne4000 commented Jun 9, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • Refactor

    • Centralized environment handling across boilerplates using a shared env module and loader; runtime .env loading is now optional and non-fatal.
    • Server entrypoints and migration scripts now use the shared loader for consistent env bootstrapping.
  • Chores

    • Removed widespread dotenv dev dependency and added a shared environment package.
    • Docker build now ensures the shared env loader is included when running migrations.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5465d2cc-9047-4b18-a451-7d2b19ee11ab

📥 Commits

Reviewing files that changed from the base of the PR and between a1f63a5 and 4744f73.

📒 Files selected for processing (3)
  • boilerplates/docker-compose/files/$Dockerfile.ts
  • packages/core/src/parse/linters/visitor-imports.ts
  • packages/core/tests/transform-ts.spec.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/core/tests/transform-ts.spec.ts
  • packages/core/src/parse/linters/visitor-imports.ts

📝 Walkthrough

Walkthrough

This PR introduces a centralized environment loading system by creating a new @batijs/shared-env boilerplate package and migrating all boilerplates from dotenv to a shared environment module with native Node.js fallbacks. It also enhances import tracking to skip recording imports that are conditionally removed by BATI configuration.

Changes

Shared environment loading migration

Layer / File(s) Summary
Create shared-env package and runtime modules
boilerplates/shared-env/bati.config.ts, boilerplates/shared-env/files/server/env.ts, boilerplates/shared-env/files/server/load.ts, boilerplates/shared-env/package.json, boilerplates/shared-env/tsconfig.json
A new @batijs/shared-env package exports env (Cloudflare Workers or process.env) and load (environment variable loader using native process.loadEnvFile or parseEnv fallback).
Switch runtime files to shared-env imports
boilerplates/authjs/files/server/authjs-handler.ts, boilerplates/better-auth/files/server/better-auth.ts, boilerplates/better-auth/files/database/better-auth/migrate.ts, boilerplates/drizzle/files/drizzle.config.ts, boilerplates/elysia/files/+server.ts, boilerplates/express/files/+server.ts, boilerplates/fastify/files/+server.ts, boilerplates/hono/files/+server.ts, boilerplates/kysely/files/database/kysely/db.ts, boilerplates/postgres/files/database/postgres/schema/todos.ts, boilerplates/sqlite/files/database/sqlite/schema/todos.ts, boilerplates/docker-compose/files/$Dockerfile.ts
All server runtime files, migration scripts, and the Dockerfile generator were updated to import @batijs/shared-env/server/* instead of dotenv/config or ad-hoc env selection.
Update package.json template transformers
boilerplates/better-auth/files/$package.json.ts, boilerplates/drizzle/files/$package.json.ts, boilerplates/elysia/files/$package.json.ts, boilerplates/express/files/$package.json.ts, boilerplates/fastify/files/$package.json.ts, boilerplates/hono/files/$package.json.ts, boilerplates/kysely/files/$package.json.ts, boilerplates/postgres/files/$package.json.ts, boilerplates/sqlite/files/$package.json.ts
Boilerplate package transformers remove dotenv from generated dependency lists while preserving framework and database dependencies.
Align boilerplate and test manifests
boilerplates/authjs/package.json, boilerplates/better-auth/package.json, boilerplates/drizzle/package.json, boilerplates/elysia/package.json, boilerplates/express/package.json, boilerplates/fastify/package.json, boilerplates/hono/package.json, boilerplates/kysely/package.json, boilerplates/postgres/package.json, boilerplates/sqlite/package.json, packages/tests/package.json
Package manifests add @batijs/shared-env as a workspace dependency and remove dotenv entries across affected boilerplates and test packages.
Replace tests dotenv usage with native loader fallback
packages/tests/src/index.ts, packages/tests/src/common.ts, packages/tests-utils/src/prepare.ts
Test loading replaces dotenv.config() with a custom loadDotEnvTest() using Node's process.loadEnvFile when available or parseEnv fallback; comments updated to reference the shared-env loading mechanism.
Track conditionally removed imports in linters
packages/core/src/parse/linters/linter-ts.ts, packages/core/src/parse/linters/linter-vue.ts, packages/core/src/parse/linters/visitor-imports.ts, packages/core/tests/transform-ts.spec.ts
Import linting logic is extended to detect BATI condition comments (e.g., //# BATI.has("react")) preceding import statements and skip tracking/path rewriting for imports that would be stripped by false conditions.

Possibly related PRs

  • vikejs/bati#753: Updates Better Auth boilerplate's environment wiring from dotenv/manual env resolution to @batijs/shared-env/server/*, directly overlapping with this PR's Better Auth migration.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: shared env' accurately and concisely summarizes the primary change—introducing a shared environment module across multiple boilerplates to centralize environment variable handling.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

Review ran into problems

🔥 Problems

Stopped waiting for pipeline failures after 30000ms. One of your pipelines takes longer than our 30000ms fetch window to run, so review may not consider pipeline-failure results for inline comments if any failures occurred after the fetch window. Increase the timeout if you want to wait longer or run a @coderabbit review after the pipeline has finished.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
packages/tests/src/index.ts (1)

178-197: ⚡ Quick win

Comment contradicts fallback logic.

Lines 179–181 state "the parseEnv fallback under Bun (which lacks it..." — the pronoun "it" appears to refer to process.loadEnvFile, yet the sentence positions parseEnv as the fallback for Bun. If Bun lacks parseEnv (as the parenthetical implies), the fallback branch will fail. Clarify whether Bun is expected to provide parseEnv, or revise the comment and implementation to match the actual capability matrix.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/tests/src/index.ts` around lines 178 - 197, The comment in
loadDotEnvTest is misleading about which runtime provides which helper; update
the comment to correctly state that Node provides process.loadEnvFile while Bun
auto-loads .env but does not provide process.loadEnvFile, so we fallback to
parseEnv+readFileSync when process.loadEnvFile is absent; also adjust wording so
it doesn't imply Bun lacks parseEnv — reference process.loadEnvFile, parseEnv,
readFileSync, and the loadDotEnvTest function to ensure the comment matches the
implemented branching logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@boilerplates/shared-env/bati.config.ts`:
- Around line 3-8: Add an `if` gate to the defineConfig call so the config only
applies when the project meta indicates the boilerplate is relevant; update the
exported defineConfig({ enforce: "pre" }) to include an if property (e.g. if:
(meta) => Boolean(meta?.selectedBoilerplates?.includes('shared-env')) or a
similar predicate that checks meta for the presence of this boilerplate),
keeping the existing enforce: "pre" and using the defineConfig wrapper.

In `@boilerplates/shared-env/files/server/load.ts`:
- Around line 19-29: The empty catch is swallowing all errors when loading the
env; change it to catch the error object (e.g., catch (err)) and only ignore
missing-file errors (err.code === 'ENOENT'), rethrow any other errors so
parse/permission failures surface; apply this around the block that calls
process.loadEnvFile, parseEnv, and readFileSync so failures in
process.loadEnvFile, parseEnv, or readFileSync are not silently suppressed.

In `@boilerplates/shared-env/package.json`:
- Around line 23-30: The package.json exports for the subpaths "./server/env"
and "./server/load" only expose type entries and omit runtime targets, which
breaks side-effect/runtime imports; update those export entries in package.json
to include appropriate "import" and/or "require" (or "default") runtime entry
points (pointing at the built JS files in dist, e.g., dist/server/env.* and
dist/server/load.*) alongside the existing "types" entries so runtime module
resolution succeeds when code imports "./server/env" or "./server/load".

---

Nitpick comments:
In `@packages/tests/src/index.ts`:
- Around line 178-197: The comment in loadDotEnvTest is misleading about which
runtime provides which helper; update the comment to correctly state that Node
provides process.loadEnvFile while Bun auto-loads .env but does not provide
process.loadEnvFile, so we fallback to parseEnv+readFileSync when
process.loadEnvFile is absent; also adjust wording so it doesn't imply Bun lacks
parseEnv — reference process.loadEnvFile, parseEnv, readFileSync, and the
loadDotEnvTest function to ensure the comment matches the implemented branching
logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 33962076-654a-4708-a8ae-5fb49bd607c4

📥 Commits

Reviewing files that changed from the base of the PR and between 4e9579d and d1cf5dd.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (40)
  • boilerplates/authjs/files/server/authjs-handler.ts
  • boilerplates/authjs/package.json
  • boilerplates/better-auth/files/$package.json.ts
  • boilerplates/better-auth/files/database/better-auth/migrate.ts
  • boilerplates/better-auth/files/server/better-auth.ts
  • boilerplates/better-auth/package.json
  • boilerplates/drizzle/files/$package.json.ts
  • boilerplates/drizzle/files/drizzle.config.ts
  • boilerplates/drizzle/package.json
  • boilerplates/elysia/files/$package.json.ts
  • boilerplates/elysia/files/+server.ts
  • boilerplates/elysia/package.json
  • boilerplates/express/files/$package.json.ts
  • boilerplates/express/files/+server.ts
  • boilerplates/express/package.json
  • boilerplates/fastify/files/$package.json.ts
  • boilerplates/fastify/files/+server.ts
  • boilerplates/fastify/package.json
  • boilerplates/hono/files/$package.json.ts
  • boilerplates/hono/files/+server.ts
  • boilerplates/hono/package.json
  • boilerplates/kysely/files/$package.json.ts
  • boilerplates/kysely/files/database/kysely/db.ts
  • boilerplates/kysely/package.json
  • boilerplates/postgres/files/$package.json.ts
  • boilerplates/postgres/files/database/postgres/schema/todos.ts
  • boilerplates/postgres/package.json
  • boilerplates/shared-env/bati.config.ts
  • boilerplates/shared-env/bati.d.ts
  • boilerplates/shared-env/files/server/env.ts
  • boilerplates/shared-env/files/server/load.ts
  • boilerplates/shared-env/package.json
  • boilerplates/shared-env/tsconfig.json
  • boilerplates/sqlite/files/$package.json.ts
  • boilerplates/sqlite/files/database/sqlite/schema/todos.ts
  • boilerplates/sqlite/package.json
  • packages/tests-utils/src/prepare.ts
  • packages/tests/package.json
  • packages/tests/src/common.ts
  • packages/tests/src/index.ts
💤 Files with no reviewable changes (2)
  • boilerplates/better-auth/files/$package.json.ts
  • packages/tests/package.json

Comment thread boilerplates/shared-env/bati.config.ts
Comment thread boilerplates/shared-env/files/server/load.ts
Comment thread boilerplates/shared-env/package.json
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
🔵 In progress
View logs
bati d1cf5dd Jun 09 2026, 03:56 PM

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/core/tests/transform-ts.spec.ts (1)

585-614: 💤 Low value

Test coverage is solid for the main use case.

The test suite validates the core behavior: imports gated by falsy BATI conditions are removed from both the emitted code and context.imports, preventing incorrect include-if-imported tracking.

Consider adding a test case for the "remove-comments-only" variant with imports to ensure isRemovedByCondition handles it correctly:

describe("imports with remove-comments-only are tracked", () => {
  const code = `//# BATI.has("react") || "remove-comments-only"
import "`@batijs/shared-env/server/load`";
export const x = 1;`;

  test("kept in graph when condition is remove-comments-only", () => {
    const { code: output, context } = transform(code, "test.ts", {
      BATI: new BatiSet([], features, "pnpm"),
      BATI_TEST: false,
    });

    expect(output).toContain(`import "./server/load";`);
    expect([...context.imports]).toContain("./server/load");
  });
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/tests/transform-ts.spec.ts` around lines 585 - 614, Add a new
test case mirroring the existing "imports stripped by a BATI condition are not
tracked" suite but using the `//# BATI.has("react") || "remove-comments-only"`
condition to verify the "remove-comments-only" branch keeps the import in both
emitted code and `context.imports`; use the same `transform(...)` call and
`BatiSet` setup (with an empty feature set and `BATI_TEST: false`) and assert
that `output` contains `import "./server/load";` and `[...context.imports]`
contains `"./server/load"`, ensuring `isRemovedByCondition` handles the
remove-comments-only variant.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/core/tests/transform-ts.spec.ts`:
- Around line 585-614: Add a new test case mirroring the existing "imports
stripped by a BATI condition are not tracked" suite but using the `//#
BATI.has("react") || "remove-comments-only"` condition to verify the
"remove-comments-only" branch keeps the import in both emitted code and
`context.imports`; use the same `transform(...)` call and `BatiSet` setup (with
an empty feature set and `BATI_TEST: false`) and assert that `output` contains
`import "./server/load";` and `[...context.imports]` contains `"./server/load"`,
ensuring `isRemovedByCondition` handles the remove-comments-only variant.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a630219f-f9cd-47c3-8511-d245bf444b3d

📥 Commits

Reviewing files that changed from the base of the PR and between d1cf5dd and a1f63a5.

📒 Files selected for processing (11)
  • boilerplates/authjs/files/server/authjs-handler.ts
  • boilerplates/better-auth/files/server/better-auth.ts
  • boilerplates/elysia/files/$package.json.ts
  • boilerplates/shared-env/bati.config.ts
  • boilerplates/shared-env/files/server/env.ts
  • boilerplates/shared-env/files/server/load.ts
  • boilerplates/shared-env/tsconfig.json
  • packages/core/src/parse/linters/linter-ts.ts
  • packages/core/src/parse/linters/linter-vue.ts
  • packages/core/src/parse/linters/visitor-imports.ts
  • packages/core/tests/transform-ts.spec.ts
💤 Files with no reviewable changes (3)
  • boilerplates/shared-env/bati.config.ts
  • boilerplates/shared-env/files/server/load.ts
  • boilerplates/shared-env/files/server/env.ts
✅ Files skipped from review due to trivial changes (1)
  • boilerplates/shared-env/tsconfig.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • boilerplates/elysia/files/$package.json.ts
  • boilerplates/authjs/files/server/authjs-handler.ts

@magne4000 magne4000 merged commit 4f47a34 into main Jun 9, 2026
370 of 372 checks passed
@magne4000 magne4000 deleted the magne4000/shared-env branch June 9, 2026 17:16
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.

1 participant