Check out a free preview of the full Rapid Application Development with Code Generation course:
The "CLI" Lesson is part of the full, Rapid Application Development with Code Generation course featured in this preview video. Here's what you'd learn in this lesson:

Lukas demonstrates utilizing CLIs to quickly generate the entire structure of an application, including placeholder components and redux slices for defined entities. A student's question regarding how to adapt this approach to changes within the domain model is also covered in this segment.

Get Unlimited Access Now

Transcript from the "CLI" Lesson

>> Let's talk about the CLI and CLIs are incredibly important because it allows us to leverage the collective intelligence of a much broader, more available smarter community. And so every modern framework has a CLI from view to react, to angular, to ember etc and a lot of times individuals will use the CLI to generate a basic project.

[00:00:33] Possibly even a single in the terms of the data model or the the progression that we talked about, like a cell, like I need to generate a component. Well, that's very convenient to do that. But what I want to illustrate here is the ability to put this together in a way that you can generate the entire structure of a project in a mirror matter of minutes.

[00:01:04] And so if we hop into this particular stackblitz here, we are going to go on a journey. And this is potentially a little bit disjointed because there's a little bit of angular and there's a little bit of react here. But I would like to demonstrate what is in so let me just pull this out into a new window.

[00:01:31] So we can see it in all its glory is most people when they work with the CLI, typically, they go about this far, or certainly doing mbmi. That's nothing new. But maybe we wanna generate a component. So I've seen a lot of developers, just do it. A little tiny piece like this.

[00:01:56] And when in fact, you stack this all together very quickly, you can generate a single command that you can even download and run this as a shell command. And so right now, in our domain model, we have users courses, lessons and assignments. But let's go ahead and let's add in another domain model to just make this interesting.

[00:02:32] And so as we go through this, you're going to notice that I'm just defining some schemas. So let's go with feedback schema. And we'll go with feedback. Now this is interesting because what is coral, the feedback. Well, to the best of my knowledge, it's feedback. So we're gonna go with feedback.

[00:03:12] We'll see what happens we'll generate it, so if it just looks super kooky then guess what, it's immutable we throw it away and we go from there so. Now, I have a config. And so I recommend that post workshop that you take this stackblitz and you kind of walk through these properties and what they are doing but really all I'm doing is creating a basic object that contains the properties that I want.

[00:03:47] So, a couple of things we're pointing out, we have libs, which in nx is a standalone library. So we're gonna have a data lib, a state lib, a material lib, a login lib. And so this allows us to create kind of stand alone libraries that we can reuse.

[00:04:06] And warm, portly we have these entities here and a couple prefixes. So everything in here, we have essentially covered a variation of it. And then if you remember in the primer, we iterated over a collection of commands to generate something. And as part of that, we used the array.reduce to consolidate the output of that particular command into a single thing into a single string.

[00:04:42] And so I think of this as a list of steps that we're going to take. So in this case. We're going to generate workspace, packages, dependencies, libs, slice. In this case react is a slice, our component layer, a container component called home. We'll go ahead and install jsonserver and then we're going to start.

[00:05:08] The application again function and parameters. And then up at the top. We're going to look at just a couple of these a couple of these methods and they should be very familiar. So we'll go with state, or rather slice, same thing. We're just reducing over the entities. And we're taking in generating a command based on each of the entities and attaching it to code.

[00:05:46] So what this looks like when it's generated is this particular block right here. So again basic string manipulation string interpolation and we're using array.reduce. And for basic one line stuff that we have, like let's say, container component, nx gc, entity model plural. And then we have a suffix.

[00:06:15] So I'm going to leave the other example in straight angular and hope that they fix that ESLn thing. But what's really interesting is most of these commands I did not have to change at all from one from react to angular. The reason being is that the command for generating a component is almost identical except for the suffix and so this was a little bit different but I was able to capture that inside of the suffix parameter and pass that in.

[00:07:00] So here where we have an object that has the suffixes, you'll notice export falls, routing is true, and style is scss. And so this is a combination of everything we've talked up to this point and if you remember in the slides. Then I said the initial project configuration or the wiring is a little bit tedious.

[00:07:32] The reason being is you have to do it at least once and so this is in my mind I think this is like this is a true custom mold that we have just made. So with that I'm going to roll the dice one more time and we're going to run this.

[00:07:52] So I'm just gonna paste this is and I'm going to just let this do its thing, and while this is going, that once it successfully installs, then we will sing, we will dance, we will be merry, and we'll move on to more sophisticated generators. If not, I'll probably tip off the chair, and die of a heart attack but the ability to add in additional entities and then generate the entire slice and stack for that particular entity is very powerful.

