Handling server-side/sensitive/runtime variables #3176
Description
Context
Currently, Vite indiscriminately replaces process.env.
with ({}).
:
vite/packages/vite/src/node/plugins/define.ts
Lines 33 to 38 in 7cd8d78
I'm not sure if this behavior is Vite is attempting to protect SPA authors from accidentally using Confirmed with Evan that this was to support libraries that indiscriminately use process.env.SECRET
in their code.process.env.NODE_ENV
.
The Problem
Applications that have a server-side encounter a common issue of needing to be able to access sensitive information from environment variables, e.g. database or API credentials. Aside from secrets, it is also possible to require runtime variables that you don't know at build time. Currently people are working around this using process.env['SECRET']
to avoid the string replacement, but it is entirely possible that in the future Vite decides to similarly replace process.env[
with ({})[
given the above code. I am unsure if this is the "blessed" way to access secrets or an oversight, considering it completely circumvents the concerns written above.
Using VITE_
prefixed environment variables is not a solution. It is explicitly documented that it should not contain sensitive information.
Using define is not a solution:
- That would be baked in at build time, which is not appropriate for all use cases.
(e.g. heroku database URLs can change across application reboots, so runtime ENV vars are required) - That exposes it to client side code because it blindly does a find-and-replace.
Potential Solutions
(in no particular order)
- This could instead be implemented individually by SSR providers. This seems counterproductive if the solution can be framework-agnostic, but would be a necessity if it is determined to be outside of Vite's scope or capabilities.
- Declare
process.env['SECRET']
as a "blessed" way to access runtime variables, although then it is unclear whyprocess.env.
is replaced in the first place. - Stop replacing
process.env.
- This replacement behavior is not currently written in the docs. - Create a "store" somewhere (in the Vite config?) that could contain such information, although I'm not sure how to expose this to the user. Vite doesn't really "know" about server vs client code aside from SSR'd code, and not all SSR code should have access to secrets. This also doesn't really solve the runtime non-secret situation.
- Have a config option to disable the
process.env.
replacement.
Non-solutions
- Start replacing
process.env[
with({})[
if you're sadistic