You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Webpack项目中process.env在业务代码失效及版本输出问题

非CRA搭建的Webpack项目中process.env业务代码不生效的解决方案

问题场景

自行搭建非CRA(Create React App)的Webpack项目时,process.env在webpack.config.js中可正常读取,但在app.js等业务代码里无法生效。需求是将版本信息输出到控制台,构建后能在服务器端查看,拒绝硬编码版本号的方式,现有配置未达预期。

现有代码片段

App.js业务代码

import React from "react";
import styles from "./styles.scss";

const onClickEvent = (e) => {
  e.preventDefault();
  alert("You Clicked Me!");
};

const App = () => {
  console.log(process.env.TERM_PROGRAM_VERSION);
  return (
    <div className={styles.content}>
      <div className={styles.label}>OWN WEBPACK</div>
      <button className={styles.btn} onClick={onClickEvent}>
        Click Me 😎
      </button>
    </div>
  );
};

export default App;

webpack.config.js配置

const webpack = require("webpack");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

const production = process.env.NODE_ENV === "production";
const Dotenv = require("dotenv-webpack");
console.log(process.env.TERM_PROGRAM_VERSION);

module.exports = {
  entry: { myAppName: path.resolve(__dirname, "./src/index.js") },
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: production ? "[name].[contenthash].js" : "[name].js",
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: ["babel-loader"],
      },
      {
        test: /\.s(a|c)ss$/,
        exclude: /node_modules/,
        use: [
          production ? MiniCssExtractPlugin.loader : "style-loader",
          {
            loader: "css-loader",
            options: {
              modules: true,
              sourceMap: !production,
            },
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: !production,
            },
          },
        ],
      },
    ],
  },
  resolve: {
    extensions: ["*", ".js", ".jsx", ".scss"],
  },
  plugins: [
    new CleanWebpackPlugin(),
    new Dotenv(),
    new webpack.HotModuleReplacementPlugin(),
    new HtmlWebpackPlugin({
      title: "Webpack & React",
      template: "./src/index.html",
      favicon: "./public/favicon.ico",
    }),
    new MiniCssExtractPlugin({
      filename: production ? "[name].[contenthash].css" : "[name].css",
    }),
    new webpack.DefinePlugin({
      "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
      "process.env.MY_ENV": JSON.stringify(process.env.MY_ENV),
    }),
  ],

  devServer: {
    port: 3001,
    hot: true,
  },
  mode: production ? "production" : "development",
};

package.json脚本配置

"scripts": {
  "start": "npm run build && node server/index.js",
  "dev": "NODE_ENV=development test=$TERM_PROGRAM_VERSION webpack serve --config webpack.config.js",
  "build": "NODE_ENV=production webpack --config webpack.config.js",
  "build:dev": "NODE_ENV=development webpack --config webpack.config.js",
  "build:watch": "NODE_ENV=development node ./node_modules/webpack/bin/webpack.js --config webpack.config.js --watch"
},

服务器端代码server/index.js

const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const app = express();

if (process.env.NODE_ENV === 'development') {
    console.log('in development.');
} else {
    console.log('in production.');
}

/* App Config */
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, '../dist')));


/* Server Initialization */
app.get('/', (req, res) => res.sendFile('index.html'));
var port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Server initialized on: http://localhost:${port} // ${new Date()}`));

问题根源

  1. 环境变量传递错误:dev脚本中把版本变量命名为test,但业务代码读取的是TERM_PROGRAM_VERSION,变量名不匹配
  2. 未显式注入业务代码:仅通过Dotenv插件无法让业务代码直接读取系统环境变量,必须通过webpack.DefinePlugin显式注入
  3. 生产构建未传变量:build等生产脚本未传递版本相关环境变量,导致构建后无版本信息

修复方案

1. 修正package.json的环境变量传递

将所有脚本中的版本变量名改为TERM_PROGRAM_VERSION,确保生产构建也传递该变量:

"scripts": {
  "start": "npm run build && node server/index.js",
  "dev": "NODE_ENV=development TERM_PROGRAM_VERSION=$TERM_PROGRAM_VERSION webpack serve --config webpack.config.js",
  "build": "NODE_ENV=production TERM_PROGRAM_VERSION=$TERM_PROGRAM_VERSION webpack --config webpack.config.js",
  "build:dev": "NODE_ENV=development TERM_PROGRAM_VERSION=$TERM_PROGRAM_VERSION webpack --config webpack.config.js",
  "build:watch": "NODE_ENV=development TERM_PROGRAM_VERSION=$TERM_PROGRAM_VERSION node ./node_modules/webpack/bin/webpack.js --config webpack.config.js --watch"
},

2. 通过DefinePlugin注入版本变量到业务代码

在webpack.config.js的DefinePlugin配置中添加TERM_PROGRAM_VERSION,确保业务代码能读取到:

new webpack.DefinePlugin({
  "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
  "process.env.MY_ENV": JSON.stringify(process.env.MY_ENV),
  "process.env.TERM_PROGRAM_VERSION": JSON.stringify(process.env.TERM_PROGRAM_VERSION)
}),

3. 验证业务代码输出

此时App.js中的console.log(process.env.TERM_PROGRAM_VERSION)应该能正常输出版本信息,可优化输出格式:

console.log(`当前应用版本: ${process.env.TERM_PROGRAM_VERSION}`);

4. 服务器端查看版本(可选)

如果需要在服务器启动时查看构建版本,可以在构建时生成version.json文件:

  • 在webpack.config.js的plugins数组中添加自定义插件:
{
  apply: (compiler) => {
    compiler.hooks.done.tap('WriteVersionFile', () => {
      const fs = require('fs');
      const version = process.env.TERM_PROGRAM_VERSION;
      fs.writeFileSync(path.resolve(__dirname, './dist/version.json'), JSON.stringify({ version }));
    });
  }
}
  • 修改server/index.js读取版本文件:
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const fs = require('fs');
const app = express();

// 读取版本信息
const versionFilePath = path.join(__dirname, '../dist/version.json');
if (fs.existsSync(versionFilePath)) {
  const { version } = require(versionFilePath);
  console.log(`当前构建版本: ${version}`);
}

if (process.env.NODE_ENV === 'development') {
    console.log('in development.');
} else {
    console.log('in production.');
}

/* App Config */
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, '../dist')));


/* Server Initialization */
app.get('/', (req, res) => res.sendFile('index.html'));
var port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Server initialized on: http://localhost:${port} // ${new Date()}`));

内容的提问来源于stack exchange,提问作者Виктория

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 09:40:59