如何将Node进程变量传入Webpack构建包?IISNode部署遇端口问题
process.env.PORT被替换为undefined的问题 这个问题我之前帮不少开发者排查过——核心原因是Webpack默认会在构建阶段静态分析并替换process.env相关变量,而不是把这个表达式留到运行时让Node进程去读取。你本地构建时没有设置PORT环境变量,Webpack就把process.env.PORT直接替换成了undefined,导致部署到IIS后,iisnode传入的端口根本没机会被读取。
下面是几个可靠的解决方案,按推荐程度排序:
1. 修改Webpack配置,保留process.env的运行时读取
最直接的方法是告诉Webpack不要静态替换process.env.PORT,让它在应用运行时再去读取Node进程的环境变量。
针对Webpack 5+
在你的webpack.config.js中添加以下配置:
module.exports = { // ...其他配置 node: { global: true, __filename: false, __dirname: false, }, resolve: { fallback: { process: require.resolve('process/browser'), }, }, };
同时需要安装process包:
npm install process --save-dev
针对Webpack 4及以下
直接在配置中禁用Webpack对process变量的模拟:
module.exports = { // ...其他配置 node: { process: false, }, };
这样配置后,Webpack会保留代码中的process.env.PORT表达式,部署到IIS后,iisnode传入的端口就能被正常读取了。
2. 使用DefinePlugin显式保留运行时表达式
如果你已经在使用Webpack的DefinePlugin(比如处理其他环境变量),可以专门为process.env.PORT设置一个特殊值,让Webpack不替换成静态值:
// webpack.config.js const webpack = require('webpack'); module.exports = { // ...其他配置 plugins: [ new webpack.DefinePlugin({ // 注意:不要用JSON.stringify,直接写表达式 'process.env.PORT': 'process.env.PORT' }) ] };
这个配置会让Webpack把代码中的process.env.PORT替换成process.env.PORT本身,相当于保留了原表达式,运行时就能正确读取IIS传入的端口了。
3. 延迟端口读取(临时 workaround)
如果暂时不想改Webpack配置,可以修改你的server.js代码,通过函数调用延迟端口的读取,让Webpack无法静态分析替换:
// server.js // 用一个函数包裹,避免Webpack静态替换 const getServerPort = () => { return process.env.PORT; }; app.listen(getServerPort());
这个方法虽然能生效,但不如前两种方案可靠,适合临时测试用。
额外注意事项
- 确保服务器上的
web.config配置正确,iisnode会自动把端口注入到process.env.PORT中,你不需要额外配置,但要确认web.config里的iisnode节点没有禁用环境变量传递。 - 本地开发时,可以通过设置环境变量来测试,比如在终端运行
PORT=3000 node server.js,这样本地也能模拟IIS的端口传递逻辑。
内容的提问来源于stack exchange,提问作者Adrian Gren

