Does accessing NODE_ENV make sense in front end code?

大兔子大兔子 提交于 2020-02-27 22:31:18

问题


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?


回答1:


It's a good practice to use NODE_ENV variables for things like API URL.

If you used create-react-app, all environment variables starting with REACT_APP_ should already be accessible with process.env.REACT_APP_VARIABLE_NAME.
You can try REACT_APP_TEST=5 npm start then console.log(process.env.REACT_APP_TEST).

If you are not using create-react-app, you have to import them in your webpack config.

You can also choose to define the process.env variables for the app through a .env file using dotenv.




回答2:


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




回答3:


You could check NODE_ENV in index.html by using:

if ("%NODE_ENV%" === "production") {
  // ...do production stuff
} else {
  // ...do development stuff
}

When index.html is compiled in a production environment it will look something like this

if ("production" === "production") {
  // ...do production stuff
} else {
  // ...do development stuff
}



回答4:


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


来源:https://stackoverflow.com/questions/50244473/does-accessing-node-env-make-sense-in-front-end-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!