How to detect environment method is running in JS util file (CRA) - javascript

In my CRA app, util JS file, there is a method pause which I would like to change depending on the environment it's running.
class CompilationEngine {
...
pause () {
return new Promise(resolve => emitter.once('next', resolve))
}
...
}
I want pause function to return Promise.resolve() in test environment(when I run npm run start) since some tests are failing due to next event not emitted in console test. So how can I
detect the environment and change the code inside pause function.

I think you're looking for
process.env.NODE_ENV
right?

Quickly answer
In CRA you can use environment variables declaring them before the npm run start
You must create custom environment variables beginning with REACT_APP_. Example:
export REACT_APP_DISABLE_NEXT = true
CRA framework will expose this operative system level variable to a simple javascript variable ready to use in any part of your react code:
process.env.REACT_APP_NOT_SECRET_CODE
source:
https://create-react-app.dev/docs/adding-custom-environment-variables/
Explanation
Environment variables like export FOO=BAR are variables at operative system level. These variables are easy accessed with:
process.env.FOO
React is not a nodejs javascript. React will be converted to vanilla javascript to be able to run in a browser. In this javascript process.env does not exist.
But CRA Framework (which is nodejs), have access to the operative system variables, so it create us an emulation of process.env containing just variables which start with REACT_APP_. Any other variable without REACT_APP_, will be ignored
Advice
Expose export REACT_APP_DISABLE_NEXT = true just in dev or test stage, not in prod

Related

Environment Variables in NextJS are Undefined

