typescript and create-react-app .env
Louis
Posted on August 6, 2019
You can create a type definition file that extends the NodeJS namespace to enable auto-completion for your env configuration. This is quite useful if you plan to reduce the amount of time spent looking up your .env
file:
Check bottom for the solution. For now, let’s wander back a bit. I first thought about this problem when I found that process.env.NODE_ENV
is typed and has code completion, while the other does not:
This piece of information had been in my mind since the first time I saw it around 2017. However, I never really looked into it too deeply as back then I had no need to leverage client-side environment variable.
At Plasmo, we decided to leverage client-side environment to swap between staging and production endpoints. Initially with 2 variables it was manageable. But when that number grew to 13, it became a bit annoying to lookup the .env file, as the variable names are increasingly getting longer. This annoyance can be tolerated for a while, as we were focusing on our product. However, in the back of my mind, there was a strong drive to squash this “bug.”
Technically this is not a bug, that is why there were "”.
A big win of using TypeScript is that refactoring is a breeze, and that is the key to move fast — starting with one file, grow it to 300 loc, then split it into several files, rinse repeat. This applies to our type definition as well, as using a single .d
(definition) file to describe both our api typing as well as our theme typing becomes convoluted. So we decided to finally split our typing into these neat files:
Finally, I can bid our good ol’ react-app-env.d.ts
farewell. But much to my surprise, when resuming CRA (create-react-app) server afterward, that file was resurrected. After going through CRA's internal packages for a bit, I found that react-scripts (the main program powering CRA) was programmed to generate this file.
This is when my brain started to notice the name of this file: react-app-env
. Every magic string has meaning, said the basic rule of edb (on Windows you can use x64dbg). To generate a file with such specific name means there was some significant use of it, probably within the organization of ${process.env.REACT_APP_AUTHOR}
.
Digging deeper with duckduckgo.com with the search term “react-app-env.d.ts declare global,” the third result (note: not 1st or 2nd, but 3rd) gave some great insight, in particular, in this comment.
The github issue's author was trying to tackle the “bug” at hand, and the code snippet was extremely insightful:
declare namespace NodeJS {
interface ProcessEnv {
NODE_ENV: 'development' | 'production' | 'test'
PUBLIC_URL: string
}
}
In brief, the typescripts support of CRA consume an extended definition under the NodeJS namespace. To extend it for our environment, simply put the snippet above in your react-app-env.d.ts
BONUS
You now know how to extends your environment typing for some good old lazy process.env
auto-completion. But now you need to deal with global API placed under Window (like Stripe.js). Below will save you a trip to the duck (This is a simplified version of our react-app-env.d.ts
file:
/// <reference types="react-scripts" />
declare namespace NodeJS {
interface ProcessEnv {
NODE_ENV: 'development' | 'production' | 'test'
PUBLIC_URL: string
REACT_APP_HASH: string
REACT_APP_API_URI: string
REACT_APP_WS_URI: string
}
}
interface Window {
Stripe: any
}
Posted on August 6, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.