vite: Exposed env vars are not available

Describe the bug

Using an .env file to define environment variables, static values are passed on and available in Vue as expected. Exposing existing env vars to Vue, however, does not work and produces empty values.

I’ve exposed the env var using the syntax from this comment.

STR:

  • open reproduction
  • start dev server with command PORT=4000 npm run dev

Expected: PORT should be available from main.js and output 4000.

Actual: PORT is an empty string.

Reproduction

https://stackblitz.com/edit/vitejs-vite-bxj6nd?devtoolsheight=33&file=.env

System Info

System:
    OS: macOS 11.6.1
    CPU: (12) x64 Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
    Memory: 1.36 GB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.13.2 - ~/.nix-profile/bin/node
    npm: 8.1.2 - ~/.nix-profile/bin/npm
  Browsers:
    Brave Browser: 97.1.34.81
    Safari: 15.2

Used Package Manager

npm

Logs

...
vite:config   env: {
vite:config     VITE_PORT: '',
vite:config     BASE_URL: '/',
vite:config     MODE: 'development',
vite:config     DEV: true,
vite:config     PROD: false
vite:config   },
...

Validations

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 3
  • Comments: 16 (5 by maintainers)

Most upvoted comments

but use all the process env will trigger unexpected error, may be env set aaa=123 in the build mode will replace const aaa = 123 to const 123 = 123

This is about explicitly exposed env vars, not all env vars. Only if you write

VITE_PORT=$PORT

in a .env file, it should be made available in Vite.

Hi, I am experiencing the dotenv variables expanding issue while trying to develop a component for my vue3 app that displays its current version from package.json.

.env

# Only VITE_SOME_KEY will be exposed as import.meta.env.VITE_SOME_KEY to your client source code
VITE_APP_VERSION=$npm_package_version

AppVersion.vue

<template>
  <span>v. {{ version }}</span>
</template>

<script setup lang="ts">
const version = import.meta.env.VITE_APP_VERSION;
</script>

Other solution that worked for me (maybe better in my case) was to use vite’s define config option:

vite.config.ts

import { defineConfig, loadEnv } from 'vite'

// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {
  // src: https://github.com/vitejs/vite/blob/main/packages/vite/src/node/env.ts
  // Load env file based on `mode` in the current working directory.
  // Set the third parameter to '' to load all env regardless of the `VITE_` prefix.
  const env = loadEnv(mode, process.cwd(), '')
  return {
    // vite config
    define: {
      __APP_VERSION__: JSON.stringify(env.npm_package_version),
    }
  }
})

.env.d.ts

/// <reference types="vite/client" />

declare const __APP_VERSION__: string;

AppVersion.vue

<template>
  <span>v. {{ version }}</span>
</template>

<script setup lang="ts">
/* global __APP_VERSION__ */
const version = __APP_VERSION__;
</script>

Hope it helps someone.

I am looking forward guys from dotenv-expand to solve the issue: https://github.com/motdotla/dotenv-expand/issues/55

I’m in the same situation.

Just returns an empty string.

In my case it was an improper Docker / Docker Compose configuration. In my Dockerfile I had to make sure to specify the arguments which I want to pass during Docker build time as ARG and assign them to ENV variables, something like

ARG HASURA_GRAPHQL_URL
ENV VITE_HASURA_GRAPHQL_URL $HASURA_GRAPHQL_URL

and my docker-compose.yml looks like

services:
  my-service:
    build:
      dockerfile: my-service/Dockerfile
      args:
        HASURA_GRAPHQL_URL: https://some-url

Maybe this helps 🤷🏼‍♂️

@svenjacobs The workaround that I’m currently using is to declare the env var as part of the script that I run to start vite, e. g.:

VITE_PORT=$PORT vite

That’s what I tried, please look at the reproduction and debug output above.

I’m able to reproduce this, but this doesn’t seem to be Vue specific

You’re right, plus issues here are supposed to be framework agnostic. I’ve removed it from the title, thanks!