Transcript from the "Final Q&A" Lesson
>> Student: The libraries that we were creating with the Nx Workspace, what would be the equivalent of that if we weren't using that extra layer of?
>> Lukas Ruebbelke: Good question. So that would then be scoped specifically to your project.
>> Lukas Ruebbelke: And I would just create that, in your app, it's a common feature.
>> Lukas Ruebbelke: And so the difference is you lose that portability but typically you'll see in an app, you'll see like a shared or a common folder. And that's where those things would go, so that it can be reused across components or additional services. And so prior to Nx, that's how I did that.
>> Student2: So if you have your project schematics, can you transfer those from one Narwhal domain to another? Or does the whole project tree get swallowed up in Git when you check it in? Is there any segmentation between Narwhal and your project? It seemed to me like it was all consolidated but a lot of people are asking the question or several people asked that question on the chat.
[00:01:07] Did I butcher it?
>> Lukas Ruebbelke: So the schematics that we're using is in the global scope when we did NPMI, G, or you can do Yarn. And so that goes into your global registry, if you will. If you created custom schematics, so for instance in the tools, if you look in the root here, is that you can create your custom schematics and check those in.
[00:01:33] So the angular CLI stuff, that's tucked into the module. Nx, those are tucked in, but if you created a custom schematic ,you would put that in tools, schematics, and drop that in there.
>> Student2: Great, that answers the question.
>> Student: I'm gonna follow up, if you were to play this, how would you select the libraries that you need?
[00:01:53] Or would there be a similar situation with the schematics or?
>> Lukas Ruebbelke: And so you can do a targeted build, ng build target, or project equals dashboard, and it will pull in whatever it needs to do that. One of the things that with a monorepo, and it's it's not a huge insurmountable thing, but if you have, for instance, a continuous integration pipeline.
[00:02:21] Well, before so go grab this repo and everything that's in it. Run it through AWS CodeBuild or Jenkins. And then push it, into CodeDeploy and then into Fargate or something. With a monorepo, is you just have to retool your build scripts, your continuous integration, to say I want to just target a piece of this monorepo.
[00:02:46] And so it can be done. But that is the one thing you would need to be cognizant of, is that when you build, it needs to be on a per-project basis, not a per-repo basis.
>> Student3: Do you usually put services in the lib folder, or-
>> Lukas Ruebbelke: Typically, I do.
>> Student3: And I noticed, so I remember, we created the logging component.
>> Lukas Ruebbelke: Mm-hm.
>> Student3: Which I don't feel like we really use it. But I'm assuming you created that in the lib folder not in the project folder because that's something that could be used across multiple projects.
>> Lukas Ruebbelke: Ding ding, and so that's it, is if you ever stop and you're like hey, I could use this over here.
[00:03:34] That's a pretty good candidate for putting it in the lib folder. So a lib is essentially transproject, in other words, it can go from one project to another. And my hands got tired from generating all that code this morning which is why we didn't talk about the logging component too much, but that was the idea.
[00:03:58] Is that we could share that on a dashboard, or a widget, or whatever.
>> Student3: And let's say if you have another project list but that's slightly different than the one that you currently have, and you wanna reuse it that. Is there a way of kind of altering it or would you just have to create another project list and have it in the project folder?
>> Lukas Ruebbelke: So it depends on what you mean by project. Or you have a list that you need it to be different. What do you mean by-
>> Student3: I guess I'm-
>> Lukas Ruebbelke: Are we talking about visually different or are we talking about functionally it is just fundamentally different?
>> Student3: I guess I'm thinking in terms of some projects that I've done where we have.
[00:04:49] So we've developed applications and both of them at the end of the day seem to do pretty much the same thing except with different data.
>> Lukas Ruebbelke: Right.
>> Student3: So I guess in terms of, so it seemed pretty repetitive, the code that we're writing, except it was for different data sets.
>> Lukas Ruebbelke: Right.
>> Student3: So I was just wondering if there's an easier way of, I guess, kinda creating a component that could be used amongst different projects but it would have different data sets, I guess.
>> Lukas Ruebbelke: So one way that you could definitely do that is if the data sets converged or they overlapped on a common set of properties.
[00:05:35] Then what I would do is I would create an interface that covered or defined that intersection. You could also even create an interface with those properties in the optional, it could go here or there. With TypeScript, you can also do union types, but the idea is that you create an interface and you say, for instance, let's say you have a cat and a dog.
[00:05:59] They both have four legs, two eyes, fur, mostly. And so these are some common properties on both of these objects as you would create a let's say a pet interface. And now on the list, for instance, instead of saying this is a list of projects, is you could say this is a list of pet items.
[00:06:29] But then in terms of the instantiation, then you're passing in a concrete instance of a dog or a cat. Because a dog or a cat implements the pet interface, then you're programming to the interface and not the concrete instance. A very good book is Head First Design Patterns.
[00:06:51] And that's one of the first ones they talk about is composition pattern. Is that if you have a pretty similar interface or visual interface, but the data is slightly different, is you define a common interface. So when I said visual interface, I'm talking about UI. But then you define an actual interface that defines that data model, that both of them can implement.
[00:07:13] And then you type everything to the interface and not the concrete implementation. Does that make sense?
>> Student3: Yeah.
>> Lukas Ruebbelke: I mean, there's probably maybe some more details that I might change my answer if I knew precisely. But I would first start there and just say what is common and can I work around the common pieces?
>> Lukas Ruebbelke: And so typically what you do is you look what is common, you program to that. And then you notice where things are different and then you write the special cases around that.
>> Lukas Ruebbelke: All right, last question for the in crowd.
>> Lukas Ruebbelke: You wanna talk about building performance, AOT?
[00:08:01] How that's gonna change the world?
>> Student3: Yeah, well, lazy loading touched on that [CROSSTALK].
>> Lukas Ruebbelke: It's amazing, it works every time.
>> Student2: So I think that's the core issue of what I'm seeing in my project is the components To understand more,
>> Student2: How it decides,
>> Student2: What's loading and what's not loading when you're late in terms of lazy.
>> Lukas Ruebbelke: So the route will activate. If the route's activated, it will go and load that but-
>> Student2: Cuz you had the, in the route itself, you had the module name and then the hashtag, then the class module name within that hashtag. So does that make it a call to go fetch additional information from the server at that point?
>> Lukas Ruebbelke: Mm-hm, so what it's doing is it's saying go to this file, grab this module definition, and then load the rest of it.
>> Lukas Ruebbelke: So there is, with the Angular router, you can preload. And so if you just go Angular router preloading, there's some different ways you can do this.
[00:09:20] But is basically a preloading strategy. And you can do I wanna preload them all.
>> Lukas Ruebbelke: Or you can specifically say I want these a la carte. And so lets say you know for a fact that 95% of your users is going to use 3 out of your 33 modules.
[00:09:42] But then I would say take Bootstrap, the first module, and make it a light as possible to get that login screen. Behind the scene, then I would preload the three modules and lead up to that. And then from there, lazy load everything else. Especially given the number of permutations and possibilities that you have.
>> Student2: Right.
>> Lukas Ruebbelke: Or definitely, even though you are on mobile, you're not gonna want to frontload everything. Especially, if you're paying per module, that make no sense. So you need to turn things on or off.
>> Student2: Okay, yeah, I think I have a better understanding of how that works now.
>> Lukas Ruebbelke: Awesome.
>> Student2: Yeah, thank you.
>> Lukas Ruebbelke: Mark, you got half your hand in the air. Now it's in the air. What do you got for me, bud?
>> Student: What is the difference between the tsconfig.app.json and tsconfig.spec.json?
>> Lukas Ruebbelke: Well, let's take a peek.
>> Lukas Ruebbelke: tsconfig.spec.json.
>> Lukas Ruebbelke: Well,
>> Lukas Ruebbelke: So one is how your TypeScript is configured for testing.
[00:11:03] So notice, we're saying for the spec here's jasmine.
>> Lukas Ruebbelke: Also it's saying include any spec file. So this is specific to testing. And then in your tsconfig,
>> Lukas Ruebbelke: It's slightly different. In this case, it's saying, for the regular tsconfig.app, it's saying ignore all the test, so exclude test and spec.
[00:11:31] But then if you look in the spec, then that on the other hand is saying give me the test. So you're just simply saying this is how I wanna configure my app and this is how I want to configure my test. Because when you go to your app, in most cases, you don't want to include the test and vice versa.
>> Lukas Ruebbelke: So one is for testing, one is for actually the application.
>> Student3: Isn't it advisable to when you're to do test-driven development, where you first write the test out and then develop?
>> Lukas Ruebbelke: There are people that would say you're not even a programmer if you don't do test-driven development.
[00:12:12] That I do not fall into that category simply because it depends on what you're doing. For instance, what if you're doing a proof of concept? You haven't even validated the feature set. It would not makes sense to say I'm gonna build this proof of concept and then I'm gonna basically write a bunch of tests along the way.
[00:12:37] The unit test at that level is not the appropriate level of test, or the appropriate kind of testing. If you're doing a probe, so I do believe in test-driven development, but the right kind. So if I'm doing a proof of concept, it certainly is test-driven, as in user test-driven.
>> Lukas Ruebbelke: Now once I validate the feature set or the functionality and I'm putting it into production, you better believe that there's going to be test. At least around the critical things. And then if a bug comes, then test on that. As well, is once you start to integrate into other systems.
[00:13:14] Well, then you're gonna have the integration test. And so it's you should always have test, but do I think a test needs to happen before you write the code?
>> Lukas Ruebbelke: I would say if that helps you be a more effective developer, then by all means. I personally would generally not do that.
>> Student: Especially in the UI code.
>> Lukas Ruebbelke: Right.
>> Student: It's never gonna happen, at least, not with the current tools. Perhaps maybe in the future. But the only time I've ever seen it being test-driven development actually be effective is on the API layer itself on the server but-
>> Lukas Ruebbelke: And the reason why that works is because it's model-driven.
[00:14:00] In other words, once you understand the model, you can infer the convention. And so it's very easy to write test on that because you know, hey, it's gonna be rest, or it's gonna be this. And it's pretty much set in stone as well as so, another example I heard, just to go the other way, is should you do test-driven development or even in terms of agile methodology?
[00:14:24] Do you just kind of, where does that go? Well, if you're doing front end Web application, you make it, something happens. Nobody's gonna die. But if you're doing embedded hardware in a pacemaker, then the stakes are a lot higher and you may want to actually lead with that.
[00:14:44] So it's just understanding, I think you gotta be careful not to make these blanket statements, test drive everything. I think not. Yes, Mark?
>> Student: Is there a way in Narwhal to publish libraries individually so that we can use them in different projects located in separated repos?
>> Lukas Ruebbelke: Yes, so when you generate a library, there's a publishable flag.
[00:15:06] And what that would do is sort of set up the code so that you can actually publish that specific library. So that it can be used,
>> Lukas Ruebbelke: As basically as an MPM module.
>> Student: Do you typically put all of the apps in this same repo or separate it out like you're saying?
>> Lukas Ruebbelke: I would generally put,
>> Lukas Ruebbelke: All the apps for a particular, within a reasonable domain. So in other words, if I'm dealing with a client that has four front end applications, they will all go in the monorepo. And so one of the clients that I'm working with now, it's that situation where they have seven or eight apps that sit within the monorepo that share common functionality.
[00:15:57] But if I was in a large organization and you had this business unit over here that had no relation whatsoever over to here and they're using different technologies or something. Would I force that into a single monorepo? Probably not, but typically if I'm working on related projects that could benefit from shared functionality, I will and will put them all on a single monorepo, aka Narwhal workspace.