ReferenceError: “process is not defined”
Common Error
This error is common in many frontend projects. You might have encountered it a few times, and it might come from a line of code like this:
// This causes the error
const { NODE_ENV } = process.env;
And the solution is:
// This fixes the problem
const NODE_ENV = process.env.NODE_ENV;
Why the Error?
Force the error now. Open the console and type the following:
> console.log(process);
Uncaught ReferenceError: process is not defined
Now, try the same in NodeJS. Create a file or open the node repl and run console.log(process)
:
> console.log(process);
process {
version: 'v14.18.1',
versions: {
node: '14.18.1',
//…
In NodeJS, “process” is defined, but not in the browser. This is because NodeJS and the browser are different runtime environments.
Build Step
Most frontend projects have a build step; this build step is executed in NodeJS.
The build step is in charge of removing the process
dependency so that it doesn’t get to the browser. It changes the values to something like the following:
const NODE_ENV = ‘development’;
These values depend on the environment variables when executing the build.
Try It with Webpack
I built a Webpack toy project, where I have the following code:
console.log('hello world');
const { NODE_ENV } = process.env;
console.log(NODE_ENV);
When I run the build step, Webpack creates the following file that will be then sent to the browser.
(() => {
console.log("hello world");
const { NODE_ENV: o } = process.env;
console.log(o);
})();
The reference to process
has not disappeared after the build step. It’s still there, and therefore, the browser complains that it doesn’t understand process
.
Try the Fix
What happens when I change my code to:
console.log('hello world');
const NODE_ENV = process.env.NODE_ENV;
console.log(NODE_ENV);
Then the build step outputs the following:
console.log("hello world"),console.log("production");
Now, the process
reference has disappeared and been replaced by the value of the environment variable at build time.
Why the Fix?
Why does the fix work?
const NODE_ENV = process.env.NODE_ENV;
By default, the build step does a simple replacement of strings. So, for example, in the Webpack configuration, I have the following:
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(env.NODE_ENV),
}),
],
With the previous configuration, Webpack replaces the text process.env.NODE_ENV
for the value during the build process.
Why Doesn’t Deconstruction Work?
Aren’t both codes the same?
const { NODE_ENV } = process.env;
// isn’t this the same?
const NODE_ENV = process.env.NODE_ENV;
For the language, they are the same. Yet, the build process takes a straightforward approach: it replaces text.
In the first example:
const { NODE_ENV } = process.env;
The text process.env.NODE_ENV
is nowhere to be found. Therefore, the build step can’t replace it.
Understand the Steps and Runtime Environment
Keep in mind: “Where is the line of code executed?”. There are several answers: in the client, during the build, during a test, or any other step you might have. This helps you understand the runtime environment and therefore catch possible errors faster.
Be mindful of the runtime environment where your code is executed.
In this case, process
is not defined in the browser environment, hence the error. The solution is to remove the reference to process
, and replace it with the value you need during the build step.
If you like this post, consider sharing it with your friends on twitter or forwarding this email to them 🙈
Don't hesitate to reach out to me if you have any questions or see an error. I highly appreciate it.
And thanks to Bernat, Michal and Miquel for reviewing this article 🙏
Thanks for reading, don't be a stranger 👋
GIMTEC is the newsletter I wish I had earlier in my software engineering career.
Every other Wednesday, I share an article on a topic that you won't learn at work.
Join more than 5,000 subscribers below.