Parcel: Destructuring doesn't work with process.env

Created on 24 Oct 2018  ยท  8Comments  ยท  Source: parcel-bundler/parcel

๐Ÿ› bug report

Destructuring doesn't work with process.env.

๐ŸŽ› Configuration (.babelrc, package.json, cli command)

{
    "presets": ["@babel/preset-env"]
}

๐Ÿค” Expected Behavior

const {PWD, NODE_ENV} = process.env;
console.log(PWD, NODE_ENV);

The console should print the variables, something like /home/user/parcel development.

๐Ÿ˜ฏ Current Behavior

The console prints undefined undefined.

๐Ÿ’ Possible Solution

๐Ÿ”ฆ Context

I am trying to follow ESLint's no-process-env rule. I want to have only one place (one line) in my codebase where I read variables from process.env, so I have a config.js file with the following code:

//eslint-disable-next-line no-process-env
const {API_URL, NODE_ENV} = process.env;

export {
    API_URL,
    NODE_ENV
};

๐Ÿ’ป Code Sample

const {PWD, NODE_ENV} = process.env;
console.log(PWD, NODE_ENV);

๐ŸŒ Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | v1.10.3
| Node | v11.0.0
| npm/Yarn | npm 6.4.1
| Operating System | Ubuntu 18.04

Bug Confirmed Bug Help Wanted โœจ Parcel 2

Most helpful comment

Currently, this

const {PWD, NODE_ENV} = process.env;

const {FILE} = process.env;

is processed by babel into:

var _process$env = process.env,
    PWD = _process$env.PWD,
    NODE_ENV = _process$env.NODE_ENV;
var FILE = process.env.FILE;

But Parcel's env visitor (https://github.com/parcel-bundler/parcel/blob/master/packages/core/parcel-bundler/src/visitors/env.js) only looks out for process.env and looks up the key that follows:
https://github.com/parcel-bundler/parcel/blob/6566e160affa161daa6d5486139e6059f685ba3a/packages/core/parcel-bundler/src/visitors/env.js#L6

Lookup hack:

--- a/packages/core/parcel-bundler/src/visitors/env.js
+++ b/packages/core/parcel-bundler/src/visitors/env.js
@@ -3,7 +3,8 @@ const types = require('@babel/types');
 module.exports = {
   MemberExpression(node, asset) {
     // Inline environment variables accessed on process.env
-    if (types.matchesPattern(node.object, 'process.env')) {
+    if (types.matchesPattern(node.object, 'process.env') || node.object.name == "_process$env") {
       let key = types.toComputedKey(node);
       if (types.isStringLiteral(key)) {
         let prop = process.env[key.value];

Remaining issue: removing the _process$env variable and also determining the name of _process$env at runtime (it could be different in some cases).

var _process$env = process.env,
    PWD = ".....",
    NODE_ENV = "....";
var FILE = "....";

All 8 comments

@EvgenyOrekhov this also doesn't work in most of webpack config. Because they use DefinePlugin.

Dont't use destructuring in process.env in most of time.

@xiaoxiangmoe "Don't use it" is not a solution. The bug should be fixed.

Cross referencing the same bug report for webpack: https://github.com/webpack/webpack/issues/5392.

Seems to be working just fine

.env.development

NAME=John

index.js

const { NAME } = process.env;

`Hello ${NAME}` // -> Hello John

@mytee306 It does indeed, but only if you extract exactly one property. Strange.

@EvgenyOrekhov indeed, haven't tried extracting more than one prop, seems like an interesting problem to solve

Currently, this

const {PWD, NODE_ENV} = process.env;

const {FILE} = process.env;

is processed by babel into:

var _process$env = process.env,
    PWD = _process$env.PWD,
    NODE_ENV = _process$env.NODE_ENV;
var FILE = process.env.FILE;

But Parcel's env visitor (https://github.com/parcel-bundler/parcel/blob/master/packages/core/parcel-bundler/src/visitors/env.js) only looks out for process.env and looks up the key that follows:
https://github.com/parcel-bundler/parcel/blob/6566e160affa161daa6d5486139e6059f685ba3a/packages/core/parcel-bundler/src/visitors/env.js#L6

Lookup hack:

--- a/packages/core/parcel-bundler/src/visitors/env.js
+++ b/packages/core/parcel-bundler/src/visitors/env.js
@@ -3,7 +3,8 @@ const types = require('@babel/types');
 module.exports = {
   MemberExpression(node, asset) {
     // Inline environment variables accessed on process.env
-    if (types.matchesPattern(node.object, 'process.env')) {
+    if (types.matchesPattern(node.object, 'process.env') || node.object.name == "_process$env") {
       let key = types.toComputedKey(node);
       if (types.isStringLiteral(key)) {
         let prop = process.env[key.value];

Remaining issue: removing the _process$env variable and also determining the name of _process$env at runtime (it could be different in some cases).

var _process$env = process.env,
    PWD = ".....",
    NODE_ENV = "....";
var FILE = "....";

Having the same problem here. Had get them one by one....

Was this page helpful?
0 / 5 - 0 ratings

Related issues

algebraic-brain picture algebraic-brain  ยท  3Comments

davidnagli picture davidnagli  ยท  3Comments

Niggler picture Niggler  ยท  3Comments

466023746 picture 466023746  ยท  3Comments

termhn picture termhn  ยท  3Comments