首页 > 解决方案 > Undefined .env variables when webpack goes into production mode

问题描述

I'm using the dot-env NPM package in order to pass simple variables to my webpack/express application.

When I run in PRODUCTION mode for webpack, all my variables from .env become undefined.

I'm building up a development and production webpack config files and currently have the following setup.

Any advise on the mistakes I'm making and why my .env variables are being dropped would be greatly appreciated.

标签: node.jsexpresswebpackdotenv

解决方案


如果您在其插件部分查看 yow webpack.prod,您就会喜欢它。new webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': JSON.stringify('production') } 所以基本上你将 process.env 设置为等于 What Eva is there

解决方案

首先你需要安装两个模块

  • dotenv-expand
  • dotenv
$ npm i -D dotenv-expand dotenv

下一个

创建一个名为 的新文件env.js,我的意思是名称由您决定。将文件放在与 webpack 相同的位置

环境.js

'use strict';

const fs = require('fs');
const path = require('path');

const {NODE_ENV} = process.env.NODE_ENV;

const dotenvFile = `.env.${NODE_ENV}`;

require('dotenv-expand')(
      require('dotenv').config({
        path: dotenvFile,
      }));
  

const appDirectory = fs.realpathSync(process.cwd());
process.env.NODE_PATH = (process.env.NODE_PATH || '')
  .split(path.delimiter)
  .filter(folder => folder && !path.isAbsolute(folder))
  .map(folder => path.resolve(appDirectory, folder))
  .join(path.delimiter);

// set your own prefix
const PREFIX = /^ENETO_/i;

function getEnvironment() {
  const raw = Object.keys(process.env)
    .filter(key => PREFIX.test(key))
    .reduce(
      (env, key) => {
        env[key] = process.env[key];

        return env;
      },
      {
        NODE_ENV: process.env.NODE_ENV || 'development',
        PORT: process.env.PORT||3000,
      }
    );
  const stringified = {
    'process.env': Object.keys(raw).reduce((env, key) => {
      env[key] = JSON.stringify(raw[key]);
      return env;
    }, {}),
  };

  console.log("stringified", stringified);

  return { raw, stringified };
}

module.exports = getEnvironment();

笔记

确保添加一个前缀,以便所有这些都以 a 开头,PREFIX 您可以设置自己的前缀

现在在每个 webpack 上添加它;

webpack.server.js

/**
 webpack server
*/
"use strict";

const path = require("path");
const nodeExternals = require("webpack-node-externals");
const webpack = require("webpack");
/**
 * HERE IS IMPORTED ALL THE WAY TO THE BOTTOM YOU'LL SEE IT
 */
const vars = require("./env");
const { NODE_ENV } = process.env;

const entry = [path.join(__dirname, NODE_ENV === "production" ? `../src/prod.ts` : `../src/dev.ts`)];
module.exports = {
    target: "node",
    name: "server",
    externals: [nodeExternals()],
    entry: [
        require.resolve("@babel/register"),
        require.resolve("core-js/proposals"),
        require.resolve("core-js"),
        require.resolve("@babel/runtime-corejs3/regenerator"),
        require.resolve("es6-promise/auto"),
        ...entry,
    ],
    devtool: false,
    mode: process.env.NODE_ENV,
    output: {
        filename: "[name]-bundle.js",
        chunkFilename: "[name].chunk.js",
        path: path.resolve(__dirname, "../bundle"),
        publicPath: "/",
        libraryTarget: "commonjs2",
    },
    resolve: {
        extensions: [".ts", ".tsx", ".js"],
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: "babel-loader",
                    },
                ],
            },
            {
                test: /\.(js|mjs)$/,
                exclude: /@babel(?:\/|\\{1,2})runtime/,
                loader: require.resolve("babel-loader"),
                options: {
                    babelrc: false,
                    configFile: false,
                    compact: false,
                    presets: [[require.resolve("@babel/preset-env")]],
                    cacheDirectory: true,
                    cacheCompression: false,
                    sourceMaps: false,
                    inputSourceMap: false,
                },
            },
            {
                test: /\.(png|jpg|gif)$/,
                use: [
                    {
                        loader: "file-loader",
                    },
                ],
            },
        ],
    },
    plugins: [new webpack.DefinePlugin(vars.stringified)],
};

对你的客户做同样的事情,就是这样:3


推荐阅读