I would like to have a way to toggle between production and dev endpoints within from the phone settings. I am worried that this will mess up the cash and might display incorrect data. what's the best way to do it, please?
I was wondering the same thing!
In your code, you can use the __DEV__ global flag to differentiate between Dev and Production "mode".
Expo's Production switch is not a reliable way to handle environment switches (production and dev endpoints in your case). Why? 2 main reasons:
Production mode always minifies your code and better represents the performance your app will have on end-user's devices.
Development mode includes useful warnings and gives you access to debugging tools.
What if you want to have the flexibility to run the app against the Production endpoints you have, but still being able to access the debugging tools? You can't.
Here's my approach: I handle environment switches with .env files.
With Expo, I got my .env to work with the following:
Added babel-plugin-inline-dotenv to devDependencies:
npm install --save-dev babel-plugin-inline-dotenv
Added inline-dotenv to .babelrc:
{
"plugins": ["inline-dotenv"]
}
Added a .env file:
ENDPOINT="https://development"
Kudos for the .env set-up instructions goes to jdrydn.
Finally, use the environment variable in your code:
<Text>{process.env.ENDPOINT}</Text>
Plus, I have one more file .env-production (technically, I have also .env-staging in case you're wondering):
ENDPOINT="https://production"
The real caveat is when you want to run your app against the Production environment. You need to:
Copy .env-production content to the .env file.
Restart Expo's Metro Bundler and clear its cache (must be always restarted between .env changes). Do that either by running expo r -c or by pressing shift-r in your terminal to restart and clear cache while the Metro Bundler is running.
That's the most optimal approach I've been able to find.
PS: If you want to toggle between Dev and Production endpoints within you app - I'd simply use a js file with exported variables for each environment.
Related
Is there a way to create a deployment of my Nextjs app to production but without promoting it immediately to prod? Similar to a preview URL, but without public traffic being routed to that URL.
My use case is that I want to deploy a "pre-prod" app, run E2E tests there, and if they are successful, promote the app to production.
Is this flow possible?
I've used vercel --prod, but that just deploys the current version to production.
I want to create a production build that allows me to then use the alias command to point the traffic to a specific version.
Thanks in advance!
In this case, my opinion, you need to create an "intermediate" solution.
In vercel, you have "dev" "preview" and "production" environments (go to Settings-environment variables). You set some settings to preview env, it's ok for you, you can after "promote to production" your preview version.
Also, you can set up a special branch in git to directly deployment on preview
I'm familiar with gulp and the ability to have a distinct configuration for each environment within a single configuration file. That way running gulp dev would allow you to start your server with the configuration of your dev environment, gulp staging for your staging and gulp prod fro production.
I'm now looking at restify and am trying to determine if something similar can be done with it. I've tried researching this online and haven't found anything meaningful. Is this possible and if so could somebody provide an example?
You can use dotenv package to load different configuration file. For example
.env.dev For Development environment
.env.prod for Production environment
.env.test for Testing environment
you can import file according to NODE_ENV var
or you can simply add all configuration variable in one file for example
.conf.env and import it.
I'm learning to use webpack-encore and noticed it is installed only as a dev dependency. Does that mean I should compile my js and css files on development and push them to the repository, and then to production?
That seems to me what the docs are implying, but wouldn't that mean a merge-conflict hell? Compiled files would be impossible to merge.
Also wouldn't that be contrary to version control philosophy? As far as I know, you don't publish binaries in compiled languages (i.e. C/C++), you push the code and expect the server to compile them. I know this isn't the same type of "compilation" in javascript, but what is the expected behavior of the production server in this case? To receive the files ready to serve them, or to compile them at the time of release?
Thanks in advance
Does that mean I should compile my js and css files on development and push them to the repository, and then to production?
Not exactly - it depends on how you deploy.
When you deploy, you need to run ./node_modules/.bin/encore production to build your assets. Once you've done this, only your built assets (e.g. web/build) need to be transferred to production.
You could run this command locally (or on some "build" server) and the transfer all the files to production. Or, you could use a git pull on production, and then run this command on production (the downside being that you would need Node.js installed on production).
You shouldn't / don't need to commit your built files to your repository. But... if it simplifies your deploy (i.e. you want to do a git pull and be done), there's no real problem with that.
I just added a PR to answer these in the FAQ (http://symfony.com/doc/current/frontend/encore/faq.html) - here's the PR until it's deployed: https://github.com/symfony/symfony-docs/pull/8109
Cheers!
Solution 1:
Run yarn run encore production locally
Check out which files have been created / modified
Add them to VCS
Commit
Push / deploy
Solution 2:
Push / deploy
Run yarn run encore production remotely during deployment
To my eyes the 2nd solution is way better, because you don't need an extra human-checking before deployment, everything is automated.
But this has a strong drawback: building assets can be a slow process, and when I deploy, my production is down during 5 to 20 seconds until assets are built.
Here's the HTTP 500 error:
An exception has been thrown during the rendering of a template ("Asset manifest file "[...]/web/build/manifest.json" does not exist.").
It looks like the manifest.json file is deleted at the beginning of the process, and created from scratch later on.
Something that should be improved?
I work on many projects that run on Express servers, whether they are front-end (i.e. React.js) codebases or server-side Node.js codebases.
Many times with the front-end codebases I would load conditional configuration based on NODE_ENV, such as the URL of the restful API that the front-end makes requests to.
I many times also used NODE_ENV to conditionally load things like DB configuration for server-side Node.js projects.
On a project that consisted of development, staging, and production (3 environments), I would usually set up my code to load configuration based on the NODE_ENV being set to any one of those 3 environments (and maybe also "local").
I was recently working on a project that was referring to the production environment as "live."
When I decided to set the NODE_ENV=live for this environment, a coworker pointed out a major flaw with this approach.
It seems that Express and some other libraries for Node.js latch onto the fact that you will either be using "production" or "development" as your NODE_ENV and using other names for your environments can have unexpected effects.
For example, Express needs NODE_ENV=production in order to run in "production" mode. According to the Express docs "Tests indicate that just doing this can improve app performance by a factor of three!"
Basically, I'm curious if it is considered common practice to set the NODE_ENV to values other than "development" and "production," like I've been doing in my projects.
I feel that if I'm going to deploy my code to the development or staging environments on the cloud, I don't think they should run in a different Express "mode" than the production environment.
Does it make more sense to maintain configurations separate from NODE_ENV?
For example, does it make sense to base your configuration off of a variable like APP_ENV, while ensuring that NODE_ENV is either "development" or "production" for frameworks/packages like Express.
NODE_ENV should be set to either development or production in traditional sense.
The reason being, when you're building a front-end application (React, etc), you either build the application in development mode or production mode. For example, in development mode, you will watch for changes and build continuously. In production mode, you minify the code and optimize it for size.
In case of a node server, the NODE_ENV refers to what mode you start your application with. For example, in development mode, you configure your server and install all devDependencies and watch for changes and live reload the server. And in production mode, you only install dependencies and start the server with optimized configuration.
Now talking about different production environments, say staging, pre-live, live, etc, you should use a separate ENV variable for this. Except local, all other environments are considered production environments and your app should be built with and start in production mode in these environments.
You usually load different configurations, say api keys, urls for each environment. These should be differentiated with a separate ENV variable like APP_ENV.
I usually use APP_ENV to differentiate between staging and live environments.
This is how the package.json will look like with different start scripts for different environments
"scripts": {
"start:local": "NODE_ENV=development APP_ENV=local your-start-script",
"start:staging": "NODE_ENV=production APP_ENV=staging your-start-script",
"start:live": "NODE_ENV=production APP_ENV=live your-start-script",
}
You will need to start the app with the right start script in each environment.
NODE_ENV is used to differentiate between development and production instances. It is not a good idea to run production code without NODE_ENV=production. NODE_ENV=development is usually not that important, because libraries usually just check to see if NODE_ENV !== 'production'. So if you want to have multiple production node environments, or production-like environments, each of them should set NODE_ENV=production. That said, you can definitely set other environment variables to whatever values you desire, and read them back from node at runtime.
A reasonable example would be to have a local staging and production versions of your configuration. In this case, I would recommend having NODE_ENV be just one of the parameters you set up for each environment. For instance, you might want three different databases for each of local, staging and production but set NODE_ENV to development on local, and production for both staging and production.
Since the variables will be shell variables, you will need a way of loading certain environment variables on the target operating system prior to running the server. Modules like https://www.npmjs.com/package/dotenv look promising for this purpose.
You can use NODE_ENV for multiple environments when your install the custom-env module:
npm install custom-env
Full docs here: https://www.npmjs.com/package/custom-env
I have recently started to evaluate webpack. Having used grunt previously I am used to the fact that I can start grunt with various parameters to configure what is going to happen during the build. For example:
grunt watch
would run a debug build and enable the watch task. While:
grunt build
would trigger a fully minimized production build that has all development specific functionality disabled.
I am wondering if webpack has a similar feature that lets me easily switch between different configurations. I have done some research already but I did not like the approaches I have seen so far:
I saw a suggestion to specify NODE_ENV=production before calling webpack, but this is not platform independend (e.g. does not work on windows).
Using the -p switch, but that seems to only affect minimization
Using a separate config file for webpack, but I would prefer a solution where I do not have to maintain two separate files.
I understand that webpack is not actually a task runner such as grunt or gulp, but rather a module bundler. But its being promoted as a replacement for grunt or gulp see this Medium.com Blog.
What I would really like to see is the ability to get a development build with something like webpack watch and a production build with webpack or webpack build is that possible with webpack
First of all, if you use webpack-dev-server it is quite easy to understand you are in dev mode:
let isDevMode = process.argv[1].endsWith('webpack-dev-server') || process.argv[1].endsWith('webpack-dev-server.js');
First condition is for Linux / mac, the second is for Windows.
and then use this to configure your files.
If you are not using dev server you can pass any parameter while running the webpack as you would do with any nodejs script (I use minimist to read the parameters but it is just a sugar, don't use if you don't need to):
let argv = require('minimist')(process.argv.slice(2));
let isDevMode = argv.dev; // or watch or whatever you want to pass
and then call it that way:
webpack --dev
This is actually a very flexible way of doing lots of things, not only specifying dev mode. I use it also to specify bundle names, etc. The only thing you need to care about is avoiding using the parameters which are served by webpack itself.