Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Env variables are not accessed by vite in PROD #3004

Closed
narender2031 opened this issue Dec 8, 2021 · 17 comments
Closed

Env variables are not accessed by vite in PROD #3004

narender2031 opened this issue Dec 8, 2021 · 17 comments

Comments

@narender2031
Copy link

Describe the bug

I am using the docker image for the production build. I have set my environment variables in docker and they are accessible by using env. But when I build the app these are not accessed by Vite.

Please help me here!

Reproduction

Create Svelte kit app by started.

  • create the docker image
  • Create the env variables in the docker system.
  • use the VITE_ as a prefix.

Logs

No response

System Info

Undefined

Severity

blocking all usage of SvelteKit

Additional Information

No response

@Conduitry
Copy link
Member

VITE_ variables are bundled during build, not looked at at runtime in prod mode. If your Dockerfile is setting them at app runtime with ENV, this is expected. If that's not what's happening, we need a proper reproduction.

@narender2031
Copy link
Author

VITE_ variables are bundled during the build, not looked at runtime in prod mode. If your Dockerfile is setting them at app runtime with ENV, this is expected. If that's not what's happening, we need proper reproduction.

@Conduitry Yes, Dockerfile is setting them at app runtime with ENV.
Do you know any workaround for this.

@narender2031
Copy link
Author

@Conduitry

.env

VITE_SOME_ENV=hello

variable.ts

console.log(import.meta.env) // {VITE_SVELTEKIT_AMP: '', BASE_URL: '/_app/', MODE: 'production', DEV: false, PROD: true}
export const variables = {
	SOME_ENV: <string>import.meta.env.VITE_SOME_ENV,
};

NOTE: import.meta.env don't have VITE_SOME_ENV after the build

api.ts

import { variable } from './variable.ts'

const data = variable.SOME_ENV // const data = "undefined "

after the build const data = "undefined " it replaced by undefined.

My docker image already has all the env variable inside the system env. When I build the file my env data is replaced by undefined.

@rmunn
Copy link
Contributor

rmunn commented Dec 9, 2021

What happens if you change import.meta.env.SOME_ENV to import.meta.env['SOME_ENV']? I remember a while ago Vite was doing text replacement specifically looking for the text import.meta.env. (with a trailing period), but I haven't looked at it in months and don't know if that's still current Vite behavior. But if import.meta.env['SOME_ENV'] works for you then that could be an easy workaround.

@benmccann
Copy link
Member

benmccann commented Dec 10, 2021

There should be some improvement on that front with Vite 2.7: vitejs/vite#5404

@bluwy
Copy link
Member

bluwy commented Dec 11, 2021

I don't think import.meta.env.SOME_ENV or import.meta.env['SOME_ENV'] would work, even with Vite 2.7. import.meta.env is a per-file variable and replacements must be done during build-time. .env files wouldn't work as well so we'd need a different strategy for this, here's two options:

  1. Have a separate build script in docker that generates a static JS file, which would be imported by app.html.
// env.js
window.__MY_ENV__ = "something"
// your-code.js
console.log(__MY_ENV__)

Keep in mind that you need to shim it in dev and SSR if needed, possible with kit.vite.define.

  1. Or have a separate build script that does a find+replace on the final build assets.

@IsaacHub

This comment has been minimized.

@bluwy

This comment has been minimized.

@bartosjiri
Copy link

@benmccann Tried upgrading to 1.0.0-next.202, variables are still undefined with import.meta.env.VAR_KEY and import.meta.env['VAR_KEY'] when provided through Docker.

Reproduction repo available here.

@korywka
Copy link

korywka commented Dec 20, 2021

Sort of duplicate: #3030

@benmccann
Copy link
Member

Please see the environment variable FAQ: https://kit.svelte.dev/faq#env-vars

To use at runtime you'll need to instantiate yourself (see svelte.dev's hooks.js for an example). You can then pass to your templates using session

@narender2031

This comment was marked as off-topic.

@SwatDoge
Copy link

This problem is still here and quite infuriating.

@SwatDoge
Copy link

SwatDoge commented Oct 17, 2022

This is an incredibly ugly hack to get this working, it converts process.env variables prefixed with VITE_ to an .env file before before runtime.

docker build file

...

COPY . .

CMD ["pnpm", "run", "preview"]

package.json (I have to use preview instead of dev, as otherwise webworkers break on ff, ive been having fun :/)

"scripts": {
    "build": "node ./.patch/env_bind.js && vite build && rm .env",
    "preview": "node ./.patch/env_bind.js && vite build && rm .env && vite preview --host"
},

.patch/env_bind.js

// Vite imports environment variables through import.meta.env. import.meta.env does not import docker variables like process.env does. This file patches this.
import fs from "fs";

const vite_env_variables = Object.entries(process.env).filter(variable => variable[0].startsWith("VITE_"));
const vite_env_variable_string = vite_env_variables.map(variable => variable[0] + "=" + variable[1]).join("\n");
fs.writeFileSync(".env", vite_env_variable_string, {encoding: "utf-8"});

I don't recommend using this, but in my case I dont have another choice until import.meta.env gets all the env variables

@AgusVelez5
Copy link

Hey, any update on this?

@cpres
Copy link

cpres commented Mar 2, 2023

I solved this by building the .env from a shell script, using a pre-populated .env with =null for each variable.

docker-entry.sh:

#!/bin/sh

SRC=.env
OUTPUT="// generated"

while IFS="" read -r line || [ -n "$line" ]; do
    use_line=$line

    if expr "$line" : "VITE" > /dev/null; then
        ENVIRONMENT_VARIABLE_NAME=$(echo "$line" | sed -re 's/=.*//g')
        value=$(printenv "$ENVIRONMENT_VARIABLE_NAME")

        if [ "${value}" ] && [ "${value-x}" ]; then
            use_line="$ENVIRONMENT_VARIABLE_NAME = '$value';"
        fi
    fi

    OUTPUT="$OUTPUT\n$use_line"
done <$SRC

echo "$OUTPUT" > $SRC

http-server dist

@zebra-f
Copy link

zebra-f commented Mar 6, 2024

https://stackoverflow.com/a/77490465/17756110 If anyone is still looking for the solution to this problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests