Lesson Description

The "Architectural Linting Exercise" Lesson is part of the full, Enterprise UI Development: Microfrontends, Testing, & Code Quality course featured in this preview video. Here's what you'd learn in this lesson:

Steve demonstrates how to set up architectural linting rules with ESLint. He also highlights the practical use of plugins, such as boundaries, to automate these checks and reduce human error during code reviews. The goal is to create guardrails that protect the architecture from accidental or careless violations by developers or automated systems.

Preview

Transcript from the "Architectural Linting Exercise" Lesson

[00:00:00]
>> Steve Kinney: Two options, right? Obviously, we have the kind of example codebase, right? But I would also say like all that stuff is more practical if you have a codebase, right, like check out a branch and like play around with it as well. Like the ones that I would kind of take a look at are something like ESLint plugin boundaries, banned dependency, and I understand that like, hey, he showed me a slide of what a rule looks like.

[00:00:26]
I am well aware that you don't remember that. So the one thing I will say is like finding like in this case, for architectural linting one, I also have like, you know, a step-by-step guide of where, when I do it together with you, what I'll do. So definitely reference that because like, no one, I can't remember how to do this stuff half the time, and I always have to look at the docs and stuff along those lines.

[00:00:52]
So that is a piece of it, or if you got like one of your little friends running, you know, try that out as well. I think those are all totally, like there's no glory in having handcrafted your own ESLint rule. Like, don't worry about it. But like, yeah, I think any of these, you know, the rules of what circular makes circular dependencies for you are obviously going to be specific. That's why I kind of think it's interesting in your codebase to kind of take a look.

[00:01:29]
OK, so our job today or what we seek to do is, first of all, violate some of our architectural principles, and then implement some amount of rule setting that will prevent us from doing that, right? Because again, what we're trying to do is guard rails, one, from ourselves, two from our co-workers, and three from our one or four or five potential robotic co-workers with very short memories who like to take every shortcut possible all the time.

[00:02:07]
So let's go ahead and we're going to violate our architecture a little bit here, where we can say like, do this in like the analytics dashboard or whatever, it doesn't really matter, we'll import user list and we'll do it from at-apps, user, yeah, users, source. Cool. And like there are some issues here where it's like, that's not really a type thing, so, but this is like a bad thing, right? We went into the package, we found its source directory, we found a component that it doesn't want to have us have, right?

[00:02:57]
Like, yes, there are some red squiggly lines because it's not the types that they support. At the end of the day, the problem is like someone shouldn't do this, so the red squiggly lines are welcome in this case, but again, like that's hoping someone has an editor set up the same way as you. That's hoping it's not, again, a friend whose name starts with the letter C, I don't want to shame anyone in particular, we all know that they're all apt to do it, right, like so on and so forth, right?

[00:03:32]
And so what we want to do is have a system in place that catches this, right? And like we will see like a, hey, no unused variables because like, sure, but like that's not the one we're worried about. Like that's not the crime is not that they imported something that they shouldn't have imported and didn't use it. The crime is that they imported something that they shouldn't have imported, right? Like, so we'll focus on the kind of main crime in this case.

[00:04:12]
So we'll do a, I think I changed, I, right, and so our only issue is this like, it's defined but never used. But again, what we want to catch is like, you broke the API contract of the, we're trying, like the whole reason we're doing an architecture like this is to have boundaries. Like we can even probably ignore that warning so we have a clearer, I think that's the one I want. And so I'll run that again.

[00:04:44]
So like, that will not be our problem in this case. So like, looks, everything's great in this case. They reached into a package they're not supposed to, that's not a public support API that is not, you know, something that team should be allowed to change and move at their own autonomous pace because they've not made the contract to maintain that, but yet everything is fine, right? So what we're going to do is we'll go into our ESLint config, right?

[00:05:13]
I might have just checked out the one where this is already done, so like, we'll take a tour of it real quick and then we'll make a few checks in here, but let's hide this for a second. So what we can have in this place, let's talk about this without the terminal there because I think this is probably super useful without watching me type at all to begin with. So we pull in the boundaries plugin, as you can see, that is just what we, something we grabbed from npm in this case.

[00:05:44]
And like, not like for some reason, not all of the ESLint plugins have like TypeScript types built in. Like so many of them, right, and so like that's fine to ignore. This is a JS file anyway, so we're not particularly concerned about it. But we can do is we can begin to find like, OK, where are the boundaries of this, of what we do and do not want to have, right? And so like, and how does that match to something, right?

[00:06:08]
So we've got this idea of like what is an app that live in the at-apps. This is very similar to that PNPM workspace that we set up earlier, and like, could you code generate, like read this YAML file, write to that that you probably could, but like, the idea that you have a folder of applications, the idea that you have a folder of packages, I would not over-optimize this one too much. The interesting part is the rules, right?

[00:06:33]
And what you are allowed to pull in and what you are not allowed to pull in. Because like if we go back over here, you know, that's not the, can we not be at the top of the page? Right, like testing obviously can pull in everything because it might have something like the integration test or the end-to-end test, where it should be allowed to pull in the application, pull in the individual packages, right, that is, you know, kind of fair game.

[00:07:01]
But for instance, like you might have it so that like, given, you know, your app shell should be able to obviously pull in the pieces, but like it is unlikely that a given piece should be able to pull in the entire app. Right, I think that's fair. Now you might, I have a very specific use case, and yeah, OK, great, cool, do that. But generally speaking, the point of the show is to pull in the pieces and you can decide like which ones can call into the other ones.

[00:07:37]
Like, we might say that like any given like sub-app of our like micro front-end architecture is able to pull in the UI components, the design system, and the shared library, but probably shouldn't be able to pull in like another team's internal code, right? And so what we do is we start out with like effectively the disallow list, right? Where we're saying like, by default, we're not allowing jumps across these boundaries, right, that we set up.

[00:08:13]
And then for each one, like what is OK, right? So, you know, in this case, the default decisions that I had made whenever I did this previously was, you know, the application can pull in the packages and the mocks, but like the application shouldn't be allowed to pull in like the test utilities. Because the test tests the application. Right, and you know, for a package we can pull in, you know, from that particular package, so on and so forth, right?

[00:08:43]
Like, do we want to allow like no private stuff to be pulled out and that is an error, right? And you can start to like set up rules that ideally you enforce in CI/CD. Right, so you can catch if there's a boundary in there. But like I said before, very rarely is somebody going to do these things like on purpose, right? And you have the case instead where like you want to have a set of like, hey, did you get a little carried away with IntelliSense?

[00:09:18]
Right, like because it's happened to me, where I'm like line 152, and like I tab complete, and it's the function I've used 1000 times, and it turns out that like it grabbed one from deep inside somewhere else on line one, and I literally did not see it, right, at the time, and like humans are not the best code reviewers. Right, like if they're stressed out and busy, they'll be like, look good to me, because like you're like, can someone review my pull request?

[00:09:42]
It's been sitting there. I need it to in order to do the next thing, and then like somebody kind of does these things. So having kind of some of these systems in place that then allow you to kind of pull this stuff in makes this a lot easier to do as well.

Learn Straight from the Experts Who Shape the Modern Web

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