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



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

上下文

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

代码

包.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" ]
}

脚本/开始.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存储库的链接。
  • scripts/start.js此脚本同时设置process.env.NODE_ENVprocess.env.BABEL_ENV
  • config/env.js此配置文件设置process.env.NODE_PATH

注释

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

我的设置

  • 操作系统: 乌班图 16.04
  • 节点:v8.11.2
  • 每分钟:6.3

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提供的见解,我才能让它发挥作用。

脚本/开始.js

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

config/devEnv.js

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

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

最新更新