首页 > 解决方案 > 如何使用自定义 webpack 在 React 上设置环境变量

问题描述

我的 React 应用程序不是由 create-react-app 运行的,而是一个自定义的 Webpack 配置。

我已经安装了dotenv//dotenv-expanddotenv-webpack.

我有.env/里面有变量的.env.development文件。API_URL

在我的网址文件中,

const { API_URL } = process.env

并使用它API_URL来获取数据。

但是在这个文件上,当 I 时console.log(process.env),它是空的。

我也尝试过更新webpack.config.js文件

const Dotenv = require('dotenv-webpack');

new Dotenv()

在插件数组中。

但还是不行。

我也尝试使用变量名REACT_APP_API_URL,但结果相同。

谁能帮我设置环境变量?

谢谢你。

webpack.config.js

const webpack = require('webpack')
const Dotenv = require('dotenv-webpack');
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpackMerge = require('webpack-merge')

const modeConfig = env => require(`./build-utils/webpack.${env}`)(env)
const presetConfig = require('./build-utils/loadPresets')

module.exports = ({ mode, presets } = { mode: 'production', presets: [] }) => {
  console.log('mode', mode, 'presets', presets)
  return webpackMerge(
    {
      mode,
      module: {
        rules: [
          {
            test: /\.(png|jpe?g|svg)$/,
            use: {
              loader: 'file-loader',
              options: {
                name: 'assets/[name].[ext]',
              }
            },
          },
        ],
      },
      node: {
        fs: 'empty'
      },
      resolve: {
        extensions: ['.js', '.json'],
      },
      output: {
        filename: 'bundle.js',
        chunkFilename: '[name].lazy-chunk.js',
        path: path.resolve(__dirname, 'build'),
        publicPath: mode === 'development' ? '/' : './'
      },
      devServer: {
        historyApiFallback: true
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: './build-utils/template.html'
        }),
        new webpack.ProgressPlugin(),
        new Dotenv()
      ]
    },
    modeConfig(mode),
    presetConfig({ mode, presets })
  )
}

标签: reactjswebpackenvironment-variables

解决方案


如果您尝试访问envJS 文件中的值,您通常需要拥有该dotenv插件。

const webpack = require('webpack')
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpackMerge = require('webpack-merge')

require('dotenv').config() // may need to set path to your .env file if it isn't at the root at the project

const modeConfig = env => require(`./build-utils/webpack.${env}`)(env)
const presetConfig = require('./build-utils/loadPresets')

module.exports = ({ mode, presets } = { mode: 'production', presets: [] }) => {
  return webpackMerge(
      ...
      plugins: [
        new HtmlWebpackPlugin({
          template: './build-utils/template.html'
        }),
        new webpack.ProgressPlugin(),
        new webpack.DefinePlugin({
           'process.env': {
               NODE_ENV: JSON.stringify(process.env.NODE_ENV),
               SOME_VALUE: JSON.stringify(process.env.SOME_VALUE),
               ...
            }
        })
      ]
    },
    ...
  )
}

注意:使用此实现,您将无法执行此操作, const { API_URL } = process.env因为DefinePlugin它会搜索和替换 JavaScript,它会在其中查找任何引用process.env.API_URL并将其替换为该值的任何值。因此API_URL将不存在于porcess.env,所以使用它只是做process.env.API_URL

你也可以使用dotenv-webpack,我认为你已经接近让它工作了。

const webpack = require('webpack')
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpackMerge = require('webpack-merge')

const Dotenv = require('dotenv-webpack');

const modeConfig = env => require(`./build-utils/webpack.${env}`)(env)
const presetConfig = require('./build-utils/loadPresets')

module.exports = ({ mode, presets } = { mode: 'production', presets: [] }) => {
  return webpackMerge(
      ...
      plugins: [
        new HtmlWebpackPlugin({
          template: './build-utils/template.html'
        }),
        new webpack.ProgressPlugin(),
        new Dotenv({
           path: envPath
        })
      ]
    },
    ...
  )
}

如果您需要更多帮助,请通过创建一个最小的、可重现的示例来分享更多详细信息。


推荐阅读