Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using dotenv with react & webpack

I'm finding information that you can use dotenv with react using

import React from "react"
console.log(process.env.REACT_APP_API_KEY)

however when I create my .env file in the root of my direction i get a undefined message in the console.

I should note that i am NOT using react-create-app.

Here is my .env file

REACT_APP_API_KEY=secretKey

Here is my webpack config file.

Is there any way I can use dotenv without using node.js and creating a small server.

const currentTask = process.env.npm_lifecycle_event;
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { postcss } = require("postcss-mixins");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const fse = require("fs-extra");

const postCSSPlugins = [
  require("postcss-import"),
  require("postcss-mixins"),
  require("postcss-simple-vars"),
  require("postcss-nested"),
  require("postcss-hexrgba"),
  require("autoprefixer")
];

class RunAfterCompile {
  apply(compiler) {
    compiler.hooks.done.tap("Copy images", function () {
      fse.copySync("./app/assets/images", "./docs/assets/images");
    });
  }
}

let cssConfig = {
  test: /\.css$/i,
  use: [
    "css-loader?url=false",
    { loader: "postcss-loader", options: { plugins: postCSSPlugins } }
  ]
};

let pages = fse
  .readdirSync("./app")
  .filter(function (file) {
    return file.endsWith(".html");
  })
  .map(function (page) {
    return new HtmlWebpackPlugin({
      filename: page,
      template: `./app/${page}`
    });
  });

let config = {
  entry: "./app/assets/scripts/App.js",
  plugins: pages,
  module: {
    rules: [
      cssConfig,
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-react", "@babel/preset-env"],
            plugins: ["@babel/plugin-transform-runtime"]
          }
        }
      }
    ]
  }
};

if (currentTask == "dev") {
  cssConfig.use.unshift("style-loader");
  config.output = {
    filename: "bundled.js",
    path: path.resolve(__dirname, "app")
  };
  config.devServer = {
    before: function (app, server) {
      server._watch("./app/**/*.html");
    },
    contentBase: path.join(__dirname, "app"),
    hot: true,
    port: 3000,
    host: "0.0.0.0",
    historyApiFallback: { index: "/" }
  };
  config.mode = "development";
}

if (currentTask == "build") {
  cssConfig.use.unshift(MiniCssExtractPlugin.loader);
  postCSSPlugins.push(require("cssnano"));
  config.output = {
    filename: "[name].[chunkhash].js",
    chunkFilename: "[name].[chunkhash].js",
    path: path.resolve(__dirname, "docs")
  };
  config.mode = "production";
  config.optimization = {
    splitChunks: { chunks: "all" }
  };
  config.plugins.push(
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({ filename: "styles.[chunkhash].css" }),
    new RunAfterCompile()
  );
}

module.exports = config;

i've been at this for a couple of hours now and I can't seem to find what i need online. Hoping someone has ran into this issue before.

thanks

like image 438
Nick Avatar asked Sep 01 '25 21:09

Nick


2 Answers

There is a dotenv-webpack plugin specifically for this situation.

Setup is dead simple:

// webpack.config.js
const dotEnv = require('dotenv-webpack')
module.exports = {
  plugins: [new dotEnv()]
}

Docs

EDIT

This answer is too verbose for comments:

You are adding dotEnv to the wrong plugins property.

 module: {
    rules: [
      cssConfig,
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-react", "@babel/preset-env"],
            plugins: [/* WRONG */ new dotEnv(), "@babel/plugin-transform-runtime"]
          }
        }
      }
    ]
  }

When it should be added here:

if (currentTask == "dev") {
  config.plugins = [/* RIGHT */ new dotEnv()]
}
like image 89
Alex Mckay Avatar answered Sep 03 '25 11:09

Alex Mckay


dotenv variables will only be available in webpack and process for things that are not being compiled by webpack.

In order to make your environment variables available in webpack compiled files you need to inject it using webpack's define or enviornment plugins.

https://webpack.js.org/plugins/environment-plugin/

This will replace all environment strings in your files with environment variables during compilation process.

The reason why your key is giving undefined is because when webpack (babel) is compiling it that string doesn't exist because it was never replaced/injected through webpack environment variables.