Setting up a nodejs project with typescript and deploying to heroku
Published: 2021-10-04 13:39:47

<p>Setting up nodejs with typescript can be quite troublesome if not done properly. To make this worse you probably won't see the issue with the way you set your project up until you want to deploy it. Today we are gonna go over how exactly we can set up nodejs with typescript in a way that would make deployment easy.</p> <h1 id="getting-started">Getting started</h1> <p>For this tutorial we are gonna be using the following packages: </p> <ul> <li> yarn </li> <li> nodejs </li> <li> typescript </li> <li> ts-node </li> <li> express </li> <li> nodemon </li> <li> @types/node (type definitions for nodejs) </li> <li> @types/express (type definition for typescript) </li> </ul> <h1 id="initializing-the-project">Initializing the project</h1> <p>we are going to initialize the project with yarn and git</p> <pre><code>yarn <span class="hljs-keyword">init</span> -y </code></pre><pre><code>git <span class="hljs-keyword">init</span> </code></pre><p>we should have our package.json file create for us like so</p> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632520932783/2sCNW9nK1.png" alt="package_json_created.PNG" /></p> <h1 id="installing-the-dependencies-for-the-project">Installing the dependencies for the project</h1> <p>To make our lives easier let's install express</p> <pre><code>yarn <span class="hljs-keyword">add</span> express </code></pre><blockquote> <p>Installing typescript and ts-node as dev dependencies</p> </blockquote> <pre><code>yarn <span class="hljs-keyword">add</span> -D typescript ts-node </code></pre><blockquote> <p>installing the type definition for node and express</p> </blockquote> <pre><code>yarn <span class="hljs-keyword">add</span> -D @<span class="hljs-keyword">types</span>/node @<span class="hljs-keyword">types</span>/express </code></pre><blockquote> <p>and finally nodemon to run our server in development</p> </blockquote> <pre><code> yarn <span class="hljs-keyword">add</span> -D nodemon </code></pre><p>After installing our dependencies it should be included in the package.json file</p> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632521040738/8iLV5N_qf.png" alt="package_json_postinstall.PNG" /></p> <p>And our node_modules folder must have been created</p> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632521068567/exkR_qz4m.png" alt="folder_structure_step2.PNG" /></p> <p>Let's create a .gitignore file and add our node_modules in there to prevent it from being tracked by git</p> <pre><code><span class="hljs-comment">// (in .gitignore)</span> <span class="hljs-selector-tag">node_modules</span> </code></pre><h1 id="adding-the-scripts">Adding the scripts</h1> <blockquote> <p>add the following to your package.json file</p> </blockquote> <pre><code> <span class="hljs-string">"scripts"</span>: { <span class="hljs-string">"start"</span>: <span class="hljs-string">"node dist/index.js"</span>, <span class="hljs-string">"build"</span>: <span class="hljs-string">"tsc"</span>, <span class="hljs-string">"dev"</span>: <span class="hljs-string">"nodemon --exec ts-node ./src/index.ts --mode development"</span> } </code></pre><p>our package.json should look like this</p> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632521099391/5ddsWf2Tp.png" alt="package_json_postscript.PNG" /></p> <h2>Explaination for the script</h2> <ul> <li> The build script is responsible for making our javascript build of the project for deployment (it would build all our files into a dist folder with the tsc command which we would set up in a second) </li> <li>start is what would run the app when we deploy it to service such as heroku</li> <li>dev is to run our app in development</li> </ul> <h1> Generating our tsconfig file </h1> Normally we would run <code>tsc --init</code> to create our tsconfig.json file but in this tutorial i would use a library created by one of my favourite youtubers (<a target="_blank" href="https://www.youtube.com/c/BenAwad97">Ben Awad</a>) called tsconfig.json. To use the package we'll run: <code>npx tsconfig.json</code> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632521146710/kN5vap8eS.png" alt="benawads_tsconfig.PNG" /> I'll select nodejs and that should create a tsconfig for us. <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632521166007/dGNke16s8.png" alt="tsconfig_benawad.PNG" /> so it contains some set rule for our project, feel free to change whatever you like to your liking but the most important options here are "outDir" which tells the typescript compiler where to compile our javascript file, "excludes" which tells typescript what files to ignore, "include" tells typescript what files to check during compilation, "target" the version of javascript we are compiling to (which Ben has set to es2017) and "module" which tells typescript what module syntax should be used. <br /> The "outDir" has been set to dist but you can name it whatever you want (but remember to change that in the package.json file) but by convention it is usually best practise to call it dist or build. <br /> we are gonna want to include the dist folder to the .gitignore file as this folder is only needed during deployment . <h2>Creating our source folder </h2> <p>First we are gonna want to create a folder called "src", this is where we would write all our typescript code</p> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632521499317/5f4OwY_bd.png" alt="final_folder_structure.PNG" /></p> <p>I'll create a file called index.ts which would be our main input</p> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632521523230/e9T9i0VCv.png" alt="indexts_stage0.PNG" /></p> <h1 id="now-lets-write-some-code">Now let's write some code</h1> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632521679053/GesTeL_86.png" alt="code_snippet_1.PNG" /></p> <p>Here we are importing express, setting the a new express application to the variable app. We set the PORT variable to use the process environment port if available and 8080 otherwise then we listen then PORT variable. And we handle our get request with the app.get() method by sending to the client "hello" + client hostname(which is localhost in this case) <br /></p> <h2>now let's run our server</h2> <br /> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632522291464/jiXMzOlZC.png" alt="start_dev_server.PNG" /> <br /> <h2> now let's run it in the browser </h2> <br /> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632522322875/z0jZnutEr.png" alt="browser_test_1.PNG" /> <h2>Let's make a change</h2> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632522346876/mqHJ-m8HP.png" alt="ts-error-1.PNG" /></p> <p><br /></p> <p>That threw an error because in the tsconfig.json the "noUnusedParameters" property is set to true which prevent the unused parameters in the code (which is some best practice stuff :( ).</p> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632522387777/58di_uSpW.png" alt="ts_conflit1.PNG" /></p> <p>To remove the error you can either disable the rule by setting "noUnUsedParameters" to false in the tsconfig.json file or simply use the editor quick fix option which I am gonna use.</p> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632522411694/WEHVSAmPz.png" alt="quick_fix_1.PNG" /> <br /></p> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632522439204/OaU2WNh7w.png" alt="quick_transition_1.PNG" /></p> <p><br /></p> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632522486329/mQja1s-F3.png" alt="fix1.PNG" /></p> <p>That was fixed by placing an underscore on the unused parameter, now let's restart the server</p> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632522500377/pF0MeLtTl.png" alt="restart1.PNG" /></p> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632522509672/FvhUmH1LD.png" alt="change1.PNG" /></p> <p>It works yay!</p> <h1 id="deploying-our-app-to-heroku">Deploying our app to heroku</h1> <p>Now let's see how exactly we can deploy our app which is the part which cause alot of issues especially when unusing typescript with nodejs.</p> <p>first i am gonna run the build command so that we can see how our app would be built.</p> <p>we'll run:</p> <pre><code><span class="hljs-attribute">yarn</span> run build </code></pre><p>This should create a folder dist which contains our compiled code</p> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632522583571/z3faCKpOS.png" alt="build_files.PNG" /></p> <p>This is gonna be what would be run on heroku when we deploy</p> <p>I am gonna delete this file for now.</p> <p>Assuming we did everything correctly up until this point, i am gonna list the step for deploying this add to heroku via the heroku-cli. If you don't have installed you can install it with <code>npm install -g heroku</code></p> <p></p><ul><p></p> <li> <h2>Logging in to heroku</h2> <br /> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632522601501/gf1ZX6Q28.png" alt="heroku_login.PNG" /> </li> <li> <h2>Adding changes to git</h2> <pre><code>git <span class="hljs-keyword">add</span> . </code></pre><p></p></li><p></p> <p><li> <h2>Committing changes</h2></li></p> <pre><code>git <span class="hljs-keyword">commit</span> -am "deploy" </code></pre><p></p> <p><li> <h2>Adding heroku remote</h2> <br /></li></p> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632522623092/A5PohYpJg.png" alt="heroku_remote.PNG" /></p> <p></p> <p><li> <h2>Pushing to heroku</h2></li></p> <pre><code>git <span class="hljs-keyword">push</span> heroku master </code></pre><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632522649820/btsEx5kyM.png" alt="deploying1.PNG" /></p> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632522665183/c-3Ze3CeK.png" alt="deploying_complete.PNG" /></p> <p></p> <ul> <h1 id="deployed-site">Deployed site 🚀🚀🚀</h1> <p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632522674943/DIqi7J385.png" alt="deployed_site.PNG" /></p> <p>yay! we have our site deployed.</p> <h1 id="conclusion">Conclusion</h1> <p>This is just a very basic example but the main purpose of this guide was to help give an idea on how you can host/deploy a nodejs typescript project of any sort. You can change the rules in the tsconfig.json file to match your use case but make sure the "outDir" is correctly specified. I have had issues deploying typescript nodejs projects myself but now I feel a little more confident doing it now so I decided to share it with the community. I hope this was able to help out in someway. Lemme know if there are better ways to do this. Please do like and comment if you found this interesting.</p> </ul></ul>