<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Petros Kyriakou</title>
    <description>The latest articles on DEV Community by Petros Kyriakou (@pitops).</description>
    <link>https://dev.to/pitops</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F189336%2Fc494b693-718f-4373-8aeb-d08ce6f7a79c.jpeg</url>
      <title>DEV Community: Petros Kyriakou</title>
      <link>https://dev.to/pitops</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pitops"/>
    <language>en</language>
    <item>
      <title>How to develop a local package and use in a vite app</title>
      <dc:creator>Petros Kyriakou</dc:creator>
      <pubDate>Thu, 18 Apr 2024 11:35:17 +0000</pubDate>
      <link>https://dev.to/pitops/how-to-develop-a-local-package-and-use-in-a-vite-app-1hb3</link>
      <guid>https://dev.to/pitops/how-to-develop-a-local-package-and-use-in-a-vite-app-1hb3</guid>
      <description>&lt;p&gt;This might be a niche topic, but recently I had to link and develop a shared library that is not part of the same repo as the main app codebase. And there is no monorepo involved either. &lt;/p&gt;

&lt;p&gt;On the web the resources to do this are scattered and don't cover hot reloading.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;if you ever came across such a scenario, in such cases the usual workflow is develop the package in isolation, build and release. Then go to the app and update the version number so you can bring the changes in.&lt;/p&gt;

&lt;p&gt;BUT, wouldn't it be cool to be able to develop the shared package side by side with live reloading and reflect the changes in the main app, make sure everything is working as expected and THEN release ?&lt;/p&gt;

&lt;p&gt;In this article, we are gonna do just that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;The setup for the purposes of this tutorial is the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Package boilerplate generated using &lt;a href="https://tsdx.io/"&gt;tsdx&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Basic vite react app with typescript&lt;/li&gt;
&lt;li&gt;Using yarn&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Shared package
&lt;/h2&gt;

&lt;p&gt;Let's call it &lt;a class="mentioned-user" href="https://dev.to/awesome"&gt;@awesome&lt;/a&gt;/package (do that by changing your package.json name).&lt;/p&gt;

&lt;p&gt;The changes needed here are very few. The main thing to know is that Vite uses ESM and needs to know exactly where to look for the root file so lets help it&lt;/p&gt;

