vitejs / vite

Next generation frontend tooling. It's fast!
http://vitejs.dev
MIT License
67.06k stars 6.02k forks source link

Destructuring `import.meta.env` Yields `Cannot destructure property of (intermediate value)` #15285

Open shellscape opened 9 months ago

shellscape commented 9 months ago

Describe the bug

When using define to replace process.env with import.meta.env, attempting a destructuring of import.meta.env will result in an error at runtime:

Uncaught TypeError: Cannot destructure property '<var name>' of '(intermediate value).env' as it is undefined.

It is/was quite common and completely valid to destructure process.env when writing for the Node platform, as it provided quick and easy means of init. e.g.:

const { DISABLE_THING = false, LOG_LEVEL = 'info' } = process.env;

In many cases when a Vite app pulls in a module which contains code like this, only a portion of the module is used as pertaining to the frontend app, and this kind of assignment is frequently used as an escape hatch or to block further execution based on context.

I've attempted to use a myriad of keyword combinations to search both the docs and the repo, but haven't found anything addressing this specific issue.

Reproduction

https://stackblitz.com/edit/vitejs-vite-9wbsbd

Steps to reproduce

  1. Run npm run build
  2. Run npm run serve
  3. Open devtools for the browser pane, and observe the error:
Uncaught TypeError: Cannot destructure property 'TEST_VAR' of '(intermediate value).env' as it is undefined.

System Info

This seems to affect both Windows and Mac OS, but at the least should be tested against the Stackblitz environment.

Used Package Manager

npm

Logs

n/a

Validations

stackblitz[bot] commented 9 months ago

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.

shellscape commented 9 months ago

This appears to be a conflict/race between define and when vite's internals replace import.meta.env with the JSON object with VITE_* keys.

XiSenao commented 9 months ago

You can inject the properties in process.env into import.meta.env using the following method.

// main.ts
const { DEV } = import.meta.env;

// vite.config.ts
export default defineConfig({
  define: 
    Object
      .keys(process.env)
      .reduce(
        (pre, cur) => (pre[`import.meta.env.${cur}`] = JSON.stringify(process.env[cur]), pre), 
        {}
      ),
})
shellscape commented 9 months ago

Yes, I'm aware. This issue isn't a request for help.