Migrate a Node.js app from JavaScript to TypeScript | Tips for gradual adoption

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
if you're someone who works on large code bases written in javascript i'm sure you've come across your fair share of issues in maintaining them so migrating to typescript can help you manage your code base much better the migration process is not that challenging but it might be a little tedious especially depending on the size of your code base the good news is that typescript is built in a way that allows you to gradually migrate your projects in this tutorial i'll walk you through the steps involved in migrating a production-like node.js application to typescript i'll also include a few tips that you can use to help with a gradual migration alright let's begin [Music] now what i have here is a typical api backend so we've got our source folder we've got some controllers some services a server.js and an index.js also we've got some tests we've only written a test for the services but i'll get to that so the goal is to actually convert this entire service it's rather small but it is mimicking a production-like api so let's open up the index.js file now this is basically spinning up a server from server.js so server.js is spinning up your api using the code.js framework i'm plugging in two different middlewares one is my core body and another one for a products controller now my products controller is essentially a route for a products endpoint so if i open up the product's controller it's basically extending from a core router which is another external dependency product's controller is setting up a route or rather an endpoint for forward slash products and it's a get endpoint so what happens in this forward slash production point is we return the response that's given to us by this product service now product service is basically a mock service that is trying to mimic what an actual real world repository would be returning so this would be your database call that's returning all the products but obviously we're gonna mock that stuff in here so we have three different products written in an array and also we have another dependency which is uuid to generate a uuid for each response now that's basically our application so let's try to migrate this entire application to typescript now the first thing you want to be doing is to set up a tsconfig.json file so we'll do that by using npx npx comes bundled with newer versions of npm it basically lets you run commands from an npm package without actually having to install the package so we've now set up our ts config file let's open it up and let's have a look so it has this compiler options and it's set a lot of commented options but it's also enabled some of them now let's actually do a few things the first thing is your out directory we need to set in our directory we'll set it as dist we also need to set the root directory which is at its current level so that looks good can go further down let's also change module resolution and set it to node.js and for the time being let's set this es module interrupt to false for now we'll revisit this later because this is something that can help you with a gradual migration now this looks good so far so i think we are set up with the ts config at least to get things started now the next step for us is to rename the js files to ts so let's actually do that we'll revisit the tests a little later but for now let's focus on the application files so starting off with index.js so index.js looks fine but if we go over to server.ts we are seeing quite a few reds quicklys and the same goes for products.ts under the controller and the spec file which we'll revisit later on the services and so on so basically changing these to ts files has introduced some errors or recommendations now let's try to fix them one by one the first step is to actually start using es6 module inputs currently you can see we are using the common js style inputs so let's go ahead and change all the modules to start using es6 all right so now we've converted all the application files to start using es6 module inputs and index.js looks good we are not seeing any errors here let's move on to server.ts now server.ts is reporting a few issues let's start off with this so it's saying cannot find module core or its corresponding type declarations now the reason is because typescript is expecting its type definitions for these libraries which we obviously haven't provided so let's fix this by installing their types so we can do npm install at types we can do core ideally we want to be doing this for our dev dependencies only so let's also do core router set this as a depth dependency in this case which i forgot in the first place all right so that seems to have taken those errors away now next up it's still complaining about a few things it's basically saying that the module is declared using export equals and can only be used with a default input when using the es module interrupt flag so what this means is we're trying to use a common js module within ie6 module now this can work but we need to explicitly define this in the ts config so over here remember we turned off es module interrupt well we need to turn that back on that basically allows you to use com.js and es6 modules together and this is important because your code base might already be using common js and you might not want to change all your modules into es6 modules so make sure that es module interrupt is turned on so you don't have to migrate all of your modules into es modules you can simply decide to migrate them gradually so in this case you might also have external dependencies that you have no control over so you definitely will need to use this es module interrupt whenever you're doing a migration whether it's gradual or whether it's in one go all right so let's move back and that error seems to have gone okay so we got our core router as well so it's complaining that you don't have a type definition for the external dependency uuid now uid already has its own type definitions which we can easily install but let's assume that this is an external dependency that doesn't come with any types so what can you do in this case well you can declare your own type definitions for libraries so let's actually do that i'm going to create a new folder and i'm going to call it at types now in here i'm going to say just going to give it a generic name and i'm going to call it module.d ts that's how you define type definitions and let's declare a module let's call it uuid now this alone should remove that error but the problem is that we haven't really given any type definitions for its use cases right so we've got this v4 we don't know what this v4 is we are reassigning it as uuid v4 and we are calling it assuming it's a function but it could well be something else so we want to make sure that we give the proper types for this external dependency so let's actually do that so let's say that it's a function it's called v4 it accepts no arguments and it returns a string so there you go we've now given it a type definition so it says v4 is a function now we can easily call it as a function and for example if we change this into a string for example well v4 is going to be a string and we can't actually call a string as a function so an arrow pops up this is exactly the kind of thing that you are benefiting from by introducing typescript into your projects so let's go back in here change it to a function and that looks good alright so there are still a few things that we are seeing complaints about so you can see that parameter port implicitly has any type so again there are a couple of things you can do to actually fix this the first and most obvious thing is to actually assign a type free we know that this port is going to be a number it's call from index.ts so we can assign it the type number and that's great but let's say that you're seeing these errors pop up throughout your entire codebase and you probably don't want to go ahead and change every single file right the whole idea is to do a gradual migration so there are things that you don't want to touch at all what can you do about it well in that case we can remove this again we have a couple of options the first one is to use at ts ignore so you can go ahead and add this comment to all these places that you are explicitly gonna ignore for the time being this is also good in a way because it allows you to revisit and figure out what you want to do with these ignored comments another option is to actually set this in your ts config json so in your ts config json there is something called no implicit any now when you set strict to true it's gonna enable strict on all these rules over here so let's keep strict as is but go ahead and change this to false so that should take the error away as well now these are your options you can either define the type explicitly if you don't want to do that you can add your ignore comments or you can just set it globally in your tsconfig.json now let's move on to the products.ts now you can see this context object has an any type we want to be more explicit we know exactly what this context object is so let's assign it the context which comes from coa so there you go so that imports core and it destructures the context object and we assign that as the type of this parameter now it's actually time to transpile this code into javascript so let's see how we can do that the first step is to actually install typescript so let's install typescript as a dev dependency once that's done let's open up our package.json now we need to do a couple of things here let's set up a new script let's call it build and it's going to do tsc tsc is basically your typescript executable let's define the project that we're going to be using and that is your tsconfig.json so that is basically your typescript build script now let's run it and you're seeing a few errors two errors in fact and this is because we didn't actually migrate or convert our test files so what if you don't want to include your test files in your build well we can go to ts config and say include only the source folder let's go back in here build it again and there you go so we've excluded any of our test files now obviously we are going to migrate it but i just wanted to show you that you are in control of the things that need to be included when it comes to transfiling your typescript code and you should set this up to the way you want it to be all right so now let's cover the final piece what do we do about tests now the first thing is open up the test you can see a few things that we need to do obviously we need to change the way we import modules so let's quickly do that now you can see that i'm using chai and mocha to set up my test so first error is basically saying i don't have a type definition for chai so let's actually install types for both chai and mocha and that just basically gets rid of all the errors now the next step is how do we actually run this test because we know that this test is relying on this product service which is a ts file but a ts file needs to be transpiled before this test can be run so one thing we can do is use a just-in-time transpiler now there is a package called ts node that lets you do this just in time transpilation so ts node is great for local development use and setting up your tests and let's actually include ts node in our test script so we are saying moca test run this specific wildcard but we need to include ts node and register this should basically transpile any of your typescript code just in time and execute the test so if we go in and do npm run tests all right so it's complaining that oh yes so we need to rename this to ts because now it's converted to typescript and it's all typescript code so there you go our single test is passing successfully so basically that's it for this video guys i wanted to cover some of the main and important things that you can consider and use when it comes to migrating a production like application so a production like application usually has a bunch of tests it has a bunch of external dependencies that might have types or might not so we've covered that scenario we've also covered a scenario where you might not want to migrate your entire code base where in that case you can always use the module interrupt to enable common js and es modules there's also one last thing which i forgot to include and that can be very useful as well now if you want to actually retain some of your code as javascript files well you can leave them as javascript files but you can go into your ts config and say love.js so this basically allows your already existing javascript code to be included in the transformation obviously nothing much is going to happen there but that allows you to change or migrate a percentage of your code into typescript and leave the rest of them in javascript so i hope all of these tips are helpful to you and if you found them helpful please like this video and drop some comments down below if you have any questions if you want more content like this make sure to subscribe to my channel so i'll see you in the next one
Info
Channel: Ambient Coder
Views: 1,162
Rating: undefined out of 5
Keywords: nodejs to typescript, node to typescript, npm to typescript, convert javascript to typescript, adopt javascript in typescript
Id: kZGzyJWIyBM
Channel Id: undefined
Length: 19min 9sec (1149 seconds)
Published: Sun Jul 11 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.