I store the API base address in my environment class, and it gets reflected into
the bundles after build. What i need is a way to somehow liberate this
value from the build process so in case i wanna deploy the app under different
servers with different API addresses, I won't have to do another build only for the sake of a new URL.
My app is quite hefty and the build is really time-consuming.
Here is what is have in my environment.prod.ts :
export const environment = {
production: true,
configName: 'prod',
baseUrl: 'https://mpisitweb1/api'
};
I would try creating an environment.json that sits under your assets folder and make it publicly available. When your application is starting I'd do a request (On the same URL your serving from) to download that file which would contain the API baseUrl.
You'd have to store the value in Angular somewhere different though as you can't override the environment variable, might be best off putting it in a service somewhere that can be injected into the http Interceptor that way you can just specify "{BASE_URL}" as your base point and have the interceptor change it out to what's needed so the rest of your app isn't aware.
Related
I need to compute and cache new data at build time that is required by both the frontend and backend API routes. Is there any way to read the static properties generated at build time by API routes? The API routes are publicly accessible, so I can't just pass the data from the frontend.
All build artifacts are saved in .next folder, that's outside application source, therefore your code won't be able to access it.
If data you're getting in getStaticProps is time consuming to compute, I'd save it in some cache and then read from this cache in your API routes.
UPDATE:
I lied, I played around and it's actually possible to access cached page data, but there are some caveats.
Build artifacts for given page are saved in .next/server/pages/. Exported static props are stored in a JSON file, that matches page path. E.g. static props for /contact live in .next/server/pages/contact.json.
Those files are deleted when you do yarn build, therefore you can't simply import them with
import data from '../../.next/server/pages/contact.json'
in your code, as that will break the build because of your attempt to import nonexistent file.
What you could do, is loading this file this way:
const cacheDirectory = path.join(process.cwd(), '.next/server/pages/');
const fileContents = await fs.readFile(cacheDirectory + '/contact.json', 'utf8');
This will build just fine and work when you do yarn start. But... it won't work when you do yarn dev, because this command clears the build folder. To work around that, you could check for NODE_ENV value and run this logic in production mode only and use some mock data in this scenario.
I build a web app using react, webpack, docker and AWS.
I create a feature which depends on environment variable. So if the environment variable value is true, the feature will be showing on the frontend.
The problem is, when I changed the environment variable on the server (Webpack already done building the app, the app is already deployed and running), my feature is not showing. I guess due to the app cannot read the value changes on system environment variable.
How can I achieve this ? is it possible to do it ?
=====
I use dotenv webpack for managing my environment variables. I already set the systemvars to true to detect all environment variables from the system or .env file.
=====
So why am I doing this, because I dont want to make a Pull Request to push a new value for environment variables. I just want to reserve the environment variables name, and change the value directly from the server if the feature is ready to deployed. And if there is an error, I just need to change the environment variable to something and the feature is down.
You simply cant change environment variable. Evn variables loaded on compile/webpack load time. So once app start u cant change, process.env.
Solution as #jonrsharpe explains. You need to create, some sort of database. It could be memory or file or database. You read data from that. Expose a API, to update the data base.
Express sample:
global.enableFeature = false
app.post("/updateFeatureToggle", (req, res) => {
const enableFeature = req.body.enableFeature
global.enableFeature = enableFeature
res.send({success: "OK"})
})
In another file, read from global.enableFeature. This is in memory-based.
I have a react component which in development will redirect to a localhost url but in production to a different url. In my backend I have the same situation and there i solved it with a package called dotenv. I was wondering how someone would do this in a react front-end.
export default withRouter(function Login(props) {
useEffect(() => {
if(localStorage.getItem('jwt')){
props.history.push('/dashboard');
}
})
const handleLogin = () => {
window.location.href = "http://localhost:8000/auth/google";
}
return (
<LoginView handleLogin={handleLogin}/>
)
})
You can use dotenv to add environment variables to react as well. During app deployment(in the build process) the environment variables must be replaced with the corresponding URLs (as this is the most frequently encountered use case in front-end applications). This can be done while configuring the build process.
Here is an example using Webpack https://medium.com/#trekinbami/using-environment-variables-in-react-6b0a99d83cf5
The whole idea here is to create a file (called just .env) filled with
your environment variables. To prevent people from finding out your
local database password is the same one you use for every single one
of your accounts on the internet , I urge you to add the .env file to
your .gitignore. Your front-end code will refer to the same
environment variable (process.env.API_URL) on both environments
(development/production), but because you defined different values in
your .env files, the compiled values will be different.
I would suggest having a separate .env file for the react app as it should not be accidentally served with the website.
Create React App has a module(built around the node dotenv module) you can use for adding custom environment variables
https://create-react-app.dev/docs/adding-custom-environment-variables/
The environment variables are embedded during the build time. Since
Create React App produces a static HTML/CSS/JS bundle, it can’t
possibly read them at runtime. To read them at runtime, you would need
to load HTML into memory on the server and replace placeholders in
runtime, as described here. Alternatively you can rebuild the app on
the server anytime you change them.
Its depend on how you are using react.
If you are using react-script, you can go will above solution(https://create-react-app.dev/docs/adding-custom-environment-variables/).
But if you are using webpack, try to use DotenvPlugin in place of dotenv module (https://webpack.js.org/plugins/environment-plugin/).
In my opinion, pls don't follow method 1 use in medium link, as env should not be push on git but package.json need to be done.
i am creating react application using create-react-app,i am using node js as a backend development.
i can run it successfully in the local environment,but while having same application in the production build application doesn't set the "apiURL"
my backend url is=http://localhost:5001/
API_URL = process.env.REACT_APP_API_URL
actually i need to get my API_URL = http://localhost:5001
but i am getting API_URL is undefined in the production deploy
and on request of some backend api i am getting
http://localhost:3000/undefined/api/someapi
but actually i need to get the
http://localhost:5001/undefined/api/someapi
can any one help how can configure my environment variable dynamically depends on the host environment
sorry for my bad english
thanks in advance
You need to set different values of your variables depending on your environment. There're multiple possibilities, you can for example do it on script level in your package.json:
"scripts": {
"deploy:staging": "REACT_APP_API_URL=<paste-your-api-for-staging> ...",
"deploy:production": "REACT_APP_API_URL=<paste-your-api-for-production> ...",
}
Or you can use my personal favorite -> https://github.com/motdotla/dotenv for managing your env variables. It's based on different .env files for eg. .env.local or .env.production where you can set your values.
I am currently making a Meteor app and am having trouble reading files from the private subdirectory. I have been following a couple different tutorials and managed to get it to work flawlessly when I run the meteor app locally. This question (Find absolute base path of the project directory) helped me come up with using process.env.PWD to access the root directory, and from there I use .join() to access the private folder and the pertinent file inside. However, when I deployed this code, the website crashes on startup. I am very confident that it is an issue with process.env.PWD, so I am wondering what the proper method of getting Meteor's root directory on a deployed app is.
//code to run on server at startup
var path = Npm.require('path')
//I also tried using the below line (which was recommended in another Stackoverflow question) to no avail
//var meteor_root = Npm.require('fs').realpathSync( process.cwd() + '/../' );
var apnagent = Meteor.require("apnagent"),
agent = new apnagent.Agent();
agent.set('cert file', path.join(process.env.PWD, "private", "certificate-file.pem"))
agent.set('key file', path.join(process.env.PWD, "private", "devkey-file.pem"))
In development mode the file structure is different than after bundling, so you should never rely on it. Particularly, you should not access your files directly like you're doing with path methods.
Loading private assets is described in this section of Meteor's documentation. It mostly boils down to this method:
Assets.getBinary("certificate-file.pem");
and it's getText counterpart.
As for configuring APN agent, see this section of documentation. You don't have to configure the agent by passing file path as cert file param. Instead you may pass the raw data returned by Assets methods directly as cert. The same holds for key file ~ key pair and other settings.
As an alternative, you would need to submit your files independently to the production server to a different folder than your Meteor app and use their global path. This, however, would not be possible for cloud providers like Heroku, so it's better to use assets in the intended way.