I am using the next-auth library which requires the use of environment variables as follows:
Providers.GitHub({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
However, when I test out next-auth it is not working and it seems to me the reason why is because those variables are not loading properly. As such, I did a little test to see if I can access environment variables in my app and the test showed that I cannot.
This is how the test went:
// .env.local (root level)
NEXT_PUBLIC_ENV_LOCAL_VARIABLE="public_variable_from_env_local"
I then add the following code to my site:
<h2>test one start</h2>
{process.env.NEXT_PUBLIC_TEST_ONE}
<h2>test one end</h2>
<Spacer />
<h2>test two start</h2>
{process.env.TEST_TWO}
<h2>test two end</h2>
In this case, test one start shows up and test one end shows up, but the environmental variable does NOT show up. The same is true for test two start and test two end.
I did a similar test with console.log - namely:
console.log("test one", process.env.NEXT_PUBLIC_TEST_ONE)
console.log("test two", process.env.TEST_TWO)
That turns up as follows:
test one undefined
test two undefined
In short, for whatever reason I seem unable to load environment variables in my nextjs app. Not from next-auth, not in the code and not in a console.log. The variables are undefined and I do not know why.
Any ideas?
Thanks.
.env.* files are loaded when server starts. Hence, any modification in them is not applied unless you restart your dev/prod server.
Just halt the process (Ctrl+C/Z) and re-run next dev/next start to make them work. Note that you may also need to re-build the project (next build) before starting in production mode if you are using them in pages that are statically generated.
To be clear, according to the most recent docs, you are supposed to
place the variables in an .env.local file
then config your next.config.js file so it includes an env config
referencing your variables like this:
module.exports = {
env: {
secretKey: process.env.your_secret_here,
},
}
then you can call the variables on the client-side using the typical process.env.secret_here syntax. I may be mistaken but I do believe the NEXT_PUBLIC prefix exposes the env variables to the client-side and should ONLY be done in a dev environment to avoid security issues.
Searching the next.js documentation I found this:
// file: next.config.js
module.exports = {
env: {
customKey: 'my-value',
},
}
// Now you can access process.env.customKey
// For example, the following line:
// return <h1>The value of customKey is: {process.env.customKey}</h1>
// Will end up being:
// return <h1>The value of customKey is: {'my-value'}</h1>
So it seems, if you are using next.js version at or before 9.4 you place env variables into next.config.js
They also include one warning:
Next.js will replace process.env.customKey with 'my-value' at build time. Trying to destructure process.env variables won't work due to the nature of webpack DefinePlugin.
If you are using version 9.4+ the documentation says you can use .env.local files and prefix env variables with NEXT_PUBLIC_ to have them exposed in the browser.
Of note with this method is: In order to keep server-only secrets safe, Next.js replaces process.env.* with the correct values at build time. This means that process.env is not a standard JavaScript object, so you’re not able to use object destructuring.

How can I set environment variables on netlify?

I have a netlify react app. which is connected to my github. I'm using emailjs for receiving the messages from whoever reaches to my app.
emailjs deals with three ids 'SERVICE_ID', 'TEMPLATE_ID' and 'USER_ID'. But I don't wanna use them openly in my component js file.
Driver Function
function sendEmail(e) {
e.preventDefault(); //This is important, i'm not sure why, but the email won't send without it
emailjs.sendForm(SERVICE_ID, TEMPLATE_ID, e.target, USER_ID)
.then((result) => {
window.location.reload() //This is if you still want the page to reload (since e.preventDefault() cancelled that behavior)
}, (error) => {
console.log(error.text);
});
}
I think you're referring to environment variables, in order to test that out locally it will vary per the stack you use for creating the app, if you use react create app you can create a .env file in the root of your project and populate the values
REACT_APP_SERVICE_ID ="your_value"
REACT_APP_TEMPLATE_ID ="your_value"
REACT_APP_USER_ID ="your_value"
Don't forget to exclude this file from git, to avoid pushing secrets in your repo. to do that add this to your .gitignore
.env
After that you can call the variables in your code using the process.env like this:
process.env.REACT_APP_SERVICE_ID
Now modify the code:
function sendEmail(e) {
// Your code
emailjs.sendForm(process.env.REACT_APP_SERVICE_ID, process.env.REACT_APP_TEMPLATE_ID, e.target, process.env.REACT_APP_USER_ID)
// your promise
}
To make that work in netlify you would have to add the variable in your netlify project, follow this section to do that: https://docs.netlify.com/configure-builds/environment-variables/#declare-variables
As you noted I added the prefix REACT_APP_, this is because react create app does this:
Note: You must create custom environment variables beginning with
REACT_APP_. Any other variables except NODE_ENV will be ignored to
avoid accidentally exposing a private key on the machine that could
have the same name. Changing any environment variables will require
you to restart the development server if it is running.
If you are using gatsby or nextjs the env variables naming convention might change so please be aware of that.
You can set env variables on netlify. Please have a check the below images.
Check Adding env variables to react app
You can create a .env in your root dir and add your keys, api end points,... inside of it.

Node vs React: functions in generic javascript modules

I have a Node server with a utils file that looks like this:
update = () => {
//
};
module.exports = { update };
This works, but when I use the same file in a React app, I get the error
"'update' is not defined no-undef"
To fix this I must add const keyword. This makes no sense to me. Why is declaring the function needed only in React?
This is because the React you're using has come bundled with a linter which warns you of potential code quality problems. create-react-app is one of the React bundles which comes integrated with ESLint.
If you don't want to see the warning and don't want to use ESLint, you can build your project manually from scratch, rather than using a boilerplate setup like create-react-app.
If you installed ESLint for your Node project, you'd see the no-undef warning for Node code as well.
Note that what you're seeing is a linter warning, not a runtime error. If you ignore the warning and bundle and serve the project anyway, it will be still be runnable if it doesn't run in strict mode. (In strict mode, the use of an undefined variable without declaring it with const / let / var first will throw an error)
The linting rule being violated in the code is described at length here:
https://eslint.org/docs/rules/no-undef
For further reference on what's going on when you don't declare a variable (and why it probably isn't a good idea), see
What is the purpose of the var keyword and when should I use it (or omit it)?
If you're using modules, you should pretty much always be using explicit imports and exports only - don't implicitly create global variables (like you're currently doing with update = () => {), since that defeats the point of using modules.

Enviroment variables react

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.

Confused by how many ways there are to set NODE_ENV

I'm trying to set a flag that informs my code whether it is in production or development. So far I've seen:
In VS Code's launch.json:
{ "configurations": { "env": "NODE_ENV": "development" } }
In Node's package.json:
{ "scripts": { "start": "NODE_ENV=production" } }
In Webpack's webpack.config.js:
module.exports = { "plugins": new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }) }
While running the code:
set NODE_ENV=production && node app
NPM packages:
https://www.npmjs.com/package/envify
Powershell:
$env:NODE_ENV="production"
I guess I'm just confused because by default I have around 4 of those set currently. How exactly do these interact? Are they all referring to the same variable? Should I only have one of these? Which ones overwrite the others?
I'd really prefer if there were just a single point to set this because it seems like every single module lets you specify it and as a result, I'm confused as to where it is actually being set. Also, is there anyway to access this flag on the client-side as well or is it server-side only?
In the scenario you've specified, the NODE_ENV environment variable will be initialized by the process that is actually executing your code. See the below excerpt from the environment variable wikipedia.
In all Unix and Unix-like systems, each process has its own separate set of environment variables. By default, when a process is created, it inherits a duplicate environment of its parent process, except for explicit changes made by the parent when it creates the child. At the API level, these changes must be done between running fork and exec. Alternatively, from command shells such as bash, a user can change environment variables for a particular command invocation by indirectly invoking it via env or using the ENVIRONMENT_VARIABLE=VALUE <command> notation. All Unix operating system flavors, DOS, and Windows have environment variables; however, they do not all use the same variable names. A running program can access the values of environment variables for configuration purposes.
So if you were to run your code using pm2, then pm2 will actually assign the NODE_ENV environment variable prior to executing your application. It uses a JSON file for options where you can specify your environment variables using the env property.
In short, all the ways to set your NODE_ENV are more or less equivalent, it just boils down to who starts your process.
Since environment variables are local to a machine (the environment) they are set locally and can't be set by a client.

Categories