节点以编程方式设置了导入的模块不可用的过程环境变量

时间:2018-08-07 14:54:28

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

我是新来的,希望这个问题的格式和公式正确。迫不及待想看到您对这个问题的回答。让我们开始吧。

上下文

过去一个周末,我试图在我的es2015配置文件中实现create-react-app语法支持,这很简单。我要做的就是使用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" ]
}

脚本/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存储库以及一些给我带来麻烦的文件。

说明

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

我的设置

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

2 个答案:

答案 0 :(得分:2)

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 ]

答案 1 :(得分:0)

回答第二个问题

由于 @Mark Meyer 提供的见解,我得以将其投入使用。

脚本/start.js

'use strict'  

import '../config/devEnv';

config / devEnv.js

'use strict'  

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

现在还悬挂了环境变量设置器,使它们可用于所有导入的模块。