feat(dev): write .env.local on first run#517
Conversation
🚀 Package Preview Available!Install this PR's preview build with npm: npm i @base44-preview/cli@0.0.52-pr.517.5e3000dPrefer not to change any import paths? Install using npm alias so your code still imports npm i "base44@npm:@base44-preview/cli@0.0.52-pr.517.5e3000d"Or add it to your {
"dependencies": {
"base44": "npm:@base44-preview/cli@0.0.52-pr.517.5e3000d"
}
}
Preview published to npm registry — try new features instantly! |
| if (projectRoot) { | ||
| const envLocalPath = join(projectRoot, ".env.local"); | ||
| if (!(await pathExists(envLocalPath))) { | ||
| const { id: appId } = await initAppConfig(); | ||
| await writeFile( | ||
| envLocalPath, | ||
| `VITE_BASE44_APP_ID=${appId}\nVITE_BASE44_APP_BASE_URL=http://localhost:${resolvedPort}\n`, | ||
| ); | ||
| log.info("Created .env.local with app ID and dev server URL"); | ||
| } | ||
| } |
There was a problem hiding this comment.
you're dependent on value that is set in loadResources(), imo it means you can just run this code in loadResources() and not keep it outside.
Maybe you can wrap it in a standalone function though.
There was a problem hiding this comment.
Wrapped the post-server logic in a standalone writeEnvLocalIfMissing(projectRoot, port, log) function. projectRoot still comes from loadResources() (the resolved port is only known after the server starts, so the write itself has to happen afterwards), but the body is no longer inlined in devAction.
| await writeFile( | ||
| envLocalPath, | ||
| `VITE_BASE44_APP_ID=${appId}\nVITE_BASE44_APP_BASE_URL=http://localhost:${resolvedPort}\n`, | ||
| ); |
There was a problem hiding this comment.
I'm not familiar with the needed of this file and its content.
Is it used somehow during the dev?
Why do you want to create it during the dev?
There was a problem hiding this comment.
My understanding is that it's required for npm run dev, the vite server
There was a problem hiding this comment.
Not sure I understand your answer.
Are you sure it's really required?
Which part is requiring it?
How it worked before?
There was a problem hiding this comment.
Good catch digging in — it turned out the original code had the wrong variable name. The frontend reads its config via @base44/vite-plugin, which consumes VITE_BASE44_APP_ID and VITE_BASE44_BACKEND_URL (same names the platform injects in clone_s3_repo.py / the sandbox provider). The previous revision wrote VITE_BASE44_APP_BASE_URL, which nothing reads — so the local-backend redirect silently had no effect and the SDK kept hitting production. Before this PR there was simply no .env.local on a fresh clone, so you had to write it by hand. Fixed to write VITE_BASE44_BACKEND_URL; PR description updated with the full rationale.
| const { id: appId } = await initAppConfig(); | ||
| await writeFile( | ||
| envLocalPath, | ||
| `VITE_BASE44_APP_ID=${appId}\nVITE_BASE44_APP_BASE_URL=http://localhost:${resolvedPort}\n`, |
There was a problem hiding this comment.
Let's introduce function that provides local address, since we output it in 2 places in this file.
There was a problem hiding this comment.
Done — extracted localServerUrl(port) and reuse it for both the .env.local contents and the outro message.
| if (projectRoot) { | ||
| const envLocalPath = join(projectRoot, ".env.local"); | ||
| if (!(await pathExists(envLocalPath))) { | ||
| const { id: appId } = await initAppConfig(); | ||
| await writeFile( | ||
| envLocalPath, | ||
| `VITE_BASE44_APP_ID=${appId}\nVITE_BASE44_APP_BASE_URL=http://localhost:${resolvedPort}\n`, | ||
| ); | ||
| log.info("Created .env.local with app ID and dev server URL"); | ||
| } | ||
| } |
| await writeFile( | ||
| envLocalPath, | ||
| `VITE_BASE44_APP_ID=${appId}\nVITE_BASE44_APP_BASE_URL=http://localhost:${resolvedPort}\n`, | ||
| ); |
There was a problem hiding this comment.
Not sure I understand your answer.
Are you sure it's really required?
Which part is requiring it?
How it worked before?
When a project is cloned and `base44 dev` is run for the first time, there is no .env.local so the Vite plugin cannot proxy API calls to the local dev server and does not know the app ID. Write .env.local (VITE_BASE44_APP_ID + VITE_BASE44_APP_BASE_URL) after the dev server starts if the file is not already present. If .env.local exists it is left untouched so custom values are never clobbered. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The frontend's @base44/vite-plugin reads VITE_BASE44_APP_ID and VITE_BASE44_BACKEND_URL; the previous VITE_BASE44_APP_BASE_URL was read by nothing, so the backend redirect to the local dev server silently had no effect and the SDK kept hitting production. Also address review feedback: extract a localServerUrl() helper (used for both the env file and the outro message) and move the env.local write into a standalone writeEnvLocalIfMissing() function. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
0efe069 to
d7bfe88
Compare
Biome organizeImports wants node: builtins first; the Logger type import must follow them. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Note
Description
On first run of
base44 dev, the frontend's@base44/vite-pluginhad no app ID and fell back to the production backend instead of the local dev server. This PR makesdevwrite a.env.localwithVITE_BASE44_APP_IDandVITE_BASE44_BACKEND_URLwhen one does not already exist, so a fresh project points at the dev server out of the box. Existing.env.localfiles are left untouched.Related Issue
None
Type of Change
Changes Made
writeEnvLocalIfMissingtopackages/cli/src/cli/commands/dev.tsthat creates.env.localwithVITE_BASE44_APP_ID(frominitAppConfig) andVITE_BASE44_BACKEND_URLpointing at the resolved local dev server URL..env.localalready exists so user-maintained values are preserved.localServerUrl(port)helper and reused it for both the outro message and the env file.project.rootfromloadResourcesto know where to write the env file.packages/cli/tests/cli/dev.spec.ts: one verifies the file is created with the expected variables, the other verifies an existing file is not overwritten.Testing
npm test)Checklist
Additional Notes
The variable names (
VITE_BASE44_APP_ID,VITE_BASE44_BACKEND_URL) match what@base44/vite-pluginexpects on the frontend side.🤖 Generated by Claude | 2026-06-02 11:16 UTC | 5e3000d