[00:08:38] So if I wanted to generate not only horizontally but vertically, a slice for a particular entity, I simply need to add it into my generator. And I'm able to pick and choose the bits and pieces that I want and spin it up. So this is by far in my opinion.

[00:09:02] The most high touch part of building a generator. With that said, what this allows you to do is if you have an agreement with your stakeholders on what the domain models are, then you can plug this in within minutes. You have the entire structure for your application. What I do with this is typically, I will generate the structure for my application.

[00:09:36] And at the same time I will generate the actual templates that I want to use for my application separately and then once the project's generated, I'll download my generated templates that are specific to this particular domain organization, etc. And then I'll just overwrite them onto the generated application.

[00:10:00] So it's very easy when it's like I want to move this thing over. And go find the equivalent file and just overwrite it. So I have a pretty good feeling about this. So let me click on localhost 4200. And let me just drag this over. And here we go.

[00:10:21] So I was able to generate this application. But let's go ahead and hop into the code just so we can see what we were left with. So if we look at this real quick, I have an app which has. The app but it has assignments, courses, feedback, lessons, users.

[00:10:54] And I've generated essentially placeholders for all of these components. And not only that, the if I go to this is why I think nx is really good if I go into course state into source into libs. Here I now have a redux slice for every single entity, that I defined.

[00:11:32] Now this may not be exactly what I wanna use but at least I have a placeholder or something to start with and so this alone by simply creating a small bit of tooling to generate a CLI command. A really a composite CLI command allows me to do what historically would have taken me all afternoon.

[00:11:59] Pre CLI I mean, it would take me a day pre CLI but post CLI that I've seen a number of developers do this one command at a time when I have been on engagements where I'm working with a client and we are doing some kind of roadmapping or discovery.

[00:12:22] And my entire goal in that engagement or that particular activity is to understand the domain model. And once I understand the domain model, then I can come over to a tool like this and I can generate an entire project. Is fast is it takes me to generate these basic schemas for the models that I've discovered through the conversation with the client and this is very powerful because now you have something that immediately you can show and you can show your stakeholders within you can start to iterate on and get feedback, Alice immediately.

[00:13:15] The other thing that I want to point out here before we move on is that these are the same commands that I would use if I were building a production enterprise grade application. There's nothing different between this generated project for a, let's say a proof of concept or a production grade application.

[00:13:40] The approach, the techniques are exactly the same, the artifacts are exactly the same. The difference is that I have or we are looking at how to accelerate that timeline by not changing the scope but by changing the way that we think about application development. Unfortunately, I don't yet know how to make myself immune to JavaScript package conflicts and inconsistencies I heard somebody say they were very smart that probably what you should do is pin your versions in your package.JSON and I think that Is a pretty good idea.

[00:14:24] So the question is how would I adapt this approach to changes within the domain model or more importantly my understanding of the domain model. So it's my understanding changes. How do I adapt this approach? Well, the beauty of this approach is that it is significantly more adaptable that my experience is that I realized very quickly that I have an incomplete or a superficial understanding of the domain.

[00:14:56] When I put something in front of a domain expert and I start to get feedback. And so for example, I built a travel application for a very large airline. And it was a constant cycle of I would build something I would show it to the stakeholder and they'd be like, that's kind of right but that's not how it works all the time.

[00:15:23] And then they would then go on to explain the 10,000 rules that govern airline travel. And so by using this approach, this one allows me to get or to uncover my superficial understanding of the domain much quicker which is what you want is that when you're programming the question is how do you know anything.

[00:15:54] And that's a really serious question is that how do you know that you are doing the right thing? Well, this is with feedback loops. This is why we write tests. This is why we do automated testing. This is why we do user testing. And in this case, what I do is that I isolate the pieces that are going to change and I generate the other pieces.

[00:16:19] And so if I realize that my domain was not quite right, well, in this case, it's fairly trivial that I would simply just generate. Maybe I don't have to generate the entire project but I would generate an entire slice of that project and then just replace it. And so I really want to encourage us to start thinking about our projects like immutable infrastructure is the pieces that we are going to change a lot where there is variance you want to segment that out.

[00:16:58] And isolate that abstract that out but the pieces that are conventional that are not going to change, you want to create a system in an environment that you can throw those away and replace it with an updated version very quickly. And again, this is the entire concept behind cloud based architecture and immutable infrastructure.

[00:17:24] Is that I don't need this container anymore. You tear down, you put something else up. And I am proposing that we can do this in code.