webpackdotenv

Use Dotenv and EnvironmentPluging with webpack configuration


I am using webpack as a bundeler , I have an env file where I set my environments in it and then read them using Dotenv

 plugins: [
    new HtmlWebpackPlugin({
      template: './public/template.html',
    }),
    new webpack.EnvironmentPlugin(['API_HOST', 'OS']),
    new Dotenv({
      path: path.resolve(__dirname, '.', '.env.dev'),
      safe: true,
    }),
  ],

now a new requirement has been added, to use the variable from the system env variable and if it doesn't exist then use the one in the file , I know that there is a flag in the Dotenv for it:

systemvars = true 

but the idea is I do not want the whole vars, I only need two for example so I thought it is better to use

EnvironmentPlugin

like

new webpack.EnvironmentPlugin(['API_HOST', 'OS']),

but this cannot be used with Dotenv; for an example if the API_HOST env variable in both system and env file I will get

Compiled with problems:

WARNING

DefinePlugin
Conflicting values for 'process.env.API_HOST'

my question:


Solution

  • I found this solution

    const common = require('./webpack.common');
    const webpack = require('webpack');
    const dotenv = require('dotenv')
    const envPath =  path.resolve(__dirname, '.', '.env.prod');
    const envConfig = dotenv.config({ path: envPath }).parsed;
    console.log("we are going back to the time we new ", process.env.OS)
    
     plugins: [
        new webpack.DefinePlugin ({
          'process.env.API_HOST': JSON.stringify(process.env.API_HOST || envConfig?.API_HOST),
          'process.env.API_PORT': JSON.stringify(process.env.API_PORT || envConfig?.API_PORT),
          'process.env.APP_TITLE': JSON.stringify(process.env.APP_TITLE || envConfig?.APP_TITLE),
          'process.env.COPY_RIGHT_DATE': JSON.stringify(process.env.COPY_RIGHT_DATE || envConfig?.COPY_RIGHT_DATE),
          'process.env.OS': JSON.stringify(process.env.OS || 'nothing'),
        })]
    

    or we can use new webpack.EnvironmentPlugin

     plugins: [
        new webpack.EnvironmentPlugin ({
          process.env.API_HOST: process.env.API_HOST || envConfig?.API_HOST,
          process.env.API_PORT: process.env.API_PORT || envConfig?.API_PORT,
          process.env.APP_TITLE: process.env.APP_TITLE || envConfig?.APP_TITLE,
          process.env.COPY_RIGHT_DATE: process.env.COPY_RIGHT_DATE || envConfig?.COPY_RIGHT_DATE,
          process.env.OS: process.env.OS || 'nothing',
        })]
    

    this will serve using the env from the system, if it doesn't exist then use it from the file, and without exposing the whole system variables