JavaScript and TypeScript Monorepos

Cleaning Output & rimraf

JavaScript and TypeScript Monorepos

Check out a free preview of the full JavaScript and TypeScript Monorepos course

The "Cleaning Output & rimraf" Lesson is part of the full, JavaScript and TypeScript Monorepos course featured in this preview video. Here's what you'd learn in this lesson:

Mike creates another tsconfig file that builds the necessary tools for various packages, and explains that when working with multiple projects in monorepoes each one refers to the other through a dist folder. Installing utilities outside of the packages folder for development purposes only is also discussed in this segment. The purpose of building configurations in different folders is to avoid the use of complex libraries.


Transcript from the "Cleaning Output & rimraf" Lesson

>> I wanna add another package, sorry, another Ts config to my packages folder. And this one serves a different purpose. The purpose of this Ts config that I'm about to create is that I wanna be able to say, build whatever is necessary For all of my packages, if anything's out of date, go ahead and just catch up.

So this one's gonna be very simple. We just need to say references and this is gonna be an array of paths. So this lets us do something like the following. I'm actually gonna stage my files here because I'm about to make a mess. If you're gonna repeat what I'm doing here, I advise you also stage your files because we're gonna create some junk.

So I could do tsc -build. And remember I'm in the packages folder now. All right, we're missing some dependencies here. I got it, I gotta straighten this out, yarn add date-functions. And react, says we need react up here. And I'm gonna need the type information for both of these.

We're already seeing that we're attempting to build we wouldn't be getting these errors. If we didn't If we were not that command was not being interpreted properly. So we'll try this again. I'm back in the packages folder. And it should work this time. Nope. I need just, of course I need just.

So what I'm using for my tests, yarn add types just and jest and then we're going to do the same thing in our types folder. So already what you're seeing here is like I'm having to run like install just in this one package and then go to this other package and install it and this other package, this is a problem that a later tool we incorporate into this project will solve, so just to recap what I did in my utils package And let you know I would have gotten this if I just run yarn.

In fact, let me run it right now. Just make sure that I catch up with everything. So everything is in my package JSON here. I just forgot to run yarn as I dragged those those folders into packages. That's why I was missing things for my node modules. But If we were to instal new dependencies, right, let's say we found a new es lint plugin, and we wanted to instal it broadly throughout our entire workspace, we would have to go to each independent package, and we would have to run this command and it's kind of We're manually doing like a for loop here for each package, I want to install this thing.

It's a little bit painful. I just want to point that out because we're gonna provide some medicine for that pain in a little while. Let's see if I'm ready now. So I'm back in the packages folder that contains all of my packages, and I want to run TSC dash B Dot write that's build everything according to the package, sorry, the TS config in this folder.

I'm just going to remove the use of this this concept of a private field, which is a new thing to, to JavaScript this year. There we go. Now here's the mess that I've created for myself as promised, you see that we've got these j s files right next to all of our Ts files.

Well, that's because this this Ts config, this this one that we were creating so we could build everything. This points to these project but it doesn't have any opinion about what the output directory is going to be. So it's not really looking at the TS configs of each respective package.

It's just sort of referring to their build output and linking it all together. So we can get around this problem. We can either like pop off all the new code changes that have been made, right, so we've got a bunch of j, s stuff. staged in Git right now we could manually roll those back.

Or we could run the same command here with dash clean and they should disappear. Go away. There it goes. So, we can modify our Ts config here with files and empty array. And if we try this again, [BLANK AUDIO] we shouldn't get all that JavaScript. And in fact we don't.

[BLANK AUDIO]. So and So just to be clear, if I were to delete these, let's delete some of our build output. Let's see if this build really works. Let's I wanna see something in front of me that proves that this works. rm rf build info and star dist.

So now we should be We just collapse things down. There's no dist folder here. And there's no Ts build info, and I should see those things pop up by building everything in the packages folder. And in fact, I do, there it is. So now I have a single command I can run that builds everything.

Pretty nice. So again, just these references they point to and we can command click into these. They point to other parts of the project, which must have composite true turned on. And that's what lets, you know if we had interdependencies between these things, they would just each refer to each other's dist folder.

They don't need to kind of like, include like a package A depends on package B. Package B doesn't need to have stuff from package A in its dist folder. All we have in here is things that pertain to types. All we have in here is things that pertain to utils.

Right, they're sort of stitched together at the tooling level, no duplication, which means you can't fall out of sync.Because there's one build output in one location for each package. So what I just did this rm rf thing, that's something that you're gonna need to do. Every so often right?

They're part of how this works part of the state current state of monorepo tooling involves caching layers, and it involves potentially things falling a little bit out of sync. So you wanna give yourself a nice button you can hit Or command you can run where it'll sort of clear everything away and you can start fresh.

That's the first thing I advise you do if things start to look weird, right like I'm missing a dependency or something's complaining about not having a module. Blow your build away and start clean and see if that works. So let's give ourselves the ability to do that. Now, we don't need this to be a function that's tied to a particular package or a functionality that's tied to a particular package.

It really has to do with the workspace. So we can install this as a workspace dependency. So we're back at the root of our mono repo and we can do this yarn, add rim raph. Now if I do this I think yarn is going to complain to me.

It's going to say running this command will add this dependency to the workspace root, rather than to the workspace itself. Which means like, rather than to a package within the workspace. It might not be what you want. But I can use the dash w flag if this is what I want, and in this case it is.

So you can see that once you're in this yarn workspaces mode. You kind of want to be operating with yarn add within a package, not at the outer level. The exception being like what we're doing right now, which is just utilities that are. Just for development purposes only, they have nothing to do with the package actually, you know functioning.

So now if I look at my outer package JSON, I have rimraf here, rimraf is a platform independent RM dash RF, so to people that may be following along on Windows This would also work in your PowerShell or your command line. So we're not tied to Unix here.

So now, in each file, I close all this down I can go to each of my packages. To their package JSON and in this little script section here, I can add a clean "rimraf dist tsbuildinfo, I should do star. I'm going to copy that line and paste it into this other package as well.

This one doesn't even have a belt. I should add that too. So both of these, I'll just put them side by side real quick. They have identical code here. Same thing. So now if I were to say go into my packages, Yarn clean, so I'm in types right so we should see dist and Ts build info disappear And we done.

Then we can do yarn build. And they come back. So now we have a clean and a built. good starting point. Now already we're saying this is another place where each package defines its own clean and its own belt. We will solve that because the mantra here is, I want one source of truth.

I do not want to break my promise to you about this being an easier thing to manage than having 10 libraries. 10 packages in a mono repo should feel like a library and a half worth of maintenance overhead. It should not feel like 10 libraries. Right. That's the whole value proposition here.

That's the reason we're choosing this pattern. So I want to make sure that we deliver on that promise.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now