johannschopplich / kirby-vue3-starterkit

✨ Kirby + Vue SPA starter: automatic routing, i18n, SEO and more!
MIT License
206 stars 19 forks source link

.env files not loading #50

Closed Small-Systems closed 1 year ago

Small-Systems commented 2 years ago

Here is another thing I found after some testing. The environment specific .env file is not being loaded. For example if you have a .env.development file and run vite in dev mode, it will actually just load the regular .env file.

Normally you would use loadEnv, and check the mode like this:

import { defineConfig, loadEnv } from 'vite' import vue from '@vitejs/plugin-vue' export default ({ mode }) => { process.env = {...process.env, ...loadEnv(mode, process.cwd())} return defineConfig ({...

In your case dotenv does not have access to the vite mode yet, so it always loads the "base" .env file. The vite.config.js file can be adapted using the method above, however doing so means it's no longer possible to define the process environment variables as you have using the non VITE prefixed variables (process.env.VITE_MULTILANG = process.env.KIRBY_MULTILANG) etc.

I'm not sure what the solution is, but I will post back here when I have an idea.

johannschopplich commented 2 years ago

You wil have to follow the official .env file naming conventions supported by Vite.

The file .env.development.example is intended to be renamed to .env, not .env.development. Make sure to follow the instructions on setting up the project.

Small-Systems commented 2 years ago

Ok, I think I had misunderstood how you had this setup. I was thinking I could use multiple .env files, for example have a .env.staging file and run vite build --mode staging to have it load that file.

johannschopplich commented 2 years ago

I think you got it right, the staging file should be loaded by Vite. 🤔

Small-Systems commented 2 years ago

The Vite way is to use the mode argument from the defineConfig function and load the correct env file based on that, see here: https://vitejs.dev/config/#environment-variables.

It seems that dotenv does not automatically load different env files. And it needs to be done like this:

const whichenv = process.env.NODE_ENV === "production" ? `.${process.env.NODE_ENV}` : ""; require("dotenv").config({ path: `.env${whichenv}` });

Which theoretically means you could use a .env and a .env.production file, but only these two as node itself only has two modes. In order to leverage vite's custom "mode" parameter i.e: vite build --mode custommode then we need to read the mode argument and load the .env accordingly: const env = loadEnv(mode, process.cwd(), '').

This would be fine, except then we can only read variables starting with VITE_, which breaks your process.env.VITE_BACKEND_URL, process.env.VITE_BACKEND_API_SLUG, process.env.VITE_MULTILANG variables.

I think it's not too hard to find a solution, it would just mean eith: using the vite way of loading env files and renaming the three non "VITE_" vars used. Or alternatively having all vars in one .env file and using a naming convention like:

KIRBY_DEV_HOSTNAME
KIRBY_STAGE_HOSTNAME
CONTENT_DEV_API_SLUG  
CONTENT_STAGE_API_SLUG

What do you think

Small-Systems commented 2 years ago

This is would be my proposed solution. Instead of using dotenv, use the vite function loadEnv() inside the default function. This way you can access the correct mode and also use vite's env loading priorities. You would have to pass the two correct env prefixes in order to access the both the KIRBY_ and VITE_ prefixed variables. You could rename also CONTENT_API_SLUG as VITE_BACKEND_API_SLUG directly in the env file and change the reference in your kirby plugins, or also pass CONTENT_ as a prefix. I've tested this setup and it works fine.

import { resolve } from "path";
import { defineConfig, loadEnv } from "vite";
import Vue from "@vitejs/plugin-vue";
import Components from "unplugin-vue-components/vite";

const root = "src";

export default ({ mode }) => {
  process.env = {
    ...process.env,
    ...loadEnv(mode, process.cwd(), ["VITE_", "KIRBY_"]),
  };

  process.env.VITE_BACKEND_URL = `${process.env.KIRBY_DEV_PROTOCOL}://${process.env.KIRBY_DEV_HOSTNAME}:${process.env.KIRBY_DEV_PORT}`;
  process.env.VITE_MULTILANG = process.env.KIRBY_MULTILANG;

  return defineConfig({
    root,
    ...
johannschopplich commented 2 years ago

Thanks for your input and feedback. Looks interesting! Could you open a PR, please?