How Nx and Monorepos just made my life 10x better

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
i already have a video going over the basics of nx and what the point of a mono repo is so i won't rehash that here if you don't want to watch the previous video though these are the key points a mono repo stores multiple or even all of your apps in one repository nx makes creating and managing this monorepo easier code shared between multiple apps in the repo can easily be abstracted into libraries that also live inside the repo and all of the dependencies for all of the apps can be managed and updated from a single package.json file so in this video i'm going to walk you through the repo for a real life project that i've just finished up that uses nx i'm not going to focus so much on how it all works but rather the specific things that demonstrate why this structure of nx and mono repos makes my work so much more efficient and effectively why i think it's worth using so what we're looking at here is my nx mono repo that i'm using to hold all of the sites that i deploy so i currently have two live sites in here living inside of the apps folder which are elite ionic and josh maroney so these are gatsby sites deployed to netlify and i can bring those up now these are live as i just mentioned so we have josh moroney and elite ionic at eliteionic.com so right away you can probably see there are a lot of similarities between these sites we have a very similar header with the tags in the search bar uh this sort of featured post component is also very similar so this is due to the shared ui that i'll get to in a moment so even though i've only got two live sites at the moment with another one on the way in this mono repo i've already enjoyed some massive efficiency gains with this setup and so i am currently adding another site right now and i plan to add more in the future as well potentially another one or two more sites maybe even more than that so that's exactly why i felt like i needed something like nx and a monorepo because maintaining all of these projects individually would have been probably far too much work for me to handle by myself but with all the benefits that nx and monorepos provide i can much more easily keep all of these projects up to date reuse code between them keep everything fresh rather than having to do that individually for each separate project okay so let's jump into some specifics i'm going to break this down into a few different things that i really like about nx or this setup and the things that are really making it worth it to me so one just key benefit and this is a pretty basic one is just having everything in the one place everything runs from this single mono repo so i do a lot of jumping around between projects so if i want to work on something in elite ionic and then signing in josh moroney i can if i need to change something that affects both of these i have all the shared libraries that i'm using so i can just jump in there and update that if i want to serve one of the applications if i want to run a development server and take a look at some work i'm doing on josh maroney i can just run nx serve josh maroney if i want to take a look at eliteionic i can just run nx serve elite ionic and that's going to start that development server get the development build running and i can see it right away and all of these nx commands are something that i do really enjoy it makes my life a lot easier not just the serve command but we also have things like the generate command so if i want to generate a new component if i want to create a say another shared ui component for my gatsby sites which are react based i can just use the narwhal react package to generate a component for me with a bit of boilerplate i can tell it which project it should belong to if i want to put that in the shared ui project it'll even handle automatically exporting that component for me if i want to export it to be available to my apps and you can see a list of all of the different shared ui components that i'm currently using in here at the moment but we will touch back on that in just a moment and we also have the nx deploy command which is another thing we are going to talk about in a little bit to actually build and deploy your application to where it needs to go we of course have test commands that we can run there's linting commands and basically you could extend this to include whatever you needed so just the default nx environment and the default nx commands provide a lot of sort of structure and value already but you can also extend it to do what you need okay so just that basic structure is useful i think but another huge benefit for me is this idea of managing all of the dependencies from a single package.json file so this isn't uh 100 required you can technically manage uh dependencies on a sort of per project basis but the recommended way is to have this single package.json file to manage all of your dependencies and the idea is that if we need to update something if i want to say update the version of gatsby or whatever plugin i'm using i'm going to update that in one place i'm just going to run npm install whatever package or npm update or however i want to go about doing that and then all of the apps are all going to get that update because they're all pulling their dependencies from this one file and as you'll see we have a single node modules file here we don't have node modules in the individual projects themselves so this means that i'm keeping everything up to date all at once which is a great benefit to me i do get the initial sort of hesitation for this approach because it seems kind of terrifying to update one dependency and have that potentially affect 10 different apps that you need to check but the main ways to combat that are to make sure that you're keeping things updated frequently which you're more likely to do in this monorepo kind of setup you're not going to get an app that gets left behind because you haven't had to work on it in six months and the other part is having a suite of tests that you can run so you can easily see if something has broken due to a dependency update so this might get harder to manage for larger monorepos with more apps in them but an example i do like to bring up is that this is effectively the structure that google uses to manage uh like a thousand or more different apps inside a single monorepo and they do take this approach of having one dependency update potentially affect hundreds or a thousand different apps so this is certainly manageable at scale okay so moving on to the third thing that i like uh that is the shared ui which we've already sort of had a bit of a look at already so not necessarily the shared ui but just the idea of abstracting into libraries in general but because this is a gatsby site or gatsby sites that i'm working with a lot of the stuff that i'm sharing between the different apps are these just ui elements that are appearing on the website like this featured lessons box this pagination is a component these article cards are a component the individual tags are a component the search box the header there's just a bunch of components here and you can see them all all listed here you can sort of have a look through that list if you want so when i began this project i just had the elite ionic website i'd created a new website uh for elite ionic specifically and then what i did was set that up inside this monorepo and i basically just started pulling out everything that could be shared to other sites that i'm maintaining so i wanted to have a new version of my josh moroney website as well and i want to have additional websites and i want to use all of this sort of investment that i've put into creating these components i don't want to have to sort of copy and paste or you know recreate a bunch of stuff anything that can be used in other apps i wanted to pull out into this shared ui library so that's what i did basically i just went through and created a bunch of react components in this shared ui library pulling stuff out from the elite ionic code base into various components and now when i want to use those components if we just open up something in elite ionic for example so i'll open up my index page here you can see that i can just import any of these components from this shared ui library and so this isn't an external library that i have to install or manage through npm this just looks directly in this shared library folder that i already have set up in the monorepo so you can see here i'm using the seo component which is down here featured topics featured lessons content feed and module feed and so we could just open up one of those for example we'll check out the featured lessons and so we can pass in some props to configure those which becomes i guess a bit more important if you're using this in multiple places you might want to tweak the functionality depending on you know if it's on joshua nearly ionic i might want to have some configuration options as to how to display that but then we basically just have you know standard sort of react component and that is being shared throughout multiple different websites and then if something happens let's say you know maybe i decided this is a bit this isn't particularly great i want to change this or there's a bug or whatever now if i have say even 10 websites i can just come to this one place update this file in one place and every app is going to get that update so that's certainly going to save a lot of time and it's also going to stop my sort of less attended to websites from getting out of date if i have a website that isn't sort of as important to my overall business as say elite ionic or josh maroney is i might not look at that for a while and then you know when i do look at it after a year i'm like oh this has some really outdated ui it's looking a bit looking a bit old you know then you have to sort of go through and spend some time updating that this approach everything just sort of gets pulled along and updated and kept fresh all together okay so let's move on to the next point which is custom generators so what a generator will allow us to do is to create a new project from some base so we're gonna be able to set up some files that we want to uh create from so this is actually in a separate project you might not have noticed that switch there but i've actually switched over into a separate nx project and unlike the last one which was created with create nx workspace this is actually built using create nx plugin so this is another monorepo that manages all of the plugins that i'm creating and so if we open up the packages folder here we can see i've got two separate plugins one called gatsby template and one called nx netlifedeploy and so these plugins can be built and either installed directly from just this distribution folder into our main monorepo or they can also be published on npm and installed just like any other dependency so this gatsby template is my generator plugin so if we jump back into our sites mono repo here and i'll just search for gatsby template you can see with this one i'm just installing this directly as a dev dependency by linking directly to that distribution folder so that's where the built output of my plugin is which is different to the netlify deploy plugin which we will talk about in the next section but you can see this one i've actually published it to npm and i'm installing it from there so with these uh plugins set up we can just use them like all of the sort of default uh nx commands we just saw before that we could run something like nx generate to create a react component using the narwhal react package so just like we can use the the novel packages we can also use our own uh plugins that we've created as well so once i've created my own generator plugin i can run nx generate josh maroney gatsby template blah blah blah can supply all of the options to that now there are already a lot of default nx uh plugins and commands that we can use and if you're adding your own in as well that can get even more confusing especially if you are working you know potentially in a team environment with this mono repo maybe you have 20 different devs uh releasing different plugins and stuff like that so if that all does get a bit hard to keep track of one great thing to use is the nx console plugin for vs code and we can basically just uh explore all of the different uh commands we have available so if i forgot the name of my gatsby generator plug-in for example or i forgot the options that i could use with it i'm going to come into the nx console here click on generate and then i can just search through these commands here and you can see i've got my gatsby template so i can just click on that command and i can even use these fields to fill out the values click run and that's going to run the command for me so i could do something like supply my new site give it a description url and all of that and it will run that command and create the site for me so i don't want this video to become a tutorial on how to create a generator exactly but we will take a quick look at how this does work so the basic idea with a generator is that we can supply a bunch of files which are going to be used as a base for creating the project so if i take a look at gatsby template lite you can see there's a files directory here and then inside of that are all the files required to set up a gatsby project so basically what i did was i took my original elite ionic code base and sort of stripped it down to its bare bones just the things that i would want in a freshly generated site and i put all those files in here but we also want to configure a new site as well there are some values that we want to set up that are unique to that new app so you might notice here some of these are template files so in the gatsby config for example i have this field here called site metadata which supplies the the title and the site url and the description that's going to change from project to project so rather than having to you know create this new project with some dummy values and then having to go back and sort of search and replace things manually we can create a template like this and we can use values that are supplied to that generate command to just automatically input the correct values and so when we're creating this generator plugin we can describe what kinds of values we expect with this schema in the the schema files here we have the typescript definition and also the schema.json file and so you can see here that we're allowing people to supply five values in total name url and description are required and we can also optionally supply tags in a directory and what that means is when you say for example use this uh nx console you can input those values using these fields or you can just apply it directly to the command itself using these flags here like name and description okay so one more thing to talk about that i do like and that is the deploy command so if i run nx deploy elite ionic i can automatically build and upload my site to netlify it's going to be running live with whatever version i just built or if i want to deploy josh moroney i can run nx deploy josh moroney so all of these sites are deployed to netlify and by default netlify will detect any pushes to your repository and automatically run a build and deploy for your site but i don't want all of my sites to build and deploy every time i push something into the repo maybe i just want to update one website or maybe i don't want to update any of them maybe i'm just making some small change to the project code base i don't want to necessarily do a fresh build and deploy of every project so although it is possible for netlify to work with mono repos they do have built-in support for monorepos i opted to deploy my sites using the nx ecosystem and the deploy functionality that they provide instead so nx gives us complete control over how we want to handle the build and deploy process for each of our applications individually and this is where executors come in which we saw back in the plug-in workspace here you can see i have this nx netlifedeploy which is what we're going to be talking about now so if we open up the workspace.json file you can see the various commands that can be run for all the different applications in the mono repo so if we take a look at elite ionic here for example we have a build command which we can run using nx run elite ionic build there is a serve command and there's a production serve command and then there is a deploy command and this is what defines what happens when we run nx deploy elite ionic or nx run elite ionic deploy and you can see that i'm using that custom nx netlifedeploy plugin that i've created as the executor here so it's basically saying when we run this command this is what is responsible for executing the command and when we do that we are supplying it with some options which include an output path so this is a path to the built gatsby site so when we run a gatsby build command the output of that gatsby site that's been generated will be put into a public folder and i'm also using some lambda functions some cloud functions for this website and so this is the folder where those functions can be found because they also need to be deployed to netlify which will then deploy them to aws and we also need the site id of the site in netlify so that we actually know you know where to upload this to in netlify so just a quick side note here creating your own plugins is sort of getting into the more advanced nx territory and you should generally be able to find community plugins to do whatever you need and there is indeed already a community plug-in for deploying to netlify uh but it didn't support deploying functions so i had to create my own and i did also contribute my changes back to the original plugin as well i'm not sure if that's been incorporated yet or not but hopefully if you uh want to use that you will be able to soon so it is something to look out for maybe you won't be able to find a plugin to do exactly what you need and maybe you will need to sort of dive into the more nitty gritty stuff of nx a bit uh but it isn't it is a little bit complex and a little bit to get your head around but it's also not completely unapproachable so i'll probably do a separate video or tutorial on exactly how to create a custom executor uh but for now like we did with the generator we're just gonna have a quick look at it just to get a sense of what's going on so let's jump back over into that uh plugins monorepo and we'll take a look at nxnetlife so the key functionality here is inside of the executors we have our deploy executor and if i open up the executor.ts file we can see what is actually happening and again we have these schema files which define what we actually want passed into this executor so we basically just have this run executor method that runs through whatever process we need to deploy our application so in this case it runs a build of whatever project we specified and that builds either going to pass or fail and then once it has that build it's going to attempt to upload that to netlify using the site id that was provided so there's just some stuff going on here just checking that the site actually exists and then down here is where we actually do the upload so if there was a functions path supplied we add the functions folder to our upload and then we run client.deploy which uses the netlify api which we have set up at the top here you can see we're importing netlify api and then we're setting that up as client here so we run client.deploy with our site id with our output path and any additional configuration we have which includes our functions folder so all of this is going to happen when we run that nx deploy elite ionic command it's going to hit this section here it's going to pull in that functionality and do whatever we want it to basically so although there is a bit of setup involved with this process i like this approach because the sites won't all be built automatically every time i push to the repo i get to manually choose when i want a deploy to go out from the command line and the builds happen on my local machine so it doesn't use up my netlife build time and i also like the idea of having complete control over the build environment so that's the gist of how i'm using nx to manage my gatsby sites at the moment and why i've found it hugely beneficial even with just two live sites in this monorepo i found the efficiency gains to be incredible and i will likely be expanding this out to four or five sites in the future which i probably just wouldn't have attempted without this structure because i wouldn't have the time to appropriately maintain them all and i haven't even talked about one of nx's key features which is computational caching to help your commands run faster this is just icing on the cake to me it's not actually why i'm using an x this video was a bit different to my usual style of video it's a bit more like a rambling devlog than a tutorial but i thought it would be useful for people to see a real-life example of an nx mono repo so if you did like this video please feel free to leave a like and subscribe and i will see you in the next [Music] one you
Info
Channel: Joshua Morony
Views: 4,203
Rating: undefined out of 5
Keywords: ionic, tutorial, tutorials, ionic tutorials, ionic framework, coding, coding tutorials, angular, angular tutorials, cordova, cordova tutorials, capacitor tutorials, mobile, mobile apps, apps, html5, ios, android, native, hybrid, pwa, web apps, progressive web applications, programming, ionic 5, react, stenciljs, stencil, performance, ui, ux, animations, screencast
Id: 1eHlaVoeDfU
Channel Id: undefined
Length: 23min 26sec (1406 seconds)
Published: Wed Aug 04 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.