Reputation: 328
I am using PKG, to make a executable .exe file for my Appolo GraphQL Server + React client bundled all into one exe file. It's working, and now there is requirement: app should read from somewhere an IP address and use it as constants for host, port, etc.
From server side I am using fs.readFileSync
- which is okay. I can read any text file as it's nodejs server side. And now the requirement is to pass that IP to the client files -> into the static folder (marked *), where I have constant.js with IP of client to connect inside (compiled static/js..). Server side files (NodeJs+React):
├───build
│ └───static
│ ├───css
│ ├───*js*
│ └───media
├───config
├───src
│ ├───core
│ ├───graphql
│ ├───guardServer
│ └───pg
└───SSL
Client React files tree:
├───.idea
├───.vs
│ └───React
│ └───v16
├───build
│ └───static
│ ├───css
│ ├───js
│ └───media
├───public
└───src
├───components
│ ├───core
│ │ ├───functions
│ │ └───modal
│ └───modules
│ ├───account
│ ├───adminPanel
│ │ └───pages
│ ├───archive
│ ├───hr-department
│ │ └───pages
│ ├───logs
│ ├───monitor
│ └───reports
├───config
└───images
So my actions are: npm run build
a clent. Then I taking the folder build and replacing a server side files: server/build folder. Then I'm doing on the server side - npm run build
and receiving an exe file. WHERE a server part (/server/index.js) of this exe can read a settings.txt, but not that part (client) which is inside /server/build/static/js...
My question is: is it possible by modifying webpacker somehow, and server environment variable will be accessible (and will be dynamic) from client side with command process.env.myvar
?
If not, if there are any tricks I can utilize in this case? Please note that PKG's fs.writeFileSync
is now allowed due to the filesystem shapshot restriction.
Code of server side:
let fileContent = fs.readFileSync("D:\\settings.txt", "utf8");
let getIp=JSON.parse(fileContent); //fine working, got IP
Client using Apollo Client and exactly for him I need to pass that IP from server side, any ideas please?
Update for Ajeet Shah. What I did:
On my server.js - var __SERVER_DATA__ = "192.168.0.111";
in index.html of client - <script>
window.SERVER_DATA = __SERVER_DATA__;
</script>
in index.js of client - console.log(window.SERVER_DATA);
Update:
I think I will end up for a while with the tiny http server, which will run on localhost:port. And from there I can freely read any settings. Thank you All for usefull answers.
I've chosen the answer with more options and there was advise about localStorage. Thank you all much for heads up. Still trying to implement offered methods.
Update.
I've finishied doing this. I've used an html variable window.SERVER_DATA = __SERVER_DATA__
as described here - https://create-react-app.dev/docs/title-and-meta-tags/#injecting-data-from-the-server-into-the-page. I will decide later on what to do with best answer, if nobody will post extra ones.
Upvotes: 2
Views: 3391
Reputation: 16524
In backend technologies, everything is solved with environment variables which is a good practice when you have to move your app through stages( dev, staging, prod).
In client side technologies( react, vue, angular or simple js) the obtainment of these values dynamically is complicated.
Check this answer to understand how variables work in js client side or how to inject dynamic values
https://stackoverflow.com/a/54271114/3957754
One strategy is use the REACT_APP variables
https://create-react-app.dev/docs/adding-custom-environment-variables/
So if you create this variable in your server side
export REACT_APP_remote_ip
React library will create a variable for you. You can use thia var in any react file
process.env.remote_ip
Similar to REACT_APP webpack offer an option to expose server side variables as global javascript variables ready to use in any .js file
new webpack.DefinePlugin({
API_BASE_URL: JSON.stringify(process.env.API_BASE_URL)
})
Another option is to create an endpoint in your nodejs server side. This endpoint has access to the environment values, so you can return anything you want:
res.json({
"ip1": process.env.remote_ip_1
});
After this, you just need to call or invoke this endpoint /settings in the most early js or entrypoint of your react or javascript files.
Finally, the return of /settings could be exposed as global javascript values or stored in localstore of browser
Upvotes: 1
Reputation: 19823
As described in docs, you can create server side variables that can be injected in your front end code.
Here is what you need to do:
myConfig.js
, and place it on the server at a public location so that frontend can load it.const myConfig1 = "foo bar"
const myConfig2 = "anythng else"
<head>
section of index.html
file in your frontend app. It will read load/data from the server and set those in global window
object.<script src="http://path/to/file/on/server/myConfig.js" type="text/javascript"></script>
<script>
window.myConfig1 = myConfig1
window.myConfig2 = myConfig2
</script>
window
object as window['myConfig1']
and window['myConfig2']
.Using this method, you don't need to rebuild the frontend app using npm run build
when you change your config vars as these are defined, separately from frontend, on the server. To change these config vars, you just need to change those on the server and do a refresh in browser.
Upvotes: 1