Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does accessing NODE_ENV make sense in front end code?

I have a react/node app that I'm deploying. One of the components attempts to access NODE_ENV in order to determine which host URL to use (localhost or heroku).

I now realize that even though NODE_ENV is being set to production, it's always 'undefined' in the browser context, because the environment is not node.

Since I can't access NODE_ENV from my react component, how do I dynamically set the host server?

like image 737
icey-t Avatar asked May 09 '18 01:05

icey-t


People also ask

What is the purpose of NODE_ENV?

NODE_ENV is an environment variable that stands for node environment in express server. The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production).

Does jest set NODE_ENV?

Jest automatically defines environment variable NODE_ENV as test (see https://jestjs.io/docs/environment-variables), as you can confirm from your error message: console.

How do you access the environment variable react?

There's only one gotcha, to access environment variables from the client app they must be prefixed with REACT_APP_ . Otherwise they will only be accessible on the server side. You can access environment variables (with the REACT_APP_ prefix) from your React app via the Node. js process.

Is process env a string?

The one notable difference with the process. env object, is that every key and value will always be a string.


2 Answers

I think you're misunderstanding the scope here. Node is a javascript runtime which runs as a server to handle backend stuff. NODE_ENV is a variable used in node to set up environment variables, thus, it is only accessible in the node environment, not in the client side.

Anyway in the first place, there is no reason why you would want to expose your config variables to your client side (that is a vulnerability issue). If it is related to some configs that relies on your server side variables, you have to set it in your client side independently. A use case I can imagine is defining a socket host and port to listen from the client side to the server side. Hope that clears things up :)

Imagine the life cycle:

  1. client requests
  2. node server processes and responds to request
  3. response is served through the browser
like image 193
Lelouch Avatar answered Sep 19 '22 13:09

Lelouch


One of the components attempts to access NODE_ENV in order to determine which host URL to use (localhost or heroku).

Yup, absolutely!

There's a difference here between having stuff around at build time, and at runtime. You'll have NODE_ENV around at buildtime - say you run webpack or something to build some JSX, or whatever.

You won't have NODE_ENV around at runtime, when the user visits your site. There's no concept of environmental variables in that web browsing context.

What I've done in this case is to programmatically create a file that will conditionally have the web server URL. Or even captures the NODE_ENV and puts the value in the application for later.

As a practical example: in a React project I was on a couple years ago we autogenerated our index.html file. This was a silly little file, bringing in our <script> Javascript tags we require and adding a <div> for the React app to render in. In the template language we did something like this:

index.html.templ

<html><body ENVIRONMENT="$NODE_ENV"></body></html>

after that file came out the other end of our build pipeline, it would look like this for our production build:

index.html

<html><body ENVIRONMENT="PRODUCTION"></body></html>

Then we just used normal DOM Javascript to grab the body element and check the attribute (then put it in a Redux store? I forget exactly).

At user visit time, we have an apparently hard-coded value of "production". But you and I know better!

Update: I forgot, there's actually two ways of doing this in Webpack itself, without using an external template tool and generating a file like I describe here!

  1. Use the WebPack define plugin. This will essentially add another step to your transpiling phase: one that goes in and replaces a literal string with some other literal string. So let e = "NODE_ENV" would become let e = "production". There's a good Medium blog post about defineplugin, and it's kind of cool.

  2. There's some environmental variable support in Webpack itself. Apparently if you run webpack with webpack --env.NODE_ENV=production. Then... maybe you can use process.env.NODE_ENV ? The Webpack documentation for this feature isn't exactly clear on this

like image 43
RyanWilcox Avatar answered Sep 20 '22 13:09

RyanWilcox