【问题标题】:node programmatically set process environment variables not available to imported modules节点以编程方式设置导入模块不可用的进程环境变量
【发布时间】:2019-01-14 17:17:40
【问题描述】:

我是新手,希望这个问题的格式和表述正确。迫不及待地想看看你对这个问题的回答。让我们开始吧..

上下文

上周末我试图在我的create-react-app 配置文件中实现es2015 语法支持,这很简单。我所要做的就是使用babel-registerbabel-preset-env 让它工作。到目前为止,你可以说这么好,但并不全是好的。经过几个小时的搜索,我发现process.env 变量没有传递给导入的模块。下面的代码将演示我的问题。

代码

package.json

{
  ...
  "scripts": [
    "good": "NODE_ENV=development BABEL_ENV=development node -r babel-register scripts/start.js",
    "bad": "node -r babel-register scripts/start.js"
  ],
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-preset-env": "^1.7.0",
    "babel-register": "^6.26.0"
  }
  ...
}

.babelrc

{
  "presets": [ "env" ]
}

scripts/start.js

'use strict'

process.env.NODE_ENV = 'development';
process.env.BABEL_ENV = 'development';

// Always works
const a = require('../src/a');
// Only when environment variables are passed in via the CLI
import b from '../src/b';

console.log('Bye bye..');  

src/a.js

'use strict'

console.log('Module A:', process.env.NODE_ENV);

const a = { name: "Module A" };
export default a;

src/b.js

'use strict'

console.log('Module B:', process.env.NODE_ENV);

const b = { name: "Module B" };
export default b;

运行代码

您将在下面看到两个npm 脚本的输出:

npm run good
# Outputs:
Module B: development
Module A: development
Bye bye..

npm run bad
# Outputs:
Module B: undefined
Module A: development
Bye bye..

我的问题

  1. 为什么不以编程方式设置环境变量传递给导入的模块?
  2. 可以在保持 es2015 语法的同时解决这个问题吗? (例如,使用 babel 插件?)

更多信息

只是将我的process.env.NODE_PATH 移至 CLI 是行不通的,create-react-app 以编程方式在其配置/脚本文件的多个位置设置环境变量。我在下面列出了一些链接,指向create-react-app repo 和一些给我带来麻烦的文件。

注意事项

根据我目前的理解,create-react-app 与我遇到的问题几乎没有关系。我对为什么以编程方式设置的环境变量不传递给导入的模块很感兴趣。

我的设置

  • 操作系统:Ubuntu 16.04
  • 节点:v8.11.2
  • Npm:6.3

【问题讨论】:

    标签: javascript node.js import ecmascript-6 environment-variables


    【解决方案1】:

    ES6 导入被提升。这意味着它们将在其余代码之前运行,无论它们在源代码中的什么位置。结果是b.js 将在您设置process.env.NODE_ENV = 'development' 之前运行。

    Babel 的输出将与此一致,并将通过将 b 的 require 语句移动到文件顶部来模拟提升的导入。 Babel 将创建一个 start 文件,如下所示:

    'use strict';
    
    var _b = require('../src/b');
    
    var _b2 = _interopRequireDefault(_b);
    
    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
    
    process.env.NODE_ENV = 'development';
    process.env.BABEL_ENV = 'development';
    
    // Always works
    var a = require('../src/a');
    // Only when environment variables are passed in via the CLI
    

    应该很清楚为什么这不起作用。

    [ 作为旁注,很多人强烈建议您不要在运行时设置NODE_ENV ]

    【讨论】:

    • 感谢您的回答 Mark Meyer,我已对您的答案投了赞成票,并将在今天晚些时候(或明天)将其标记为正确答案。是的,很清楚为什么我想要的不起作用。根据您的旁注;我是否在追逐独角兽试图让 ES6 和运行时环境变量同时工作?无论如何,非常感谢!
    • @sxkx,我真的不确定。我没有尝试过使用这样的 ES6 模块,也没有在运行时设置 NODE_ENV 的地方做任何事情。
    • 我找到了第二个问题的解决方案。这是一个相当简单的问题,请参阅我的解决方案。
    【解决方案2】:

    回答我的第二个问题

    感谢 @Mark Meyer 提供的见解,我得以让它发挥作用。

    scripts/start.js

    'use strict'  
    
    import '../config/devEnv';
    

    config/devEnv.js

    'use strict'  
    
    process.env.NODE_ENV = 'development';
    process.env.BABEL_ENV = 'development';
    

    现在环境变量设置器也被提升,使它们可用于所有导入的模块。

    【讨论】:

      猜你喜欢
      • 2012-09-14
      • 1970-01-01
      • 2012-10-16
      • 2018-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-08
      相关资源
      最近更新 更多