Lesson Description

The "Managing Dependencies & Manifests" Lesson is part of the full, TypeScript Monorepos: Architect Maintainable Codebases course featured in this preview video. Here's what you'd learn in this lesson:

Mike covers tools like manypkg for linting and maintaining consistency in package manifests, helping detect issues such as incorrect dependencies and missing fields.

Preview
Close

Transcript from the "Managing Dependencies & Manifests" Lesson

[00:00:00]
>> Mike North: In this next section, we're going to take a close look at several tools that we can use to work with our package manifests. Establish consistency across our monorepo. Detect varied use of dependencies, meaning you have six versions of REACT across your monorepo. How do you deal with that?

[00:00:22]
As well as trimming away unused dependencies and exports. So a bunch of things that sort of relate to working with your package manifests and your external dependency graph. And these are some really nice kind of standalone projects that you could layer on top of pnpm or an NPM workspace or a Yarn workspace.

[00:00:48]
They all sort of work with any monorepo that sort of aligns with those conventions. So first we're going to take a look at many package and the main purpose we're going to use many package for is linting our package manifests. So if you wanted to have a really opinionated formatting of your package.json, like alphabetizing your dependencies, for example.

[00:01:20]
This is kind of like prettier for package JSON, if you want to think about it that way. Not just for formatting JSON and getting your quotes right and you're indenting, but more having a standardized way of formatting things so that as people change, go in and make changes to package JSON.

[00:01:39]
You're keeping the increment of change very small. Like nice readable diffs instead of seeing that somebody moved six lines around or something like that. Let's begin by installing the Manypkg CLI. So we'll go back to our environment, our dev environment, and we'll install this package. And I'm in the workspace very important here.

[00:02:01]
Like this is where you want your workspace level tooling. So we've installed any package CLI. By the way, there's an NPM scope. I know you've been working with packages like this before, but like this is an example of something that has a programmatic interface for like consuming this as a library as well as being able to use a CLI that they provide, the next step we're going to take is we're going to run pnpm many package check.

[00:02:31]
By the way, if you're still using NPM and you have to use like npm run or npx like this. This is the thing I really enjoy about pnpm, the fact that YARN does this as well, where if you have something that's in your Node Modules bin folder, something here, you can just invoke it directly menu package has a check command.

[00:02:54]
Remember, this is different from the check that we've been running that relates to svelte and type checking. Let's see what it finds. Workspace is valid, that's interesting. Am I in the right spot? [LAUGH] I thought I left some problems here. Well, let's look at the documentation and let's create a problem for ourselves and see if we can detect that maybe I fixed some things on the fly or fixed some things as we were going.

[00:03:26]
So Manypkg check runs checks against your Monorepo. An example of this is having peer dependencies that are not dev dependencies and having their range specifiers meet. So we don't have any of those root has production dependencies. We could certainly do that. So let's go to our package JSON here and let's say many package CLI is a production dependency.

[00:04:01]
>> Mike North: This will tell us if it's working. Hey, great. The root package JSON contains dependencies. This is disallowed dependencies versus dev dependencies in a private package. They don't affect anything and it creates confusion. This is important. It's not like, I want to be clear, private package. In this case, it kind of means two things.

[00:04:25]
One is literally this, which is, is this published to NPM or not? But the other is, is this a leaf level dependency or not? So, for example, in this package here, like if we were, let's say, let's say we had a step where we built things and then we want to slim down the set of dependencies, we need to run the UI in production, it does matter that we have some runtime dependencies here.

[00:04:59]
So I would argue this is a little bit of an imprecise way of describing this. It's not about private packages. It's about being a leaf level dependency versus being a dependency that has dependencies. If we need express as a transitive dependency, despite this being a private package, like if we were to move this up all of these and say these are all just needed for dev, that's going to be a problem, right?

[00:05:27]
Because remember, there are build commands with each of these. Each of your build tools, they have a mode where you could say, only install my prod dependencies. Sorry, not build tools. Your package managers have only installed prod stuff. That's an example of something that it can detect. If you were to say fix.

[00:05:52]
I think it's not fix, it's fix. You can see that it went through and it actually did this. Rename for us the kinds of things that it can detect. They have a bunch of different rules here. Invalid package names. This is about you've gotten too cute with your Monorepo package name.

[00:06:13]
You've put an emoji in there like a double width UTF16 character. And it's just not gonna, NPM will be unhappy with that. This is the one. This is the one that I was trying to run us into and I forgot a step. So let's do this. I'm gonna have my Monorepo's v2 URL here.

[00:06:36]
I want to go back to my code, and I'm going to say in my root package JSON, I'm going to have repository and then URL. And now let's run this. Wait, is it just this? Yep, there it goes. So this is a nice thing that many package is going to detect for us.

[00:07:07]
Like in an ideal world you could say I have one git repo for my monorepo. But ultimately when you publish to NPM, if we go to npm.js, oops, beach balling, and let's go to Babel, Babel preset TypeScript. You kinda wanna have a homepage or something that, well, maybe this is a bad example.

[00:07:43]
Here's the point. There's a repository URL on each package you publish and one option for doing this. And I can switch to a branch that I have here where I've got all of the work that we've already done today or that we will get through today. If I go to packages and then UI, you could have your own readme for each package and what you'd want to do is say all right, well I have a repo for the whole monorepo and I have a URL there.

[00:08:17]
Now, what many package is trying to get us to do is say there's a UI path here that we can go and add in each package's package JSON, not just for the whole repo. So if we go up here, repository and paste this in and grab that and we're just gonna change the name, that last little token in the string.

[00:08:40]
So we'll add this to server as well. I know I'm going a little fast here, but server and then models. Oops, I think I copied the whole line. Great. Now if we run this check again, it's going to say it has a repository. It has a repository field of this when it should be.

[00:09:23]
>> Speaker 2: You have the branch name in the, you tree/subs instead of-
>> Mike North: Yes. This is even more sophisticated than I hoped, right? You wanna have, this is steering me towards a mistake that I could have made here. So it's pretty sophisticated and it's a small number of checks that many package enforces, but generally a good thing to use.

[00:09:49]
Now there are other things that this does which is it allows you to run scripts for all packages within your monorepo. But bluntly I would use pnpm for this. In future steps, we'll use Lerna because this is not going to be as aware of the dependency graph. You'll see that a lot of monorepo tools have this feature where you're going to install a bunch of these tools and you'll have 12 different ways you can run a task in each package.

[00:10:25]
But what you want to lean towards is the ones that let you do interesting things we're going to see later in the course. Like Lerna, an NX is where that gets really sophisticated and what you should lean on. But this still has a unique feature of lending those package JSONs and giving you a very some helpful feedback where you can even see the stuff I'm doing.

[00:10:48]
It's busting me on because I'm pasting in strings that are not quite right.

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