访问 Elastic Beanstalk 节点中定义的 process.env.PORT,由 Webpack 构建的捆绑包
Posted
技术标签:
【中文标题】访问 Elastic Beanstalk 节点中定义的 process.env.PORT,由 Webpack 构建的捆绑包【英文标题】:Accessing process.env.PORT defined in Elastic Beanstalk Node, bundle built by Webpack 【发布时间】:2018-10-22 09:53:47 【问题描述】:目前,我正在本地计算机上构建一个 REACT 应用程序,并将其生产构建部署到 Elastic Beanstalk。它是使用 Webpack 构建的。
在 index.js(服务器端)中,我使用 env 变量,例如:process.env.PORT(在 Elastic Beanstalk 中定义),当 Webpack 构建它时,这些被替换为包含本地 process.env 的 Objects() .
有没有办法阻止 Webpack 评估某些环境变量? 还是我做错了,我是否需要先在 Elastic Beanstalk 上构建生产包,然后再提供服务?
在最坏的情况下,我可以简单地将所需的值添加到 dotenv 文件并以这种方式处理它。不过,我希望能够使用 Elastic Beanstalks 环境变量。
提前致谢
更新: 为了在下面更好地解释,我试图在服务器端脚本的运行时访问 process.env 变量。然而,代码在部署到 AWS Elastic Beanstalk 之前构建在我的本地机器上
webpack.config.server
'use strict';
const util = require('util');
const path = require('path');
const webpack = require('webpack');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
// const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
const paths = require('./paths');
const nodeExternals = require('webpack-node-externals');
const getClientEnvironment = require('./env');
const merge = require('webpack-merge');
const base = require('./webpack.config.base');
const publicUrl = '';
// Get environment variables to inject into our app.
const env = getClientEnvironment(publicUrl);
const config =
target: 'node',
entry: paths.serverIndexJs,
externals: [nodeExternals()], // / in order to ignore all modules in node_modules folder
output:
path: paths.serverBuild,
filename: 'bundle.js',
publicPath: '/'
,
module:
rules: [
// "postcss" loader applies autoprefixer to our CSS.
// "css" loader resolves paths in CSS and adds assets as dependencies.
// "style" loader turns CSS into JS modules that inject <style> tags.
// In production, we use a plugin to extract that CSS to a file, but
// in development "style" loader enables hot editing of CSS.
test: /\.scss$/,
include: [ path.resolve(paths.scss, 'vendor') ], // Global styles
use: [
loader: "isomorphic-style-loader" // creates style nodes from JS strings
,
loader: "css-loader", // translates CSS into CommonJS
options:
importLoaders: 1,
sourceMap: true
,
loader: "postcss-loader",
options:
sourceMap: true
,
loader: "sass-loader", // compiles Sass to CSS
options:
sourceMap: true
]
,
test: /\.scss$/,
exclude: [ path.resolve(paths.scss, 'vendor'), path.resolve(__dirname, '../node_modules') ], // Module styles
use: [
loader: "isomorphic-style-loader" // creates style nodes from JS strings
,
loader: "css-loader", // translates CSS into CommonJS
options:
importLoaders: 1,
sourceMap: true,
modules: true,
localIdentName: '[path]___[name]__[local]___[hash:base64:5]'
,
loader: "postcss-loader",
options:
sourceMap: true
,
loader: "sass-loader", // compiles Sass to CSS
options:
sourceMap: true
,
loader: "sass-resources-loader",
options:
resources: [
path.resolve(__dirname, '../node_modules/bootstrap/scss/_functions.scss'),
path.resolve(__dirname, '../src/scss/config/**/*.scss'),
path.resolve(__dirname, '../node_modules/bootstrap/scss/mixins/**/*.scss'),
path.resolve(__dirname, '../src/scss/helpers/**/*.scss'),
]
]
,
]
,
plugins: [
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'development') ... . See `./env.js`.
new webpack.DefinePlugin(env.stringified),
],
node:
console: false,
global: false,
process: false,
Buffer: false,
__filename: false,
__dirname: false,
setImmediate: false,
;
module.exports = merge(base, config);
【问题讨论】:
getClientEnvironment 做什么?它的输出是什么? 【参考方案1】:不是 100% 清楚您要做什么,但听起来您只想将一些环境变量传递给 DefinePlugin
,而不是全部...?如果是这种情况,您可以只写一点 fn 来过滤或将环境变量列入白名单,然后将结果传递给 DefinePlugin
。如果你的 DefinePlugin
中没有包含一个 env var,webpack 将在构建时不知道它。
【讨论】:
感谢 Brandan,我认为这有点让我走上正轨。问题是在 AWS Elastic Beanstalk 中,我正在定义键值对,例如 PORT。 Elastic Beanstalk 将这些作为环境变量公开给节点应用程序 - process.env.PORT。由于应用程序是在部署到 AWS 之前在我的本地计算机上构建的,因此这些环境变量不可用。我希望 process.env.PORT 在运行时可用,而不是在构建期间被 Webpack 替换为“未定义”。再次感谢【参考方案2】:来自 env.js 的 getClientEnvironment 返回一个键值对象,然后将其传递给 DefinePlugin。
尽管诸如 process.env.PORT 之类的环境变量没有被传递给 DefinePlugin,但它们被 Webpack 编译为未定义。
这是由于 getClientEnviroment 将环境变量作为 process.env 的对象返回
'process.env':
NODE_ENV: '"production"',
PUBLIC_URL: '""',
REACT_APP_HOST: '"localhost"',
REACT_APP_PORT: '"8080"'
我没有意识到,在这样做时,DefinePlugin 会覆盖所有 process.env 变量。
根据 definePlugin 的文档:
为进程定义值时首选“process.env.NODE_ENV”: JSON.stringify('production') over process: env: NODE_ENV: JSON.stringify('production') 。使用后者将覆盖 进程对象可能会破坏与某些模块的兼容性 期望在流程对象上定义其他值。
【讨论】:
以上是关于访问 Elastic Beanstalk 节点中定义的 process.env.PORT,由 Webpack 构建的捆绑包的主要内容,如果未能解决你的问题,请参考以下文章
AWS EC2 / Elastic Beanstalk |如何按域列入白名单?
在 AWS Elastic Beanstalk 上运行节点和反应
在 Amazon Elastic Beanstalk 节点之间共享数据