VueJS place multiple .env in folder

Viewed 1914

Hello I'm using VueJS 2 and I have multiple .env in my project. My app have .env for each company to select the company configuration (skin color / files...)

Actually I have all my .env in the root folder:

.env.company1-dev
.env.company1-staging
.env.company1-prod

.env.company2-dev
.env.company2-staging
.env.company2-prod

.env.company3-dev
.env.company3-staging
.env.company3-prod

So when I'll get 20 companies it will be confused on my root folder so it is possible to create a folder where I can place all my .env ?

The idea :

/environments/company1/ 
    .env.dev
    .env.staging
    .env.prod
    
/environments/company2/ 
    .env.dev
    .env.staging
    .env.prod
    
/environments/company3/ 
    .env.dev
    .env.staging
    .env.prod
3 Answers

On your vue.config.js file you can add:

const dotenv = require("dotenv");
const path = require("path");

let envfile = ".env";
if (process.env.NODE_ENV) {
    envfile += "." + process.env.NODE_ENV;
}

const result = dotenv.config({ 
    path: path.resolve(`environments/${process.env.VUE_APP_COMPANY}`, envfile)
});

// optional: check for errors
if (result.error) {
    throw result.error;
}

the before run you can set VUE_APP_COMPANY to a company name and run your app,

Note: It's important to put this code on vue.config.js and not in main.js because dotenv will use fs to read files.

References

The accepted answer we have also used in the past. But I found a better solution to handle different environments. Using the npm package dotenv-flow allows not only the use of different environments but has some more benefits like:

  • local overwriting of variables by using .env.local or .env.staging.local and so on
  • definition of defaults using .env.defaults

In combination we have set up our projects with this configuration:

.env
.env.defaults
.env.development
.env.production
.env.staging
.env.test

And the only thing you have to do in your vue.config.js, nuxt.config.js or other entry points is

require('dotenv-flow').config()

Reference: https://www.npmjs.com/package/dotenv-flow

The powershell solution

I was handling exactly the same problem. Accepted solution is kind of ok, but it did not solve all differences between companies. Also, if you are using npm, your scripts can look nasty. So if you have powershell, here is what I suggest - get rid of the .env files :)

You can keep your structure like you want in the question. Just convert the env files to ps1.

/build/company1/ 
    build-dev.ps1
    build-stage.ps1
    build-prod.ps1
    
/build/company2/ 
    build-dev.ps1
    build-stage.ps1
    build-prod.ps1
   

Inside each of those, you can fully customize all env variables, run build process and apply some advanced post-build logic (like careful auto-deploy, publishing, merging with api project, ..).

So for example company1\build-stage.ps1 can look like this:

# You can pass some arguments to the script
param (
    [string]$appName = "company1"
 )

# Set environment variables for vue pipeline
$env:VUE_APP_ENVIRONMENT = "company1-stage";
$env:NODE_ENV="development";
$env:VUE_APP_NAME=$appName;
$env:VUE_APP_API_BASE_URL="https://company1.stage.mycompany.com"

# Run the vue pipeline build
vue-cli-service build;

# Any additional logic e.g. 
# Copy-Item -Path "./dist" -Destination "my-server/my-app" -Recurse¨

Last part is easy - just call it (manualy or from integration service like TeamCity). Or, you can put it inside package.json.

...
"scripts": {
    "build-company1-stage": "@powershell -Command ./build/company1/build-stage.ps1 -appName Company-One",
  }
...

The you can call whole build process just by calling

npm run build-company1-stage

Similary, you can create localhost, dev, prod, test and any other environment. Let the javascript handle the part of building the app itself. For other advanced work, use poweshell. I think that this solution gives you much more flexibility for configuration and build process.

P.S. I know that this way I'm merging configuration and build process, but you can always extract the configuration outside the file if it gets bigger.

Related