Repository navigation
.env loading quirks across the VS Code extensions (dotEnvPath, cwd, missing babel.cjs)
#4562
Unanswered
unrevised6419
asked this question in
Q&A / Support
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Follow-up to #2951. Loading
.envfromgraphql.config.tsbehaves differently in each GraphQL VS Code extension, and the documenteddotenv/configpattern works only by accident. Below is what I found digging into the published bundles (graphql.vscode-graphql0.13.4,graphql.vscode-graphql-execution0.3.4,graphql-config5.1.7).1.
dotenv/configresolves.envagainstprocess.cwd(), which is not the workspaceBoth extensions call
loadConfig({ rootDir: <workspace folder> }).rootDironly tells cosmiconfig where to look forgraphql.config.*. The config module itself is evaluated with the process's working directory, which is whatever VS Code was launched from (for example/when started from the Dock, or the repo when started withcode .).So these only work when VS Code happens to be started from the project directory:
What works everywhere is resolving the path from the config file's own location:
The CommonJS equivalent (
graphql.config.js/graphql.config.cjs):Runtime support for
process.loadEnvFile. The config is evaluated by the Node.js runtime that ships inside VS Code (Electron), not by the Node installed on the machine.process.loadEnvFilewas added in Node v21.7.0 / v20.12.0 (experimental until v22.21.0 / v24.10.0). VS Code 1.90 and 1.91 ship Node 20.9.0 and don't have it; VS Code 1.92 (July 2024, Electron 30, Node 20.14.0) is the first release that does. Bothvscode-graphqlandvscode-graphql-executiondeclare"engines": { "vscode": "^1.63.0" }, so on VS Code 1.63–1.91 usedotenvwith an explicitpathinstead; it works on any version.loadEnvFilethrows when the file is missing, so a wrong path fails early instead of silently leaving the variables undefined.process.chdir(rootDir)is not a good fix inside the extensions: the extension host is shared with every other extension, loading is async (so concurrent loads would race on one global cwd), and multi-root workspaces have several roots.2.
graphql-config.dotEnvPathonly reaches the language serverThe fix from #2951 (and #3964) is the
graphql-config.dotEnvPathsetting. Invscode-graphqlit amounts to:That runs in the language server process (
out/serverIpc/out/serverStdio), so it populates that process'sprocess.envonly.vscode-graphql-executionevaluates the config in the extension host, a different process, and has no equivalent:dotEnvPathappears neither in itspackage.jsonnor in its bundle. Soextensions.endpoints.default.url: process.env.X(or${X}interpolation in YAML) stays undefined for the execution extension even with the setting configured.3.
vscode-graphql-executionships jiti without its transformThe execution extension bundles jiti v2, whose
createJitiwrapper lazily loads the Babel transform:After bundling, that resolves to
<extension>/dist/babel.cjs, and the published extension does not include that file (dist/only holdsextension.js,helpers/,providers/). As far as I can tell, this means the execution extension cannot compile agraphql.config.tson its own. It only picks up a compiled copy when jiti's shared cache ($TMPDIR/jiti/) already holds one for the current file contents, written by the language server, codegen, or the CLI. Because the cache key includes a content hash, every edit to the config breaks it again until something else recompiles it. That makes the.envissues above look intermittent.The language server bundle does not have this problem, since its Babel transform (including the
import.meta.dirname/import.meta.filenamerewrite) is inlined.Suggestions
vscode-graphql-executionhonoursgraphql-config.dotEnvPath, resolved against the workspace folder, before evaluating the config.dist/babel.cjswith the execution extension (or mark jiti external / copy the file inesbuild.js)..envrelative to the config file instead of usingimport "dotenv/config".Happy to open issues or PRs for any of these if they sound right.
All reactions