I'm new, hopefully this question is properly formatted and formulated. Can't wait to see your answers on this question. Let's get to it..
Past weekend I was trying to implement es2015
syntax support in my create-react-app
configuration files, which was straight forward. All I had to do was use babel-register
and babel-preset-env
to get it working. So far so good you could say, however it wasn't all good. After some hours of searching I found that process.env
variables are not passed through to imported modules. The code below will demonstrate my issue.
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;
Below you will see the output of both npm
scripts:
npm run good
# Outputs:
Module B: development
Module A: development
Bye bye..
npm run bad
# Outputs:
Module B: undefined
Module A: development
Bye bye..
Just moving my process.env.NODE_PATH
over to the CLI won't work, create-react-app
programmatically sets environment variables at multiple places in their configuration/script files. I have listed a few links below, pointing to the create-react-app
repo and some of the files that are giving me troubles.
create-react-app
repo.process.env.NODE_ENV
and process.env.BABEL_ENV
.process.env.NODE_PATH
. From my current understanding, create-react-app
has little to none to do with the problem I'm having. I'm interested in why programmatically set environment variables are not passed through to imported modules.
ES6 imports are hoisted. This means they will run before the rest of the code regardless of where they are in the source. The result is that b.js
will run before you have set process.env.NODE_ENV = 'development'
.
Babel's output will be consistent with this and will simulate hoisted imports by moving b
's require statement to the top of the file. Babel will create a start
file that looks like:
'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
It should be clear looking at that why this isn't working.
[ As a side note, many people strongly recommend that you don't set NODE_ENV
at runtime ]
Thanks to the insights provided by @Mark Meyer I was able to get it to work.
scripts/start.js
'use strict'
import '../config/devEnv';
config/devEnv.js
'use strict'
process.env.NODE_ENV = 'development';
process.env.BABEL_ENV = 'development';
Now the environment variable setters are hoisted as well, making them available to all imported modules.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With