&lt;p&gt;in &lt;code&gt;package.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"exports": {
    ".": {
      "import": {
        "types": "./dist/index.d.ts",
        "default": "./dist/shared.esm.js"
      },
      "require": {
        "types": "./dist/index.d.ts",
        "default": "./dist/index.js"
      }
    },
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what we are saying above is the following. &lt;/p&gt;

&lt;p&gt;If you are an ESM consumer (import) use the these types and this is the entry point.&lt;/p&gt;

&lt;p&gt;If you are a commonJS consumer (require) use these types and this is the entry point.&lt;/p&gt;

&lt;p&gt;Now vite knows what to look for, great!&lt;/p&gt;

&lt;h2&gt;
  
  
  Vite setup
&lt;/h2&gt;

&lt;p&gt;in &lt;code&gt;vite.config.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {defineConfig, ViteDevServer} from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [react()],
    optimizeDeps: {
        exclude: ["@awesome/shared"]
    },
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, Vite likes to optimize deps but in our case since its an ESM lib we want to skip that.&lt;/p&gt;

&lt;p&gt;Great, now vite knows about our package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yarn setup
&lt;/h2&gt;

&lt;p&gt;Now we need to do two things.&lt;/p&gt;

&lt;p&gt;Install the package as a local dependency.&lt;/p&gt;

&lt;h3&gt;
  
  
  In shared package
&lt;/h3&gt;

&lt;p&gt;The first step is to make sure yarn knows where to look for the package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn link
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  In main app
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add link:./../your-project // here adjust to be the relative path to your project. In case you use pnpm or npm you need to adjust this accordingly - most probably use file: in front.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you already released and use the package with a specific version. e.g in package.json you already have the package as a dependency like so - &lt;code&gt;"@awesome/shared": "0.0.1"&lt;/code&gt; then do the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn link @awesome/shared
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, we have made sure vite is aware of the package, and our package manager, in this case yarn - has made the necessary linking.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development
&lt;/h2&gt;

&lt;p&gt;In shared package do a change that is meaningful and can be easily observed in the vite app.&lt;/p&gt;

&lt;p&gt;Afterwards, &lt;/p&gt;

&lt;p&gt;In &lt;code&gt;shared package&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn start // if you used tsdx to scaffold or else use the equivalent command with your setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;vite app&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will notice that the shared package change you made is reflected in your vite app. &lt;/p&gt;

&lt;p&gt;However, you will notice that making a second change to the package it is not being reflected to the vite app.&lt;/p&gt;

&lt;p&gt;Thats because, Vite by design does not watch changes in &lt;code&gt;node_modules&lt;/code&gt; and because does caching of the dependencies under &lt;code&gt;node_modules/.vite&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;The suggestion is to run the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn dev --force // underneath its vite dev --force
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is too manual for our liking, isn't it?&lt;/p&gt;

&lt;p&gt;So, let's see how to fix that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding a plugin to watch specific packages for changes
&lt;/h2&gt;

&lt;p&gt;We need to add a plugin in order to watch for our packages, so here is the final &lt;code&gt;vite.config.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {defineConfig, ViteDevServer} from 'vite'
import react from '@vitejs/plugin-react'

// This plugin will watch node_modules for changes and trigger a reload.
// Works only for build --watch mode.
// https://github.com/vitejs/vite/issues/8619
export function pluginWatchNodeModules(modules: string[]) {
    // Merge module into pipe separated string for RegExp() below.
    const pattern = `/node_modules\\/(?!${modules.join('|')}).*/`;
    return {
        name: 'watch-node-modules',
        configureServer: (server: ViteDevServer): void =&amp;gt; {
            server.watcher.options = {
                ...server.watcher.options,
                ignored: [
                    new RegExp(pattern),
                    '**/.git/**',
                ]
            }
        }
    }
}

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [react(), pluginWatchNodeModules(['@awesome/shared'])],
    optimizeDeps: {
        exclude: ["@awesome/shared"]
    },
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start the vite app again and do changes to the shared package. They should be reflected to vite app almost instantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus
&lt;/h2&gt;

&lt;p&gt;Now that you are able to develop and test your package, you need to unlink the local package and use the version you used when releasing the package with the changes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn unlink @awesome/shared 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now update &lt;code&gt;package.json&lt;/code&gt; (in vite app) with the latest release version and run &lt;code&gt;yarn&lt;/code&gt; to install it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You have learned how you can easily make changes to a shared package and they are then reflected to your vite app. Now you can be sure the changes work before releasing the shared package.&lt;/p&gt;

&lt;p&gt;I hope you found this useful and if you want to keep in touch you can always find me on &lt;a href="https://twitter.com/9pitops"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>vite</category>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>Introducing Messageraft! # buildinpublic</title>
      <dc:creator>Petros Kyriakou</dc:creator>
      <pubDate>Thu, 07 Oct 2021 15:07:15 +0000</pubDate>
      <link>https://dev.to/pitops/introducing-messageraft-buildinpublic-4p0b</link>
      <guid>https://dev.to/pitops/introducing-messageraft-buildinpublic-4p0b</guid>
      <description>&lt;p&gt;Introducing &lt;a href="https://twitter.com/messageraft_com"&gt;Messageraft&lt;/a&gt;  🎉. A single API that can be used to dispatch email, SMS, and chat-based notifications all from a single interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backstory
&lt;/h2&gt;

&lt;p&gt;Since I sold my startup, I have been left with a void that my creative mind was looking for ways to fill.&lt;/p&gt;

&lt;p&gt;One of the ideas that I kept coming back to prior to selling my startup was a notification gateway as a service. I went ahead and scratched my itch and MessageRaft is the result of that.&lt;/p&gt;

&lt;p&gt;Let's get some things out of the way first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notifications gateway, erm whats that doc?
&lt;/h2&gt;

&lt;p&gt;A notifications gateway as the name implies is a portal where notifications pass through. In layman terms, it's basically a server that has an API exposed to other services/apps and receives requests.&lt;/p&gt;

&lt;p&gt;And you guess it, notification requests. Simply put, it is a single API that can process multiple types of notifications and dispatch accordingly.&lt;/p&gt;

&lt;p&gt;While it is still in its infancy, it is fully functional, the core is open-source hence it is &lt;strong&gt;free&lt;/strong&gt; to use and you can get started in &lt;strong&gt;under 2 minutes&lt;/strong&gt; (your internet connection and computer is the only bottleneck on that!!!)&lt;/p&gt;

&lt;p&gt;So, without further ado, I have built and released a CLI which you can use to get started &lt;a href="https://www.npmjs.com/package/@messageraft/cli"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Future plans
&lt;/h2&gt;

&lt;p&gt;Messageraft is going to be 100% build in public and its core will always be free. I am looking to see if it picks traction and if it does I plan to create a product around it for people who don't want to host the service themselves plus a magnitude more providers support.&lt;/p&gt;

&lt;p&gt;In addition, I have recently released a helper tool that makes it even easier and faster to develop and test emails locally from your machine with the help of MessageRaft which I am going to cover in another article so stay tuned for that!&lt;/p&gt;




&lt;p&gt;This is the first time I am building in public and would appreciate any type of feedback you can provide. As always you can find me on &lt;a href="https://twitter.com/9pitops"&gt;twitter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>opensource</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Managing multiple environments in NestJS</title>
      <dc:creator>Petros Kyriakou</dc:creator>
      <pubDate>Wed, 22 Sep 2021 16:47:32 +0000</pubDate>
      <link>https://dev.to/pitops/managing-multiple-environments-in-nestjs-71l</link>
      <guid>https://dev.to/pitops/managing-multiple-environments-in-nestjs-71l</guid>
      <description>&lt;p&gt;So, recently I started working on a new startup and each time I do, I try to adopt a new technology be it language or framework . (this is not always recommended, in this case I have previous experience with NestJS)&lt;/p&gt;

&lt;p&gt;This time around I chose to adopt NestJS. Have used it before for pet projects and found it really fun so I thought why not to use it as the backend for my new startup? Felt like a no-brainer.&lt;/p&gt;

&lt;h1&gt;
  
  
  The problem
&lt;/h1&gt;

&lt;p&gt;As this is not my first rodeo with startups, I actually take time to set up the backend properly instead of being in an MVP rush mode. One of the things that needed configuration early on, was &lt;strong&gt;the separation of environment variables between different modes&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;e.g development, test, staging, and production&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Looking at the &lt;a href="https://docs.nestjs.com/techniques/configuration" rel="noopener noreferrer"&gt;docs&lt;/a&gt; there is no real suggestion on how to do that but it gives you breadcrumbs here and there on how to achieve such a thing by putting the pieces together.&lt;/p&gt;

&lt;p&gt;So here I am documenting how I did it so you don't have to waste more time on it. Ready? Let's go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1
&lt;/h2&gt;

&lt;p&gt;Create the following structure in the root of your NestJS app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvo60qcmu8gqcol5tez6f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvo60qcmu8gqcol5tez6f.png" alt="Screenshot 2021-08-16 at 7.37.13 PM.png" width="208" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 - Initializing ConfigModule
&lt;/h2&gt;

&lt;p&gt;Open up your &lt;code&gt;app.module&lt;/code&gt; and write the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ConfigModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// ...skipping irrelevant code&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;ConfigModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forRoot&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; 
    &lt;span class="nx"&gt;PrismaModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ProductsModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;AuthModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;controllers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AppController&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AppService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// ...skipping irrelevant code&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if we don't pass any &lt;code&gt;options&lt;/code&gt; to the &lt;code&gt;ConfigModule&lt;/code&gt; by default it is looking for a .env file in the root folder but it cannot distinguish between environments. Let's move onto the next steps where we make the &lt;code&gt;ConfigModule&lt;/code&gt; smarter in where to look and what to load&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 - Populating the development.env file
&lt;/h2&gt;

&lt;p&gt;Let's populate the &lt;code&gt;development.env&lt;/code&gt; file as a first step towards creating separate environments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JWT_SECRET=luckyD@#1asya92348
JWT_EXPIRES_IN=3600s
PORT=3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4 - Populating the &lt;code&gt;configuration&lt;/code&gt; file
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;configuration.ts&lt;/code&gt; - its main purpose is to create an object (of any nested level) so that you can group values together and make it easier to go about using it. &lt;/p&gt;

&lt;p&gt;Another benefit is to provide defaults in case the env variables are undefined and on top of that you can typecast the variable as it's done for the port number below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// configuration.ts&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;configuration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;NODE_ENV&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;3001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_EXPIRES_IN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then let's pass options to the &lt;code&gt;ConfigModule&lt;/code&gt; to use this configuration file like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import { configuration } from '../config/configuration'; // this is new

// ... skipping irrelevant code

@Module({
  imports: [
    ConfigModule.forRoot({ 
       envFilePath: `${process.cwd()}/config/env/${process.env.NODE_ENV}.env`,
       load: [configuration] 
    }), 
    PrismaModule,
    ProductsModule,
    AuthModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})

// ...skipping irrelevant code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have now used two options to configure the &lt;code&gt;ConfigModule&lt;/code&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;load&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This should be pretty self-explanatory, that it loads the configuration file we are giving it and does all the goodies mentioned above.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;envFilePath&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are pointing the module (underneath its using the dotenv package) to read an .env file based on the &lt;code&gt;process.env.NODE_ENV&lt;/code&gt; environment variable. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;process.cwd()&lt;/code&gt; is a handy command that provides the current working directory path&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;BUT we are just now loading the variables, how do you expect the module to make use of the &lt;code&gt;process.env.NODE_ENV&lt;/code&gt; variable before the env variables are loaded?! &lt;/p&gt;

&lt;p&gt;Well, read more on the next step!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 - Initializing the NODE_ENV env variable
&lt;/h2&gt;

&lt;p&gt;First of all, what is the NODE_ENV variable for? Well, it's a practice used by devs to denote which environment they are using. &lt;/p&gt;

&lt;p&gt;In short, NODE_ENV lets the app know if it should run in the development, production, you-name-it environment by looking at its value. &lt;/p&gt;

&lt;p&gt;There are actually many ways to go about loading env variables, and one of them is to set the variable inline to the execution script like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// package.json

"scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "NODE_ENV=development nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "NODE_ENV=production node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json",
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Notice the &lt;code&gt;NODE_ENV=development&lt;/code&gt; and &lt;code&gt;NODE_ENV=production&lt;/code&gt; above.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When we execute the script using one e.g &lt;code&gt;npm run start:dev&lt;/code&gt; it will actually set the variable and will be accessible in your NestJS app. Cool, this gives an answer to the question we had above.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Windows users must install &lt;code&gt;cross-env&lt;/code&gt; package as windows doesn't support this way of loading variables and alter the commands like so &lt;code&gt;"start:dev": "cross-env NODE_ENV=development nest start --watch"&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 6 - Usage
&lt;/h2&gt;

&lt;p&gt;We now have two methods of reaching the values of the env variables&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 1
&lt;/h3&gt;

&lt;p&gt;As seen above we can make use of the process.env. to access the variables. However, this has some drawbacks in terms of accessing env variables during module instantiation so be mindful of that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 2
&lt;/h3&gt;

&lt;p&gt;Using the &lt;code&gt;ConfigService&lt;/code&gt; to access the variables. Setting up the &lt;code&gt;ConfigModule&lt;/code&gt; now gives us access to its service which consequently gives us access to the variables&lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Get&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AppService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ConfigService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;appService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AppService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;configService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ConfigService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;getHello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jwt.secret&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 7 - Update .gitignore
&lt;/h2&gt;

&lt;p&gt;If you do a &lt;code&gt;git status&lt;/code&gt; you should notice that the &lt;code&gt;development.env&lt;/code&gt; file is being watched and will be committed. While that is somewhat OK as long as you don't use the same values for example in the &lt;code&gt;production.env&lt;/code&gt; lets update .gitignore to ignore &lt;code&gt;.env&lt;/code&gt; files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// .gitignore

// add at the bottom

**/*.env
!config/env/development.env

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What it says here, is to ignore all &lt;code&gt;.env&lt;/code&gt; files except for &lt;code&gt;development.env&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  (&lt;strong&gt;BONUS&lt;/strong&gt;) - Validating the env variables
&lt;/h2&gt;

&lt;p&gt;Now we have come full circle but we can go one step further to ensure that our variables are in the correct type and loaded.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1 - Install &lt;code&gt;joi&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;This library will do the heavy lifting of validating our env variables by comparing them against a &lt;code&gt;schema&lt;/code&gt; we provide.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install joi

OR

yarn add joi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 2 - Populate validation.ts
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;joi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validationSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;NODE_ENV&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;provision&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;JWT_EXPIRES_IN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what we did above was to make sure that the NODE_ENV is one of the mentioned strings, the JWT_* variables are &lt;code&gt;strings&lt;/code&gt; and &lt;code&gt;required&lt;/code&gt;, and we require the &lt;code&gt;port&lt;/code&gt; to be a number and have a default value (hence why we don't &lt;code&gt;required()&lt;/code&gt; a value to be present)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Notice that the validation schema naming must be exactly like it's in the &lt;code&gt;.env&lt;/code&gt; file and NOT how you wrote the names in &lt;code&gt;configuration.ts&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Step 3 - Update options in &lt;code&gt;ConfigModule&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;validationSchema&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../config/validation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;ConfigModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forRoot&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;envFilePath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;/config/env/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.env`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="nx"&gt;validationSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="nx"&gt;PrismaModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ProductsModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;AuthModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;controllers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AppController&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AppService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So here we imported and provided the &lt;code&gt;validationSchema&lt;/code&gt; to the module. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Exercise: Try setting up NODE_ENV something else than the four values defined in the validation schema and see what happens&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  (&lt;strong&gt;BONUS 2&lt;/strong&gt;) - Avoid the need of importing the config module everywhere
&lt;/h2&gt;

&lt;p&gt;There is a handy option to avoid having to import the config module in every module that is being used which is pretty neat. Its called &lt;code&gt;isGlobal&lt;/code&gt; and below you can find how it's used&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;ConfigModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forRoot&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;envFilePath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;/config/env/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.env`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;isGlobal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="nx"&gt;validationSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="nx"&gt;PrismaModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ProductsModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;AuthModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;controllers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AppController&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AppService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;You have set up a flexible way of setting up your env variables for each environment in a non-complicated manner while also maintaining type and value integrity by validating the env variables against a schema.&lt;/p&gt;

&lt;p&gt;I hope you found this useful and if you want to keep in touch you can always find me on &lt;a href="https://twitter.com/9pitops" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>environment</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Cheap/Free SMS API ?</title>
      <dc:creator>Petros Kyriakou</dc:creator>
      <pubDate>Fri, 16 Aug 2019 21:51:15 +0000</pubDate>
      <link>https://dev.to/pitops/cheap-free-sms-api-3ipb</link>
      <guid>https://dev.to/pitops/cheap-free-sms-api-3ipb</guid>
      <description>&lt;p&gt;Is there a cheap / free API of sending SMS?&lt;/p&gt;

</description>
      <category>help</category>
    </item>
  </channel>
</rss>
