访问 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 节点之间共享数据

记录 Elastic Beanstalk 节点应用程序

Elastic BeanStalk 节点 Js/Angular 部署问题

Elastic Beanstalk 预部署 Laravel 节点错误