React at Scale with Nx

Rate this content
Bookmark

The larger a codebase grows, the more difficult it becomes to maintain. All the informal processes of a small team need to be systematized and supported with tooling as the team grows. Come learn how Nx allows developers to focus their attention more on application code and less on tooling.


We’ll build up a monorepo from scratch, creating a client app and server app that share an API type library. We’ll learn how Nx uses executors and generators to make the developer experience more consistent across projects. We’ll then make our own executors and generators for processes that are unique to our organization. We’ll also explore the growing ecosystem of plugins that allow for the smooth integration of frameworks and libraries.

160 min
01 Jul, 2022

Comments

Sign in or register to post your comment.

Video Summary and Transcription

Welcome to React at Scale with NX. NX provides benefits such as faster command execution, controlled code sharing, consistent coding practices, and an accurate architecture diagram. The workshop covers various topics including workspace setup, library creation, code splitting, API integration, and testing with Storybook and Cypress. NX offers functionality such as caching, Nx console, and Nx cloud, and provides a dependency graph for visualizing project dependencies. Troubleshooting tips and workspace generator creation are also discussed.

Available in Español

1. Introduction to React at Scale with NX

Short description:

Welcome to React at Scale with NX. In this workshop, we'll introduce you to NX and the benefits of using a monorepo. A monorepo is a repository that contains multiple applications, allowing for atomic changes, easily shared code, and a single set of dependencies. Atomic changes enable you to make a change and see its effects across the entire app immediately. Sharing code becomes easier as you can export and import functions within the monorepo. Having a single set of dependencies ensures that all applications stay up to date and reduces the lag in the development process.

All right, everyone. Welcome to React at Scale with NX. Yeah, let's go. And so my name is Isaac Mann. I am an architect at Narwhal. I've been here for three and a half years. And, Zach, you want to introduce yourself?

Sure, as I find the mute button. I'm Zach Derose. I've been with Narwhal going on four years now. I am a senior engineer and engineering manager, like Isaac, and, yeah, looking forward to sharing this NX knowledge with you all. So, yeah. Yeah. So, yeah, Zach and I joined like two weeks apart. So you can see how like Zach's the optimistic one. So he's almost four years. And I'm saying, well, more than three years. So glass half full, glass half empty. Yeah, I guess so. I'm sorry I didn't hear your spiel because I'm like writing in the chat. But, yeah. That's funny.

Yeah, so we are going to give you an intro to NX today going through a workshop that normally we have this workshop set up for a two day workshop. We're going to be going through a one day of it, the first day. And normally it takes about six hours, but we're going to just try to get through it however much we can in three hours. So basically what that means is we'll be cutting down the space that we'll give you to do things on your own. So I'll be running through things, the lab, and giving you some space for questions. But we're not going to be pausing for 10 minutes at each lab to have you do everything on your own. But the repo is linked in the chat. So if you feel like I'm going too fast, it's there and you can go through it at whatever pace you want when you do it later. A few notes just to, I guess procedural notes. So we want to make sure that this a friendly environment that everyone feels welcome and included. So that includes any life choices that people make and any technical choices that people make. So no shaming people for what they choose to do with their life and no shaming people for what technologies they use at work. So that's right. And we will not shame people for using IE, even though it is being phased out, I think, this week, tomorrow? I don't know. It's a big celebration happening. Yeah, today. All right. OK, anything else and I'm missing, Zach, before we dive in?

Nope, just a reminder, though, to anyone new, I've been saying this a lot, but I'll be in chat. So let's use the Zoom chat if you have any questions as we go. I'll answer things as I can. And if it's appropriate, we'll interrupt Isaac to go over some stuff as he's screen-sharing. So yeah, cool. All right. I'm going to share my screen, and share my full screen here. And we're going to be going through some slides. All right, so this is React at scale with NX Monorepos. And one thing that we should start out with is kind of defining what a monorepo is, and why you'd actually want to use a monorepo. So a monorepo is a repository, usually a Git repository, where you have multiple applications in the same repository. And so the benefit of coding in that way is that you get atomic changes, you get more easily shared code, and you can get a single set of dependencies. So let me back up a little bit. There are two kind of flavors of monorepo that you can get into. There's the Google style monorepo, for lack of a better word, where there's lots of tooling and lots of things to help you share code better. And then there's kind of like the learner style or very light touch, less tooling. And we'll get into that a little bit later with the, I think we call it code co-location sometimes. But NX can help with both. But during this workshop, we're going to be talking about the Google style, which has a single set of dependencies, one package JSON at the root. Whereas the learner style is you've got lots of package JSONS with different dependencies for each application in your repo. So we're going to be focused on that Google style for this workshop. But at the end, we could do a demo of what NX would look like in that in the more learner style of monitor repo. We've got these three things that a monitor repo gives you, atomic changes, shared code, and a single set of dependencies. Now let's go into what each of these things mean. So atomic changes are, say you have an app and a library and your repo. Actually, in this case, we have in two separate repos. So you have the app in a UI library. If you have it in two separate repos, then say you make a change to your library and it breaks some behavior in your application. So the library author makes a change, publishes it. The app developer at some point later updates to the latest version of the library. And they realize, hey, this is broken. We can't use this next version of the library. So they tell the library dev, OK, they file a bug. You need to fix this. And then later on, the library dev comes back and they say, OK, I got to fix that. They make the change. They publish a new version. And then later, the app dev updates to the next version of the library and say, OK, it's finally fixed. So that's the long cycle time if you have them in two separate repos. If they were to be in one repo, then the library dev, when they make the change, they could run the tests for the whole application, the whole repo, and say, oh, wait, this change that I'm about to make, it breaks this other app so I'm going to fix it right now. So you got a cycle time of 45 minutes instead of a week. So that's the benefit of an atomic change. You make one change, and you can see the effects of it immediately across the whole app even before you make a commit. The other second thing is, it's easier to share code. So say you've got a function called username is valid, and this logic is used in lots of different apps, if you have a monorepo, sharing that code is as easy as exporting a function and then importing it somewhere else. And anytime you change that logic, it immediately takes effect across your whole repository. Whereas if you have separate repos, you got to version things and republish them, and you got that whole cycle time, that lag in your development process, just like I said with atomic commits. A third benefit is having a single set of dependencies. So often if you have multiple applications, there's always going to be some applications that you're developing on all the time that are going to be on the latest versions of things. And there are going to be some applications that you just touch occasionally and they always get left behind. And so updating them and moving them forward is a pain because they inevitably, they get six versions behind and you have to remember all the things, all the problems you had to solve for the last year when you were updating things, you have to go back and relive them all over and over again as you're updating this old application. Whereas if you keep everything on the same version, then you just make that change once and you just do it across your whole application.

2. Benefits of NX

Short description:

NX helps with faster command execution, controlled code sharing, consistent coding practices, and an accurate architecture diagram. It eliminates problems with code co-location and provides benefits such as faster command execution, controlled code sharing, consistent coding practices, and an accurate architecture diagram. NX allows for faster command execution, controlled code sharing, consistent coding practices, and an accurate architecture diagram. It addresses the drawbacks of code co-location and provides benefits like faster command execution, controlled code sharing, consistent coding practices, and an accurate architecture diagram.

You say, okay, every time I see this code pattern, I do this fix on it and you do it one time and you're done with it. Whereas instead of having to do it now and then two months from now and then six months from now for all the different applications you're looking at. The other thing that single set of dependencies helps with is if you're doing like a, what is it called? Micro fund-in kind of approach, you have to have things on the same version otherwise you'll get weird bugs with like a React 16 library trying to be injected into a React 17 application and things are confused about what a singleton of a certain instance is or whatever. So having a single set of dependencies just eliminates that whole class of problems.

All right, so Code Co-location is what you would do if you were just to dump multiple applications in the same repo without any tooling around it. You just drop it in and you say, it'll be better, we'll be able to share our code and it'll be nice. But here are the problems with that. The time it takes to run tests will grow exponentially. You have trouble having code boundaries and keeping things contained and not have spaghetti code. And then you'll have inconsistent tooling when you're trying to manage your code base. So running unnecessary tests.

So let's say you have a homepage that depends on a UI library. If you were to change the homepage then you only need to run the test for the homepage. You don't need to run the test for the UI library because there's no way a change to the homepage could break the UI library cause that's just the way the dependency goes. But if you don't have the tooling that understands that you won't know which tests you have to run. So you end up, just running the tests for everything anytime you make any change. And that makes the time your CI takes grow exponentially with the number of things you add in because every app you add just adds more tests that you have to run no matter where that change is made. Even if you're making changes to one app that has no dependency on the other you have to run the test for everything just to make sure that you didn't break something by accident.

And obviously this is a very small example. You could tell just by looking at it if you need to run tests for something or not. But your dependency graph is gonna look more, something like this, this is even a really small repository. Any moderately sized company you'll have hundreds of nodes in this graph once you get working on things. So at that point you can't just know as a person just by understanding the code to know what tests really need to run, you need to have some tooling that will do that for you. So you need to know that when you change the CartPage library, you need to know that the tooling can tell you that you need to test the Cart app and then the Cart End-to-End app because those are the things above it that depend on it. All right. You want to have code boundaries. So let's say you have something in your library that you only want to use internally to that library or you know that it's going to change and you don't want other people in other parts of the code base to be using this. So you could do things like, I know React does this sometimes, they have unstable or they prefix the names of things with warning messages to people to say, hey, don't actually use this, it's your own fault if you use this, this is going to change, it's going to break your code. And just to get people to not depend on things that aren't meant for public consumption. Whereas, so, you know, that's a problem with having code that's shared that way. Whereas if you have tooling that blocks you from making these deep imports, you can stop this problem before it even happens.

All right, the other thing is inconsistent tooling. So if you have lots of applications in your repo, you get the ballooning NPM scripts. And the format of those NPM scripts is based on the whim of the developer at the moment that they wrote it. Because they're always gonna have some random flag that nobody knows or expects. And you just don't even know how to do different things. So one application could be build. One application could be dev. One application could be a launch. And they all do the same thing, but if you're switching from one application to another, you have no way of knowing how to get going on it. There's no consistency in those scripts.

All right, so NX can help you to get the benefits of the Monorepo style of coding without the drawbacks of code co-location. So it helps by giving you faster command execution, controlled code sharing, consistent coding practices, and an accurate architecture diagram. So things that help with faster command execution, if you use Executors, which are basically like NPM scripts, but in a more structured NPM scripts basically. So there's tooling around them that helps you get like auto-completion and get some like graphical. So there's NX console that lets you like visually fill out all the options that are available. So the second thing is NX affected, helps you run the tests on things that are actually affected by a PR. So you can run tests or builds or any command only on the code that's affected by your change. So that speeds up your CI and your local development and you get local and distributed caching. So if you run a command a second time on the same code without changing the code, it's gonna be almost instant. It's gonna pull from the cache instead of running the command again. And then you can use distributed caching, which allows you to share that cache across your whole organization. So that's NX Cloud and it's a paid product. Although there's a large free tier for NX Cloud. So most applications it's just free. It's so when it get to a giant companies you have to pay some.

You get controlled code sharing with NX. You can have a defined API for your library and say, hey, if anyone's gonna use this library, these are the things you're allowed to use. If you try to reach into something I didn't explicitly export in this defining the API then it's gonna throw an error and you're not gonna, your code won't compile. You can set up tags to say which libraries and applications are allowed to depend on each other and say, these belong to this team and this whole set of projects belong to this team and they can't interact with each other. They can only depend on shared things. You can easily publish libraries to NPM and you can use something like the Code Owners file in GitHub, which requires an approval from a certain set of people for changes to a particular project, particular section in your repo.

NX also allows you to have consistent coding practices. There's linting, lint rules that help you determine which things depend on which other things and enforcing those defined APIs and libraries. Generators are basically scripts that allow you to create or modify code. There's special kind of generators called migration generators that update your code when you update versions. If you go from React 16 to 17, there's a migration generator that updates your config files to make sure that your code stays up to date along when you're updating your framework as well. So, NARL has a set of plugins that support different frameworks and tools, so, Angular, React, Express, Nest, Next, Cypress, Storybook, things like that. And then, there are also, so those plugins do things like set up your configuration for those tools, and they have the migration scripts to help you stay up to date as the version numbers bump up. And then community plugins, so things that NARL does not have out-of-the-box support for. There's a community where people write their own plugins for things like Vue and other things, and you can use those community plugins to help enforce those consistent coding practices.

All right, another thing that NX gives you is an accurate architecture diagram. So if you run NX graph on a repo that has NX installed, you can see what the actual code structure is of your repository, not what you wish it was or not what it was six months ago, which is usually what our architecture diagram is. It's what the code actually is right now and how the different parts of your code actually depend on each other. And so this is really used and this is a picture of an old version of the NX graph. We'll get into the common more up-to-date one, which it's a lot nicer. You can zoom in more and you can hover over it and see how different things are depending on each other. It's really useful. This is one of the, I don't know. One of my favorite features of NX is this dependency graph.

Okay, so this is how NX structures your repository by default. So if you go the lightweight NX setup, you can have it structured however you feel like. This is just the default. If you go all in with NX and you say, hey, NX, structure my repository for me, then this is what NX will do. But if you want to do the lighter weight version, then you can just add NX to your existing repo and not change your structure at all. But so we'll go through this one with the all in for NX setup. And then maybe at the end, I can show you how to use NX in a repo that's structured differently. All right, so NX has a, by default has an apps folder and a libs folder. So apps are anything that's like the, has an entry point basically, it can be deployed somewhere.

3. Introduction to NX and Workspace Setup

Short description:

Apps are deployable entry points, while libs are shareable pieces of code. The dist directory contains built applications, and tools are for scripts and generators. Workspace.json and project.json files configure NX. Tsconfig.base.json sets up aliases for libraries in the repository. Config files can be set at the workspace or project level. Plugins have executors and generators. Nx list shows installed and available plugins. Generators modify code, while executors perform other tasks. Custom generators can be created. Lab one creates a new workspace with a given name. Plugins can be added with yarn add. The Nx generate command runs generators. Custom generators can be created. Lab two generates a React app. Nx version shows the installed Nx version.

So apps are anything that's like the, has an entry point basically, it can be deployed somewhere. Whereas libs are anything else. It's like a shareable piece of code. So a lib could be like a page in your application or a lib could be a UI a UI library, or it could be like a set of utility functions. This is just a reusable, shareable piece of code. Dist is where the applications get built to, tools is for scripts, it could be the generators that we talked about or database scripts or anything like that. So workspace.JSON or in this workshop, we're gonna be using project.json files. This is just a config file for NX itself defining how the build system works, basically. Nx.Json has another config file, some settings for NX at the root. tsconfig.base.Json has some global TypeScript settings with the main piece in here is that it sets up aliases for different libraries in your repository. So you can import libraries in your repo almost like they were npm packages, but they're not actually deployed anywhere to npm. They're not published to npm, they're just within your repo, but you import them as if they were npm packages. All right, so for most of these config files you have a workspace level configuration and a project level configuration. So the workspace in this case would be a tsconfig.json and that inherits everything from the tsconfig.based.json. So anything at a project level inherits from the global. So if you want to change something across the board, you set it at the root workspace level. And if you want to change it only for that particular project, you change that setting at the project level. Same thing for jest configs, we've got a workspace level and a project level, jest config, and you can see you got ES Lint and some other things as well that are set up the same way. All right. So today we are going to go through these labs, lab one through 11 here in the repo. And yeah. So this is what lab one is going to be. Lab one is creating a new workspace so when you run MPX create NX workspace, that you give it a name and the name gives you three things. It sets what directory you're going to create this in like you're cloning a repo, what your path alias is going to be in your TypeScript imports. So you're at my org slash some project. So my org is the path alias. And then your MPM scope, if you were to ever publish, you know, something in a library in your repo actually publish it to MPM, that would be the MPM scope for it. Now all three of these things you can set to something else if you want to. But this is just by default when you create a new workspace, these three things are set to the same, to the same string. And then later on, you can obviously change them. All right so this is the repo that we're working from NX React workshop and I'm gonna click on, yeah so feel free to work along with me if you want. If not, you can just watch. It is totally up to you. So you want to, this lab, the steps are to, we want to generate an empty NX workspace for a fictional company called the Board Game Horde. So I'm going to pull my US code over here, and so we wanna do, I'll set this up this way. All right, so we want to make the npx create NX workspace, and we're gonna set it to Board Game Horde so it's important to have this, use this exact string here, if you don't, some of the code we copy and paste later won't work, you'll just have to update that. So when you run that you get different options here, apps, NPM, TypeScript, you could set something up with a React application pre-created for you, a bunch of other things, you could do a React and a Express setup, but we're gonna do this apps one, the top one. Apps and we're doing no for NxCloud. Now I'm gonna skip out of that because I already did it and we don't wanna wait for NPM to install dependencies, but this is, I've got a bunch of folders in here that are things I did later. There we go, so that's what a new, there we go. So this is what it should look like. Move that just, okay. And that should be, okay. So this is what it looks like if you run that command, you'll have a Workspace.json, which is empty, it has no projects in it. Nx.json, which has a few options in here. You can see here's the NPM scope. If you want to change that, this is where you would change it. This says what your default base branch is. So it could be main or master, or whatever you have, developed sometimes, people have for that. And then some other options in here, we'll get into these more later. This is set up for Nx Cloud, which we'll get into later, and all this stuff we'll get into later. And I wanna show the TypeScript here, okay, so these are just the base TypeScript options here. All right, so that was lab one. So now you have a default Nx repo. So now let's go into plugins. Plugins are a collection of, they have executors and they have generators. So the difference between executors and generators, generators create or modify code, and executors do everything else. Executors can build or test or lint or deploy or basically anything else you can do to your code that isn't making new code, that's what executors are for. And so Nx list will give you a list of the plugins that are currently installed in your repo and some plugins that are available to be added. So a plugin, it's an NPM package. So you add it just like you would any NPM package. So you can do yarn add of the name of the plugin. And once it's been added, then you can, that should be called generators. Then you can run the generate command to run your generator, your codemod. It's what React calls them. So you run Nx generate, and then you give it the name of the plugin and then a colon and then the name of the generator that you're referencing in that plugin. And then whatever options that generator is looking for. In this case it looks for a name for the, so for the React application generator is just needs a name for the app. And then there are a bunch of other flags that you can set for this, the application generator as well. If you need help finding what the, setting the flags that are available, you can install the edX console VS Code plugin. And that lets you, it gives you a UI. So you can click and say generate, and then I want to generate an application, and then you can just fill out the form to set whatever flags you want for that generator. So we have plugins for all of these things, code generation to spin up React or Angular or Storybook or backend things like Node and Nest and Next, or like just helper tools like Cypress or TS Linux, things like that. Yeah, so you can also make your own custom generators. So we had a question about that already. And these are very helpful for encoding your specific organizations, like code structure, things that you do all the time. So everyone has a specific set of things they do when they make a new page in their application, specific ways that they set things up. And it's nice to encode those in a script rather than having a checklist that people forget step seven all the time or whatever. So just having a script that they run and it automatically does it the same way every time. That's a great thing to do. I have computers do things that they're good at and let people do things that they're good at. All right. So let's do lab two. All right, so I'll go down here, next lab. So we're going to generate a React app. So one thing, so when we run this, so if I run Nx ____ version, it gives me 14.3.1 is the version of Nx that I have. If you don't have Nx installed globally, this won't work. You'd have to do Npx Nx ____ version, or you could do, you know, install it globally. Npmi-g ____ nrl-cli, or you can just do Npmi-g Nx and that'll install it globally, and then you can, you don't have to prefix it with Npx every time. Okay, so Nx list, we talked about that earlier.

4. Installing React Plugin and Generating Store App

Short description:

In this part, we install the normal React plugin and the Material UI library. We generate a React app called Store and add a fake API.ts file. We also update the app.tsx file and copy game images to the assets folder. Finally, we serve the Store application in development mode.

Let me, let me just make sure I can see, so this is listing all the things that are installed, and those shouldn't be there. So let me, here, I think it's remove node modules, install. Okay. So I had done some prep work before this, and I was further along in our workshop, and then I just reverted to the beginning of my Git history and when I ran nxlist, it showed everything that I had in my node modules. Okay, so let's try that again. Nxlist, there we go. So this is what I expected to see. So all I have installed by default here, I've got the NW workspace, a linter, and some testing, just testing, and that's it, but we have some other plugins available to us and we're going to install the normal React plugin here. So these are ones provided by Narwhal and these are community plugins that other people have written and Narwhal doesn't maintain them, but they might be helpful for you. So you can take a look there and look at those.

So let's go to the next step here. So we're going to yarn add, we'll use MpMis. MpMi-S. I don't think you need the dash S, but maybe you do, I don't know. I will follow the instructions because I am dutiful. So we'll add the Narwhal React plugin here. And then for this particular application, we're also going to install the material UI library. Copy that. Okay. Quickly, while this is installing to Timothy's question, could you show the workspace file real quick, Isaac? Yeah. Timothy, if you're, so I don't know where you came in, Timothy, but the way that we're working through this is where in lab one we created our own repository. So we ran that command npx create nx workspace, and that's sort of the repository we're working with. I'll throw in the link to the lab again here, but we're using the repo on GitHub, mainly for our instructions for each lab. So let me drop that in. Yep. So this is a command that'll set up your repo for you. Yeah, yeah, yeah. Perfect, thanks, Isaac. All right, okay, so I've installed that, and I've installed MaterialUI. Okay, so now the Step 5 here is to use the normal React plugin to generate a React app called Store. So here, this link takes you to the, no, I guess it doesn't. Okay, we're gonna go to nx.dev, and we're gonna search for React Application, and that's what we want, normal React Application. So these are the docs telling us how to use normal React Application, and so you can read through that if you want to, or you stay on your, stay on the instructions here, and it'll tell you what to do. So you can do nx.generate, all right, it doesn't work on the dark background. All right, well, I know what it says in here. So I'm gonna do nx.generate, narl React, not ReCAD, not Application, and we're gonna call it Store, because it says here to call it Store, and it says make sure you add React Router and select SCSS as the style when asked. So we'll do this, so we'll choose SCSS, and would you like to add React Router? I'm gonna say yes. Okay. All right, so now let's look and see what that did. So that created this Store. It also created a Store End-to-End section, which we're not gonna do anything with that now, but later at the end of the workshop, we'll add some Cypress tests here. So it created the Store here and right now, there's very little going on there. And actually let me show you. Okay, well, before we update the code, I'm going to run NX Serve Store and jumping around a little bit. Let's see, 1200. So this is the default application that gets generated for you. It's got some links to documentation and things like that, but we're gonna continue with, we're on step six here. We want to add a fake API.ts file and this link here goes to the code that we're gonna copy. So let's copy the contexts, that's one out. And then, underneath source here, app store, here. Yeah, I'm gonna put it underneath source here. New file, fake. Ah. What is in here? New file, fakeapi.ts. Paste in the code that I copied. I'm gonna save that. And then, I'm gonna update the app.tsx file with code from here. Copy the contents. Paste that. And update the CSS. Copy contents. All right. Now, we'll go back to our instructions. So I'm not spending much time on the React specific pieces because our main focus is NX not React. Okay. So we put them in there. And then we need to copy the game images. So we'll move them from here. We need to copy the game images. It is not, so the guys. And that's all right. Yeah. That's and we want this one. Okay. So now we have, three image files here that we're going to put in under assets. One, two, three. Okay. So we've got those assets there. And now we're going to serve our, it's like our data, but I'll do it again. NxserveStore runs the store and development mode. And go back to... There we go. So this is our beginning application here. It doesn't do a whole lot yet, but it's got some styling for material, and it has some fake games that we can... All right. So I'm going to... commit these changes, I'll call it lab two. And if you get stuck, there's a solution file that gives you some hints on what to do. Okay, so we've done, we've used the React plugin to make a React app. Now we're going to dig into executors and what they are.

5. NX Executors and Build Configurations

Short description:

Executors in NX are defined in project.json files and have a structured format. To run an executor, you can use the nx run command followed by the project name, target, and options. The NX console plugin provides an alternative way to run targets. The build output is stored in the dist folder, and options for the build are defined in the project.json file. NX allows for different configurations, such as development and production, which can be customized with specific options. The cache in NX stores different settings for a week, allowing for easy switching between configurations.

So executors are defined either in a workspace.json. In our case, they're defined in the project.json files. And they look like this, they can have any name you want, just like NPM scripts. But they have a little bit of structure inside of them. If you look at the, if you look at the test executor here on the right-hand side, it has a builder or executor property which says which executor to use. And then it has an options object, which is going to be different based on which executor you're running. But in so in this case, it's pointing to where the JesConfig is stored and where the tsconfig file is. And so it's just kind of a structured way of setting up your, like the commands that you can run in your, in your project.

So to run an executor, you can do nx run and then you do the project name and then a colon and then your target, which is like build, lint or, or serve and then the options that go with that. So for it to serve my app, you do nx run my app serve. And then you can, you can shorthand that if you want to. This is the one I use most often. You do nx and then the target and then a space and then your project and then the options come after that. So nx serve my app, nx build my app and nx test my app. That's what I usually type in. Also, you can use nx console to, to run these and you get the same, same kind of form to fill out. I should show that, show that next. Alright. I will share my screen. Alright, let's go to lab three. Okay. So we're going to, we need to build the app. So to build the app, just like we were doing, we did nx serve store before to build it. We're going to do nx build store and it runs that nx build store. It's processing. And it's successfully ran the target. So the, the way nx knows what those names are and the way to look up those things. If you look here, there's this project.json file inside of app store project.json. And we've got this targets property here, underneath we've got build and serve, lint and test. So we can run nx lint store and run the linter against. We could run nx test store, this will probably fail. So unit tests haven't been updated. Yeah. As it could you demonstrate to, if you go to the project.json file, if you're using the NX console plugin, you'll also see these little text links at the top. You can use those to run the targets as well. Yeah, so these things, this comes from the NX console plugin here. So if you can just click this and that'll run nx build or serve, whatever. NX console itself is over here. So if I want to build something, I can click build and then click which project I wanna build. Or I can find the project and then click build here and run it. So it's multiple different ways. If you go here, it lists out a form that you can fill out with whatever other flags you wanna set on that. Okay, build there. So we should have a dist folder. Let's go look at that. Apps, so dist folder. So we've got App Store. This is the build output of App Store. And you built it. Objects, so we just did that. Okay let's see if we can find in here, look at the options under build. So it's using the Gnarl web pack executor. So it's using web pack under the hood, also using Babel. This is the output path where it gets sent. Use the index file. So this, assets option here. This is the folder where our assets, images are. And so that's getting copied over because we're setting this up here. So if we had other assets, we could put in the path to some other assets folder here, I don't know, images. And it would copy those over. And all these options are defined in the documentation for each plugin. Yeah. Cool. Send a flag to the executor so that it builds for production. I think I built for production by default. Let me see. The next build store. And you can see here, this is happening almost instantly because of the cache. So it built for production by default. So if you want to build for development, you can do dash dash configuration, development. And it'll build... So you don't have the the hash, the hashes on the files anymore because I built for development. If you look under dist here, the output is different. But it's nice. That configurations and that project JSON file too, I think. Yep. Yeah. So then we have two different configurations set up here. There's there's a development configuration and a production configuration. Both of these settings, both of these configurations inherit from the these are the global options. And then development takes these and overwrites them with these options. It's like doing an object out of sign. Same thing with production. It takes whatever's up here and then overwrites it with this, with whatever options are set down here. So you can set up however many configurations you want and development and production are not magic strings. You can have them be whatever string you want. Yeah, so I was going to show you that when we do the different configurations, it doesn't just cache the last thing that was put in. It caches it for a week, all the different possible settings. So I can go back and forth between things and they're cached. Okay, open the dist folder.

6. Introduction to Libraries and Folder Structure

Short description:

We have four types of libraries: feature, UI, data, and util. Feature libraries are for routes and pages, UI libraries for presentation components, data libraries for network interaction and data access, and util libraries for pure JavaScript utility functions. Feature libraries can import any of the other three, UI libraries can only import util, data libraries can only import util, and util libraries can only import other util libraries. It's recommended to have application-specific libraries in a folder named after the application and shared libraries in a shared folder.

We notice things are different and we can also see that there's this serve here. This serve executor, basically it takes this store build command. So it's whatever settings are set up here, it uses that and then it builds it in development mode. So it's actually serving it up. So if you wanted to change, whatever options you change up here will also affect the serve output down here. Oh. Okay. All right, now let's do... Okay, so we've made an application, now let's make a library. So in general, we have four different kinds of libraries and you can make, you can structure libraries however you want to, but these are some naming conventions that we found to be useful. So you have feature libraries, which are things like a route, like a page, UI library, is presentation components, just focused on just the UI, and then data libraries are focused on just interacting with, like doing, fetching stuff from the network or handling your local data access, things like Redux or however managing your store that way. And then we have util libraries, which are just like pure JavaScript utility functions that can be used by anything. Generally speaking, you'd wanna have, you have feature libraries only, feature libraries can import any of the other three. UI libraries can only import util, and data can only import util, and then util can only import other util libraries. So you make sure that you don't have a util function that imports from a feature library and things get confused and you have cyclic dependencies and things like that. Also structure your directories however you want to, but generally speaking, it's nice to have application specific libraries in a folder that's named after that application. So if we have libraries that are based on the, that are meant to be used in the store app to put them underneath a store folder underneath libs and things that are shared across multiple applications, you put them in a shared folder.

7. Benefits of Splitting Code in NX

Short description:

When deciding whether to create a new library or add code to an existing one, consider the benefits of splitting things out. NX provides caching, effective commands, and insights into code structure. However, be cautious not to go too far and create too many projects or libraries. Use your judgment to find the right balance. The dependency graph provides a visual layout of your code base.

Now, if, after you've put something, a library somewhere and you wanna move it somewhere else, it's easy to move things around with a generator and we'll get to that in lab nine. So don't stress too much about where you put things. Generally speaking, you have this debate about, should I, I have some new code to put in and there's this question of should I make a new library to put this code in? Or should I add it to an existing library? So NX is, the basic building block of NX is the library or the project. And so the more you split things out, the more NX can help you. The more caching will help you, the more the effective command will help you, the more the project graph can give you insights into how your code is structured. Now, obviously you can go too far with that. If you have 1,000 projects, your project graph is no longer helpful because there's too much going on. And you're, there's more configuration files than there are code files at that point. Or you have to, you know, you have to go to seven different libraries to accomplish any task. And so, you know, use your own judgment, but you know, if you feel like NX is not helping you as enough, or you're having too many cache misses, then you might wanna split things out more. And if you feel like, you know, it's hard to wrap your head around features because there's split across too many libraries, maybe you have too many libraries and you need to consolidate the code more. So it's a trade-off, and it's kind of up to you how much you split out and how much you combine together. So this is what the dependency graphs gives you, you know, visual layout of your code base. And we'll do a demo of that a little bit. Let's do Lab four.

8. Migration Scripts and Component Library Creation

Short description:

In this part, we learn about migration scripts and generators that help jump to specific labs in the workshop. We install the NxReactWorkshop plugin and run migration generators to migrate to the latest version. The migrations.json file contains instructions for running the scripts. We can choose to run all migration scripts or select specific ones. Lab 3.1 is optional and introduces the migration feature of NX. We create a component library called uishared in the libs store folder. We generate a new React component called header and use it in the app.tsx file. TypeScript may require a server restart to recognize the new library. We serve the project and see the header component displayed.

All right, over here. Lab four. Oh actually not Lab four, we have a little interlude, Lab 3.1. So if you would like to just jump to a specific lab in our workshop here, we have some migration scripts, some generators that will help you jump to a specific, a specific lab in our workshop. So the way to do that is if you run install, this is the development dependency, NxReactWorkshop. So this is a plugin, it's a very simple plugin, it has no executors, only generators. And you wouldn't wanna use this in a, it's a plugin only for this workshop. You wouldn't wanna use it in your production code, but, it's just not useful. And let's do, so we added that, and, then we're gonna run, actually, let's do all of the actual instructions, 0.0.1. 0.0.1.

Okay, so I'm installing an old version of this plugin, and I'm gonna show you what the migration generators look like. Okay, so let me, let me quit, three, okay. Okay, so then we wanna migrate the latest version of this plugin. And Nx has a, the command for doing this is Nx migrate, and then you give it the name of the plugin you wanna migrate. React, Workshop. And you can either do at latest, or that's, you know, at latest is the default. And what that does is it goes and fetches from npm the latest version of this plugin, and then it says, hey, are there any migration generators between the, what you have currently installed on your repo, and like starting from what you currently have installed and going to what is the latest on npm. And what it's going to do is, collapse this. It's going to create a migrations.json file, which is a set of instructions about which scripts it needs to run. So the reason that there's this step, it doesn't immediately run the migrations because in very large codebases, you might have, I don't know, 15 generators to run on an update and sometimes they don't always work automatically. And so you wanna be able to commit your changes. If you've gotten a few of the migrations done and not all of them done, you wanna be able to commit that migrations file and so you don't get super far behind in the pace of the main branch. And so you can commit it and you can run the scripts in multiple different PRs, basically. So this migrations file here has all the different migration generators that are in this package. And in our case, each generator is a particular lab or completing lab one, completing lab two, completing lab three. And if I were to run actually in the terminal, it tells you what to do. So I ran NxMigrate. You run npm install, and then you run NxMigrate, run migrations to actually run the scripts. So if I do my... What this will do, this will actually finish the whole workshop all the way through the second day, which I don't know if we actually want to do. I think we will skip step five here and go to step six, which is actually helpful. Step six is instead of running all the migration scripts, so we could manually edit this and say, actually, I only want to run through lab three, so I'm just gonna delete all those and just do these, one, two, and three. Or you can just do a single one, or you can run this generator here and run generate, and so NARWAL-NX React Workshop Complete Labs, and there's some different options, so I can do from lab one to, doing a dry run, showing me what's gonna happen, from lab one to lab three, and that'll do the range here, or I can do, I just wanna run the script for lab four, because I'm already up to lab three, I just wanna run the script for lab four to complete it, so if I run this, it didn't actually run the script, it just created the migrations file, and then to migrate it, we run this, the migrations.json is assumed, so you don't have to add that equals on there. So this, basically this generator updated this, and said only put the lab four script in here, and so if I run that, and it's migrate run migrations, okay, this has completed lab four for me. Let's go look at the steps for lab four to see what actually it did. This is lab 3.1, so basically this is a way of jumping to whatever step you wanna be on on the workshop. So lab four was creating a component library. So we did, said to create a new React library called uishared and to put it in the libs store folder. So let's see. So generator, so we do that. So it's inside of here lib store uishared. So basically what it did was NX generate, narwhal, React library, and then we call it uishared and then put it under the directory of libs actually of store. So that's the command that I ran to do that. Hey Isaac, sorry we have a question in the chat here from Timothy. For the stuff from lab 3.1, did we actually need to run that migration or if we missed that, can we just continue? Yeah, you can skip 3.1. 3.1 is optional. It's just to help people if you wanna jump to a specific lab. So, yeah. So it's completely optional but it is helpful to move around the labs if you want to. And it's also helpful to kind of introduce you to the migration feature of NX, which is, you know, it's a pretty powerful feature. Yeah, a lot of chat in the chat about the migration and how cool it is. So, cool. But yeah, sorry to interrupt. Go ahead, Isaac. Let me send the link out here again. Okay, so that was step two to create this store, Store UI shared. Then we're gonna generate a new React component. So instead of doing this from the command line, I'll do this using NX console just to show the different ways of doing that. So I'm just gonna type in component here and it gives me all the generators that have component in the name. So I want a create React component, this one, not a storybook story or a cypress spec. So I want that and we wanna call it header. So I'm not actually clicking run on any of these things because I already ran that script, but I'm just showing you what you would do to do it. So you do this and make sure that the generate component is automatically exported. So you wanna make sure that it is exported. You click that, make sure that's set to true. From the command line it would be. From the command line, you'd do the dash dash export flag. And so that would create this header, component. And then supposed to copy in this code which has already been copied in. So copy and paste this code from here. Make styles, all of this copied in there. And then we use that header component in the app.tsx here. So we're using it, we're importing the header from here. So this red squiggle here is because TypeScript has not caught up with the fact that the new library has been created. So if you run into that, if you do TypeScript restart ts server, that should fix that red squiggle there. Yeah, so that is fixed. That, and so here's the instructions on that. Now, why is that? Oh, it's lowercase h. So that should not be lowercase h. That should be uppercase h. Okay. And I need to fix our migration script. It's not, it's not copying it over correctly. All right. Okay. So now we've served the projects and C, so we should now have a, a header. So to serve the project, we do nx serve store again, and let's go here and refresh this. And there's our header. It is kind of squished because I made it small, but okay. That cat looks extra grumpy when it's squished in with him.

9. Dependency Graph and Utility Library Creation

Short description:

In this part, we learn about the dependency graph and how it shows the projects and their dependencies. We see how Nx can detect dependencies and how to manually define them. We also learn about creating a utility library called utilformatters and its defined API. The utility library is used to format ratings for games. We import the utility library and update the rating in the app.tsx file.

All right. I think that is the end of that lab. Oh, then let's, let's look at the dependency graph. That's a good idea. Good idea person who wrote the workshop. Nx graph. So type in the next graph. Oh, I think the word it's not. Sorry, go ahead. That's fine. All right. So type in Nx graph and it, it shows you what, what the projects are in your, in your repo. So this we've got the, some end to end tests, which we haven't written yet. We have the store application and then we have the, our UI library. And you can see the lines here are dependencies between the different projects. This implicit line here just means it's a manually defined dependency. The end to end test don't actually have a TypeScript import of anything in the store application. So Nx wouldn't know that there was a dependency there unless you tell it, tell it manually that there is a dependency. Whereas this line here, there is, if you click on it here, it tells you in this app.tsx folder file, there is an import from the store UI shared. The store UI shared project. And you can see it, it's right here. App.tsx. So this is the line that makes that dependency happen. And if I were to, let me comment this out. And so this won't build anymore, but we will stop this and I'll run Nx graph again and show all projects and look, there's no dependency. So Nx is smart enough to know when you actually have a dependency or not. All right, so that was lab 4. Lab 4. We can make this lab 4. Okay, so let's do this one more lab and then we'll take a break. All right, lab 5. So we have a UI library. Let's make a utility library. So this is gonna store just some functions or can store some like Typescript types would be another good example of a utility library. So if you see here, these ratings are kind of nonsense numbers. That's not what you would wanna see if you were actually at a store. So we're gonna fix the formatting of those and make a shared utility library that will add some formatting to those ratings. So we want the ratings to look like this, well, 1.9 out of 10, or 7.4 out of 10 instead of what we had up there. So let's do... We're gonna make a new library from the NARAL workspace package. So this library has nothing to do with React. It's just a pure JavaScript function. So we're gonna make a... Actually, this may not be right. So let me see if this is... We're gonna make a new library here. And actually, yeah, this is... we're gonna make a NARALJS library, because that makes more sense, because it's JavaScript. And we're going to call it, we're gonna call it utilformatters. So we're prefixing it with util- to communicate that it's a utility library. And then we're putting it in the store folder. So utilformatters. So here we've got this dry run happening. This is showing you what files would be created. But we want it to be inside of- we want it to be inside of libs slash store. We don't wanna be, we don't want it to be at the root here. We wanna update this directory folder here. So we set store there, let me see, okay yeah. That's, these are the locations that we wanna create these files. So if we're happy with that, let me just double check. Okay, we're gonna put it in there. We're gonna call it that. I think that's it, okay. So when we're happy, we click run here. And we can go here. And so we got UIShared and we've got util formatters. So inside of here we have store utilformatters. This is just the default. We want to get the code that we're gonna copy from here. So we're gonna do a format rating function. And we set it like that. And export everything there. Just so you know, so this index.ts file here this is the defined API for this library. So if we had, we'll get into this a little later I think, but if we had export const secret or call it don't use this equals two. And if we don't explicitly export that in here, actually that's not, let's see how to do this. So right now we're exporting everything from there. We could just do export format rating. Export format rating. So if we were to do this and somebody tried to try to use the don't use this constant, nx will throw a linting error and will say, hey, you can't, you can't commit this PR. You're using things you're not supposed to use. So this is our API here. Whereas if you do export star that says, hey, anything inside this folder is fair game. Yeah, that's fair game. So I've done that. Formatters, want to use it in your front-end project to format the rating for each game. So we're gonna do the import and then update our rating in app.tsx. Let's copy this. Apache.txt. FormattRating, and see where is this? FormattRating. Okay.

10. Adding Feature Game Detail and Back-end API

Short description:

We generate a new React library called feature game detail inside the store directory. The library is automatically added to the store app project. We update the routing to include the game ID in the URL. Each card in the app.tsx file is wrapped in a link to navigate to the feature game detail. We serve the project and check the styling. We add the necessary CSS declaration and check the server and dependency graph. In lab seven, we add a back-end API using the Express plug-in. We create a new app called API and set up a proxy for Store.

All right. We will serve this. Next serve store. Fresh. And our ratings are formatted. So that's working. And if we look at the NxGraph, show all projects, now you can see the store app is using both the UI shared library and it's also using the util formatters library. All right. All right. So we'll pause there. Lab six. So we're gonna make a route library or feature library. We're gonna... Right now we've got a list of all the games in our store. We wanna have a detailed view of individual board games. So we're gonna make a new React library and we're gonna call it feature game detail. We're gonna put it inside of the store directory and we're gonna set up some automatic routing for us. So let's do... Okay. So we're going to generate a library. We want it to be a React library feature game detail. And we want it in the store directory and the root app project, we're gonna call it store. So basically this is automatically adding the route to the store app project. Anything else in here that we want to set? Don't think so. I don't think we need to set that. This is generating a library with routes. This is if we wanted the library itself to have routes inside of it, but we don't need to do that. Yup, okay, so we're gonna run that. And see what it's created. So we've got that feature game detail. It created, so this for us and in our app.tsx it added these routes to the app.tsx for us. So it added some links and these routes and gave us this feature game detail. So we don't need this like page one and page two's routes in here. We just want this route. And I'll go back to the instructions here. So we made that change the routing to pick up the game ID from the URL. So we want to have the path include the ID in the URL there. So it's not there in this way. Okay, take my ID from there, populate the component with the provided files. So we want store feature game details. I'm gonna copy that. So now we're using the route parameter to specify which game ID we're showing. I'm gonna get the styles here. That's right here. Then let's see. Make clicking on each card in the app.tsx go to there. So we're gonna wrap the card with this link here. So in our app.tsx, so instead of having this link stuff here, get rid of those. And we want each card here. So link around like that. Move the card inside that link. And this key we don't need on the card anymore, we'll have the key on the link itself. So link to that and then key there. Yes. Okay, let's serve this and see if this works. Link. Let's serve store. Did it work? Some weird styling. But, looks like it's working, so it's updating this, this is the route down here. Let's see, why did that style do that? Did we need to update, did we miss a step? I'm gonna do that, TSX. Do we miss the SCSX? No, I got the SCS, this is just for the feature game detail. So, I'm looking to see if there is a, oh, here, we're gonna do some live debugging. All right. Yeah, turn that text declaration off I think. Yeah, right. Yeah, okay. I mean, it's just, there's just not a, weird, okay. Add that to our app CSS. where we need to do this right now it's just the heavy handed with it, let's just say, add a declaration you will never be able to learn it. There we go that's good enough. So we checked the serv and the dependency graph you can see the feature game details being referenced by the server. Good all right let's keep going.

Lab seven. Okay this is where it gets exciting. We're going to add a backhand API. So up until now we've we've just had one app in our in our repo and now we're going to add a new a new plug-in, the Express plug-in. We're going to make ourselves a backhand app. So we've been we've been serving up their game details for this fake API. We want to make it a real API now. Ok, great, a new app called API from the Express plug-in, and we'll call it and we want to set up the proxy for Store. Ok. So I'm going to use the next console to make sure I pick the right and make it an app. And see now, now we have Express as an option here, because I've just added it. Now express application, we're going to call it API and front end project here. What this does is sets up proxy configuration for us for development. if I run this, this front end project option creates... if I can find it... Oh, no, I think it's actually in here. Here, this file.

11. Setting Up API and Store Communication

Short description:

Here, we set up the API and the store to communicate with each other. We copy the code from the fake API to the appropriate location and update the ExpressMain.ts file. The API is now visible in the dependency graph. In lab eight, we wire up the front-end application to use the backend API, making real network calls. We delete the fake API file and update the app.tsx component to use the fetch function. We serve the API and the store simultaneously, with the API on port 3333 and the store on port 4200. We verify that the network calls are working correctly. We update the individual game detail view to use the backend API for fetching data. We also use the shared FormatRating function in multiple places. Finally, we serve the project and observe the changes.

Here, this file. Now when I run the store, when I serve the store, it will automatically proxy any slash API requests to this local host port so that when I serve... I can serve the API and I can serve the store, and they'll know about each other. Okay. Copy the code from fake API to here. Apps API source app game super repository. Okay. So you're going to copy this And go up to here to... We need to make that folder SourceAppGames.Repo repository.ts. Start repository.ts. Okay. So we copy that over and let me just look at this to make sure I copied it. Yeah, that's everything. And then we update the ExpressMain.ts folder or file to do this to use that repository. So it's just serving up the games and serving up individual games here. So, okay. So now we're not serving things yet, but just look at the graph here. You can see that we have an API. It's not connected in anything, but it's there. So let me save this. I think this is lab seven. I'll save this as lab seven. All right. So we've done that. We've done everything on here. Okay. Now let's go to lab eight. All right. Now we're going to wire up the front end application to use the backend API to make, actually to really make a network call and you know, something will actually show up in the network tab. Um, okay. So we're going to delete the fake API that Ts file. This that we've done step one. When you use fetch in the app.tsx component, so I'm going to click in here. So let's see where is fetch. Yeah, so here's where it's making a real network call. So we'll copy this. Stores, app.tsx. We should be able to see. Let's do that. The changes here. So we've got our data loading a state, we've got a use effect here. It's making a real network call and setting the statement comes back. Okay, so that's working there. We updated that. And then, so we're going to serve the API. And then we're going to serve the store at the same time but in a different terminal. So let's serve the API. Then nx serve store. So notice that the API is on port 3333. And our store itself is on 4200. So they, if you look at the proxy config, this is telling the store, if you go to slash API and look for this API on port 3333. So refresh this and moment of truth. Let's look at the network test. So this, it worked. Let's double check. It really is using the network tab and here we go. It's loading from the network tab. And if I click on an individual one, Maybe it doesn't make an extra network call for the individual ones, but, but it's really making a network call here. We have an API that actually works. Should look the same, you can see that it's making it a network call to slash games. Okay. So let's keep going. The front end server are being used different ports. Okay. Calling it through the proxy config dot JSON file. Okay, so now let's update the individual game detail view. You use. To instead of using the fake API to do its own fetching like this. So we'll copy this. Let's feature that was the game. Details TSX file. And just try running here. Okay, so we've got that. CSS. Why does it need different CSS? Oh, cause we're making the... Okay, so we're updating the, the GameDetail route to show more information rather than just the ID. Okay. We're using the shared FormatRating function in here. Um... Here. So now this is being used not only in the route app, but also in this library here. So this is a util function that's being used in multiple places. Okay. So now we're gonna serve it and we're gonna see what this looks like. So it's already serving. I can't resolve GameDetail module, that's... In sense... Okay. Store featured... Okay.

12. Sharing Code Between API and Frontend

Short description:

Let's continue with Lab 9, where we want to share code between the API and the frontend. We'll create a new library called util interface inside the API folder to encode the connection between the two applications. By using TypeScript types, we can ensure that both the API and frontend are updated whenever the game definition changes. Run the command to generate the JavaScript util interface library in the API folder. There is currently no difference between JS and workspace plugins. Make sure to run npm install and check that all NX packages in the package.json are on the same version. Once the library is generated, import it into the GamesRepository.ts file and use the interface in the code.

Let me refresh this. Okay so... So now, we have a detailed view down below. It's got a buy and a share button. More interesting things. So it's working! Hooray! Okay, I wanna show you the dependency graph here. Now that we have multiple applications. Yeah, I was like, after the dependency graph too, can you also show the proxy config a little bit? Yeah, yep. I can show that again. So we still have the API is off on its own. It's not importing anything from the store, it's not sharing anything. But you can see the game detail. Both the game detail and the store application depend on this storeUtilformatters library. So if we click on this link here, the app.tsx imports there and gameDetail.tsx imports, makes that link happen here. So, and then, yeah, cool. Yeah, and I can show you the proxy config file. So this is inside of the root of the store app. And it's just saying, anytime this application makes a request, that starts with slash API, instead of looking for it on local host 4200 or wherever this application's being served, I look for it on another local host 3333. And so this obviously is only for development. When you build it and serve it in production, you'd be copying your express app deployable into the slash API folder, and you'd be putting the store application in the root. So could you show the project JSON too just to show how we tie in that proxy config file too? Yeah! Yeah. So here, let's see, where is it? So here we go. So underneath serve, there's an option called proxy config, and it's just the path to that proxy config file. Yeah, and you'll notice too, sorry, Isaac, I just wanted to address Phillip's question because he was asking about it. If you go to that line, so that was added in lab seven, which was just recently. So when we generated the API application, we actually specified this store application was going to be using it, and that's what set up this proxy config. So it all got generated for us. We kind of glossed over it. Yeah, let me show you. This setting here, so when I made, I called it API, I'll make a new one called, well, I won't make it, but API2, and then you set the front end project here. And this is saying, hey, add a proxy config to the store. So this is- Yeah, I was just gonna say, you could see it in the dry run outputs to see what process you get. It's updating that file, and it's updating the... Well- It's not actually the project JSON because there already was the proxy config. So it just added a second proxy this time, but the first time it would have touched it too. So- Yeah. Sweet, thanks, Isaac. Sure. All right. Has anybody tried using the migration scripts to jump to a particular lab? I'm curious if that's been helpful for anyone. Yes, we will have a recording. Okay. Well, Timothy's giving it a try now, but we can maybe keep going. All right, we have an hour. Hopefully, I'm gonna get through Lab 11, and then I'd like to do a little demo of basically starting from an existing repo and adding little sprinkles of NX, which is basically what most of you will be doing if you have an existing repo at your work and you want to start adding NX to it. Okay, so let's do Lab 9. So, Lab 9, we want to share some code between, we're gonna encode the connection between the API and the frontend to say, hey, we've got this type of what a game, the definition of what a game is. And if that changes, both the API and the frontend need to change. So, we can encode that with some TypeScript types, and we can share those between the two different applications. So, whenever that changes, we can update those things. So, we'll make a new library called util interface. And we'll put it inside the API folder. And we'll end up moving it later, but we're gonna start with it there. So, generate a library. You can either call it workspace or JavaScript. I like calling it JavaScript util interface. That's what I wanted. And we'll put it in the API folder. Okay. I think that's all we need. Yeah. Now run that. And so now we have this API util interface here. And let's... Quick question in the chat, Isaac. There's a question though. What's the difference between JS and workspace? When you're choosing which plugin to use? Currently there's no difference. I think, I'm pretty sure there's no difference. We're in the process of moving things over from workspace to JS. So workspace is left in there as to keep people who are used to using workspace and have it still be there. Eventually, like theoretically, you could make libraries that are not JavaScript, that are... You could have Python code or C-sharp code in an X. And so then making a narwhal workspace library could make sense as something that doesn't have Babel or Jest or ESLint set up for it. Cause those don't make sense for other languages. But right now there's no difference. Let me paste in... Timothy, make sure you run npm install. And the other thing you can do to troubleshoot is double-check that in the package.json all your NX packages are on the same version. Sometimes we run into troubles with that. I think they just released this morning a new version of NX. And so they always do that. The day of a workshop they always release a new version and that makes running things problematic, but... They like to keep us on our toes. Yeah. That's more than likely what the problem is. Okay, so I pasted that in and we'll import it in here. GamesRepository.ts. So we're gonna use this new interface in our game's repository file. Our namespace. This is a great games.

13. Building the API and Moving the Util Interface

Short description:

Let's build the API and inspect the dependency graph. Our front-end store needs to share the game interface. We'll use the move generator to move the util interface to the root of the libs folder. We can do this using the NX console or the command line. The move generator updates the necessary files and references. After the move, we trigger a build of everything and check the dependency graph. Finally, we update the front-end app to use the shared types, and both the store and API are now using the util interface.

And let's build the API. Go and assign it here. Now, one thing that's interesting, you may notice this, is when I ran Nx build API, Nx put out this message that says it's waiting for one dependent project task to finish. If we look at our graph here, Nx saw that API depends on API util interface. And it said, oh, so before I build API, I need to build API util interface. And so it was trying to do that before it built Nx API itself. Curious. Yeah. So Nx API util interface does have a build command, which if it's just a TypeScript types library, that doesn't really make sense. So we could just go in here and delete that. Yeah. I think there is an option for when you run the generator for the library, you can specify it as buildable or not. That will create that build target. So if I take out those targets there and I run it again. And next build API. This time, it didn't display that message because it saw, even though it still depends on the API Util interface, there's no build target there. So it doesn't try to build it. But that can save you a lot of headaches if you're trying to build something and you don't realize that you haven't built a library. So where are we in our steps here? OK, so we've built that. Inspect the dependency graph. OK, our front end store keeps a list of games in the state, but it's currently typed to any, so we need to share that game interface. So now we're going to use the move generator. So we're going to move the util interface to the root. OK, the root of the libs folder. All right, we can do that. So let's run. So I like, so you can either do it from the command line, generate-nrwall-workspace-move, and then dash-dash help to figure out what the options are. Let's see, move. And then this is an example that moves libs my-feature-lib to libs shared my-feature-lib. So project my-feature-lib and then moves it to here. So you can do that. I like to use the next console. So I'm going to keep doing that. So, Isaac, we just recently added something into NX console 2 where you can right-click on a project in the file directory, and it'll be in the menu. In the file directory? Not even next console itself? Yeah, you can just right-click there. And at the bottom, it says move NX project. Move NX project. Oh, cool. All right. All right. We're going to do live. So that just brings up this is cool. All right. That's awesome. Yeah. Yep. So folder movement So for people watching, it's interesting because move is like moving things around not actually generating stuff. But it still fits, like, that mechanism of changing around source files in your repository. So what we're doing is move in a library. But we're still using the generator mechanism to do this. So that's why I'm just putting that there. Because this is more than just moving the folder. If you just move the folder, you'd have a lot of broken code, broken references to it. So this, you can see in here in this dry run, it's updating this other application over here. It's updating the TSConfig paths. And it's updating the workspace.json file. And in addition to actually doing all the folder move. So I'm going to run this. So it's taking APIUtilInterface and then moving it to just the root level util interface. This is the new name of it here. And you can see, make sure that it's. Did the lab want us to move it into Shared? Or was? No, well, the lab says, move it up to root. OK, you're right. Sorry. Maybe it's supposed to move it again. Yeah, I would expect to put it under Shared, but. But the instructions say to move it to the root. So, I don't know. Let's follow the instructions then. Sorry. I guess I must have remembered it wrong. So yeah, this is a good example of something that would make sense to put under a Shared folder. OK, so that's there. And let's just make sure. Well, let's see what else we have. Trigger build of everything and look at the dependency graph. So NxBuildAPI. So that still works. NxBuildStore. So it's building dependent projects there. So that still works. And let's look at the graph. Oh, I didn't update the store itself. So our front-end store does this. So we did the move. And then we want to, yeah, we didn't do step 9 here. We need to actually use these types in the front-end app. And NX was able to tell us that by looking at the graph..tsx, that's 1, data here is a game, okay we'll put this in here, good. So now if we do NX graph, there we go, so now both the store and the API are using this util interface. Ta-da! That's so cool, I love that.

14. Installing Storybook Plugin and Generating Stories

Short description:

In this part, we install the Storybook plugin and generate Storybook stories for the header UI component. We run the Storybook configuration generator and choose to automatically create Cypress Stories. We answer yes to all the prompts. We then proceed to lab 10.

So now, I don't know, I've spent enough time working in projects where you have the separate repository for the back end and whenever you change something, like what the request body looks like or what the response body looks like, it's like coordinating those across repos is, it's really difficult. So I love this piece of it, one place for the TypeScript interface is awesome. Yeah.

Okay. All right. So let's go through this. So let's look at the Storybook plugin, we're going to generate some Storybook stories for our UI component, the header UI component. Let me see, that was Lab 9, I think. And so we're going to do, install the narrows Storybook plugin. All right. And then we're going to run the Storybook configuration generator on the story I shared project. Book configuration. The React Storybook configuration that's what we want. Do that on why does it not? Store. Store you I shared? Yes. Yes. So that's the right name. This sets up some storybook configuration files for us. And we want to say yes, automatically create Cypress Stories. Automatically generate stories for us. And let's run this. Saying yes to all those questions. So if we ran it from the command line, there would be prompts saying, do you want this to be checked? And do you want this to be checked? And do you want this to be checked? Well, this is generating to Timothy. We just crossed into lab 10 actually. So you just click the next lab at the bottom of that file I just linked you.

15. Running Cypress Tests Against Storybook

Short description:

In this part, we run Cypress tests against Storybook. We start by serving Storybook and the UI shared component. We set up controls for the header component and demonstrate how changes are reflected in real-time. We then move on to Lab 11, where we run end-to-end tests using Cypress. We launch Storybook and Cypress, and run a Cypress test that checks if the header contains the expected text. We update the test to match the actual header text and verify that it passes. This approach provides a hybrid between unit tests and end-to-end tests. Finally, we conclude the workshop and discuss whether to proceed with Q&A or a demo of adding NX to a generic Lerna repo.

All right, so if I run this, I serve Storybook. Storybook stored UI shared. So I haven't even touched any of the config files and Storybook. So this is the BoardGameHoard header component. We don't have any controls set up. So let's do that. header.stories.tsx. So basically, we need to add title here. Actually, let's set it to default of BoardGameHoard here. And that's fine. And I think we're not actually using a prop of title in here. So let's set that up. And string. And props.title. And let's do, if it's not passing in anything, then we'll do title is go get only. This is just to show off what Storybook can do for you. So now we've got a control here. And as we type in, you can see that we've got our changes are being shown up here, as we're typing it. So that's pretty nice. That's pretty cool that you can view your components in isolation in Storybook. And let's see if we can take this a little bit further with Lab 11. So Lab 11 is running Cypress tests against your Storybook. So you can run. So the thing that's really nice about Cypress is that you're running tests the way your users actually use your application. But some of the difficulties of that is that you have to start at the beginning of your application. Or you have to work on your whole application at once. Like you see the whole screen at once, when maybe you just want to test just a component the way a user would work on that component. And so using. So there's either you could either do Cypress component test or you could do this kind of hybrid approach with storybook and Cypress. So let's run this. So let's see. So it starts off with running end to end tests. Index ETE Store UI shared. If I ran it like this it would run, it wouldn't actually show the Cypress test being run. So I'm going to add dash dash watch. So we can actually see Cypress launch. Go ahead and throw up a hand in the chat if you use Cypress. I'd be interested actually. Great. So when I ran the end to end tests it first, first it launched storybook and then it launched Cypress. So now I'm going to run this Cypress test. Because we're in watch mode, it brings up this window where I can click and run it. On the other screen. OK, so we're going to run this. And OK, so it's expecting this to contain the text welcome to header. So that's because we haven't updated our test at all. So let's do that. So in our spec file, we're going to add this. So this is not the unit test, which would be under lib store UI shared header. This is under the end-to-end test, which are under apps store UI shared end-to-end integration tests here. So we're going to. Where's that code I copied supposed to go? So we're going to do that site visit in the before each. That's where it's supposed to go. And then go ahead and do a test. OK. So this argument here, we're going to a particular URLs. And we're passing in that the title should have this string in the URL. We're specifying it that way. And then we're checking that the actual header itself has that string. So this string should match that string. All right. So now if we go to Cypress again, let's try running this again. It's passing already. It happened so fast. So we run it again and now it's passing because the text we put in matches. And if we were to change this, let's set this to 2. See. So it's still working. So this is just another approach to testing. Kind of an in-between between unit tests and end to end tests, which is pretty cool. Yeah. All right. So this is the end of the actual workshop itself. Zach, what do you think we should do? Should we do some Q&A now? Or should we do my demo of adding NX to just a generic Lerna repo? Yeah. It sounds like the chat is maybe pushing for the demo. I was almost wondering if maybe we could look at- we probably won't have time for those. There's been a lot of interest in generating our own Workspace generators. OK. But yeah, chat looks overwhelmingly for the demo. So let's do that. Maybe while you're getting that set up, let me hit some of the questions here in the chat. I was like, you might be able to help with this one. Nigar asks if we can remove plugins, if there is a command for removing an NX plugin. I didn't think there is one. Like I mentioned to him, what I normally do is just remove it from the package JSON file and then do the fresh install. And the install is gone. I didn't think we had a command for removing a plugin. Yeah, so you can remove it. That gets rid of it from node modules. But then you'd also want to make sure I do a global search for at Narwal slash the name, so that that'll show up wherever it's being used in executors.

16. Dependency Versions and Migration

Short description:

You can change the versions of dependencies like Storybook and Cypress, but there are no guarantees that they'll work. NX updates the versions for you, and sticking to the versions provided by NX ensures compatibility. However, upgrading TypeScript or your framework to the latest version may require custom migration scripts. NX is working on providing the best migration scripts for everyone. You can choose to go fast and handle the pain points yourself or wait for NX to do the work.

So you make sure you swap those things out before you delete it from node modules. But that's the only thing you'd need to do, yeah. Sweet, and yeah, Jose had a question for dependencies like storybook and Cypress. Do the versions lock to the version of NX you're using or can you change and use the first one you want? So yes, you can change, use whatever version you want where there's no guarantees that that'll work. NX does update the versions for you. And so if you stick to the versions of those packages that NX gives to you, then we can guarantee that they're gonna work together. But if you start bumping your TypeScript version, that's often the one that people wanna upgrade faster. You wanna upgrade TypeScript or you wanna upgrade your framework of React or whatever to the latest version, you can do that, but then you're going ahead of whatever migration scripts we have. So basically we're trying to, as we're maintaining it, we're trying to do those upgrades just like you are. And as soon as we've figured out the best way to do that and the best migration scripts for everyone, we're gonna publish those. So if you wanna go fast, you can deal with those pain points yourself. But if you wanna sit back and wait for us to do the work, you can do that too. Cool. We have more in-depth question here from David. But let's do the demo first and David we'll try to address that afterwards.

17. Installing and Configuring NX

Short description:

To get the benefits of NX's caching and graph, use Yarn workspaces or Lerna. Install NX without actually installing it by running NPX NX graph. Add NX to the package.json to make it work. The project graph shows dependencies between projects. You can exclude projects and group them by folder. Use NPX add NX to Monorepo to add NX to your package.json. NX Cloud allows caching commands across your organization. NX Console works without executors or project.JSON files. Some generators may not work, but custom generators can be created. Minimal changes are required to use NX. Run NX build to build projects.

Let's do install. So this is the Netlify CMS package repository here. You can see it's a learner json. It's got a learner json file. I know very little about this other than it's got a learner file and I ran a, I made a little video adding in X to it. But when I first got it, I had no background on this repository. It's not like it's custom made to be, to work well with NX or anything. But so basically, in order to get, wow, NPM install has taken a while. In order to get the benefits of NX's caching and the graph, that's very straightforward. That's really easy with, if you're using something like Yarn workspaces or Lerna. And whenever NPM finishes installing, I can show you how to do that. So basically, well, to install NX, to run the NPX, the NX graph, you don't actually even need to install NX at all. So I can run NPX, NX graph on here. And let me show you the package JSON of this, just so you know, I don't have any secrets. So there's no narwhal or anything in here. I'm not hiding anything. And so I'm just going to run NPX, NX graph here. And... Huh, I thought that worked. I tried that before. I thought there was an option you needed to pass it. Let me see if I can find it. Yeah, maybe it is. Oh. Whenever this finishes, we will. I'm looking up Victor's Twitter file cause that's the last place I remember. This was definitely there. Let's see. So maybe you just need to add in NX to the package.json. I know that'll work, if you add in NX to the package.json it should work. Okay. All right, MPM install is finished. MPX NX-graph, yeah, it still doesn't like that. Okay, so I'm gonna do MPMY-D NX. So adding NX as development dependency. Okay so I'll just add it. There we go. All right, so now all I did, the only changes are the package lock and package JSON. And it's now created, we can look and see what the project graph looks like for this repo. So it's kind of hard to see exactly what's going on. So it might be better to, let's click on one of these things. Let's look at, I don't know, maybe this one. And let's do a focus on that. So now now it's just looking at the projects that directly depend on this one. They're linked like one link away from this one. So you see Widgets file is dependent on by app and CMS widget. And then this one also depends on CMS UI default. One thing you can also do is you can do, you can take one step further and go two steps away. And now these are the projects that are available. And three steps away and four steps away, looks like two steps away as far as it goes. And you can also do this group by folder. Looks like they're all under packages. So that's doesn't really tell us that much. But yeah, so that's one thing you can do. You can also like manually exclude things. You can click on this and exclude it. So there's only three things now. So that's handy. And let's see, what else can we do? Let's run. Um, let's see. Now to use NX itself, if you run NPX, add NX to Monorepo. So this works on a, a learner repo and a Yarn workspaces. I think those are the two main things. Basically things that have packaged JSON files that define the, define the separate like projects. If I run that, that, that would, that also adds NX to your package JSON, but it adds another file as well. I think, I think it will add an NX.JSON file to the root here. So this, this is all without and you can choose to say yes or no to NX cloud. Sure we'll say yes. NX cloud, I haven't even demoed that. That's pretty amazing the first time you see that in action. So instead of just caching on your machine, you're caching your commands across your whole organization. So I run a build on my machine and then I want Zach to review my PR. He can check out the PR that I've pushed up to GitHub and he runs build on his machine and it's immediately an instant build because all that happens is he downloads the output of that build command to his machine. He doesn't have to run the build itself. Okay, so this is what just got changed. So it looks like we've got a yarn lock and a package lock, but basically NX.JSON is the only thing that's added. Package JSON just has this, it has NX and we added NX Cloud because we said yes to that. So just use NX.JSON file and now we can, oh let's see. Yes, NX Console even works. Okay, so we have no executors defined. Everything is still in NPM scripts. We have no project.JSON files, nothing, so none of the plugins that we talked about, like no normal React. So NX Migrate will not work. What else will not work? Most of the, a lot of the generators probably won't work. Like the libraries and application generators won't work but probably component generators, those would probably work. It's kind of hit or miss with those generators but you could make your own generators. That would still, that should still work, but anyway, very minimal changes here. It happens in five minutes and now we can run. Let's run build on, hopefully something that's close to the bottom here, NX build. And so this is running, this is running build on Netlify CMS lib widgets.

18. NX Functionality and Migrating to Plugins

Short description:

NX provides caching, Nx console, and Nx cloud. To migrate to plugins, copy an existing project.json file and update executors. The run commands executor lets you move towards a plugin setup. Install plugins to start using them. The run commands executor executes commands on the terminal. Set the current working directory in project.json. To get basic NX functionality, it takes five minutes and provides caching, Nx console, and the NX graph out of the box.

And there's nothing like nothing custom about this. I didn't even, I don't even know what command it's running. Something, let's see, cross M that it's running Webpack here and it took 4.7 seconds. If I run this again, click run again, this time it took 0.65 seconds because it was cached. And that's all with virtually no changes.

Let me look up the script here, CMS lib widgets here. Lib widgets. Yeah, I'm looking for the packages on. So basically it's running this script. This is the script that I just ran. So NX was able to find it and. Oh, sorry, there's a question in the chat. How was the NxJson file added? What was the command? Yes, the NxJson file was added by running npx add Nx to mono-repo. So yeah, and all that command does is it does an NPM install on Nx itself and it adds an Nx.json file. And you get caching, you get Nx console, you can do Nx cloud. You can get distributed caching that way. What else do you get for that? Yeah, those are the main things.

So then if you wanted to migrate this, like take advantage of some of the plugins, you could, let's see, let me see if this works. Well, I'm gonna have to do this kind of a hand-wavy and not actually do this. But you could make a project.json file. And probably what I would do is I would copy an existing project.json file. This is a bad example because that's a Cypress one. Let's do a, testament. I should get an app, probably. But anyway, you copy an existing one and then update your executors in here to use whatever you wanted to add in. And then you can like one at a time migrate projects over to using the plugins if you wanted to. Or if you didn't want to use the plugins, you could, and you just like this format of having things in the project.json rather than npm scripts, you could do npm script build. So I'm gonna copy this, project.json, I'm just gonna delete everything in here. Okay, so I'm gonna do, this is build, and narwhal workspace, there's a run commands executor here. And, and here, I'm just pasting in the MPM script. This should actually work here. That, okay, and now I'm gonna run, Netlify CMS lib widgets. Nx build netlify CMS lib widgets. Okay, it didn't work. Oh, narwhal workspace is not installed. Okay, so I need to install that. My dash D, at narwhals slash workspace. So this is, as you get, do more buying into Nx in the ecosystem, you wanna start using some of the plugins. You have to install the plugin first. What are we doing? So this, what this run commands does is just basically executing this command on the terminal. So it's essentially the same thing as the MPM script, but it's just in this different format here. And it lets you move more, if your goal is to move more towards the plugin kind of setup then this lets you get closer to that format. And you can do things kind of one at a time. So the other, I think this should work without a top level workspace.json file. Okay let's see if that works. Cannot find module. And, can that one还能不能 be installed? So this is the joys of the live demo. Is nx. Is that it's called? I just didn't want to install, yes. Okay, so there's one other thing I need to set in our project, Jason here, one of the options you can set the current working directory of the, and we want the current working directory to be this, copy over to path. Okay, so we want the current working directory to be here. So you need to be in this folder and then run this. Oh, come on. Module build failed. Okay, well, I'm gonna stop debugging this, but basically that's what, those are the steps that you would take. You go through one at a time and start to move things over. But to get the basic level of NX functionality working, it takes five minutes. And you get caching and you get, and you get your, your NX console and the NX graph working out of the box. So, so you probably can see my screen now, so I'm on the left side, I'm with the guy LAB10 guide and here on the left, the application with the current state at the end of LAB9, so I just follow there and yeah, I've already installed this. Okay. Okay, then I go to the console and go here and do something with storyboard. That one? Yep. So that one is opens. And store UI shared. And store UI shared into the project name. Yep. And everything else is already checked, so that should be fine. And then I hit run. Then take some seconds, copy this. And then it's changed. I think it's done. If you scroll down. No. It's we will run.. OK. But in theory it should work after that, right? So I mean. Yep. It should. OK. So close the terminal and paste in the command and hit Enter. Oh, this is a different error message that I had before. Did I miss something? I don't think so. Right. Okay, can you look at your file tree? Yes, here. Okay. No configurers should have been found in your configurer. Documents, Story, My Shared Story book. Can you look at the dots storybook there? Folder. Yeah, right there.

19. Troubleshooting and Creating a Workspace Generator

Short description:

Try deleting the dot storybook folder and run the generator again. If there's an error, check the root level package.json file and the node version. Use nbn use 16 if there are issues with version 17. Create a workspace generator with SCSS as the default CSS style. Set the CSS style to SCSS in the generator. Run the generator and check the generated files.

Yeah, right there. So nothing was created there, that's a problem. Let's do, try deleting that folder, the dot storybook folder. Yes. And then scroll up to the very top and delete the dot storybook at the very top there. Yep. So. And that's run this, the generator again. Okay, generate. It's already there you can just click run again. Okay. Okay, it would already exists. Okay. Go to, yeah, I guess you can just delete it. I would work or you can do in the, sorry, in the UI, the console UI, uncheck generate Cypress specs on the right hand side. There's some check boxes in that form over there. Okay, here? Yep. So yeah, uncheck that one, configure Cypress and uncheck generate Cypress specs. Okay. There you go. Let's try that. Okay. And now let's look inside of those dot storybook folders. Make sure that, yeah, that's, now you have things there. Okay. That's what, that's what should be there. Okay. Should I try it again? Yeah, try running an xstorybook. Ah, this looks, oh. This is actually the error that I got before, so. Module build failed. Digital envelope. Interesting. And here's the, all right. Okay. So let's try. Scroll to the bottom. Make sure, can you do an nx build store? Make sure that's that's working. There's, okay, that worked. Can you look at the root level package json file? Oh, package json. So no, this is actually the wrong one. This one. Yeah, let's make sure that all of the narwhal packages are 1431, it looks like they're all, those are good. Let's look at the root level package. Okay, that's fine. Okay, let me look at my version and see if there are any differences. I wasn't following the whole conversation, but people in chat are suggesting checking the node version. Oh yeah, no, we didn't. That's a good idea. So that could be. Okay, then let's nbn use 16. Maybe because I know there are some issues before with 17, maybe this will, solve the issue. All right, let me take that back. No 17 doesn't work with store. There's some praise for workspace generators, so. Okay. So if you're going to make a workspace generator, nx generate workspace generator, and I'm going to call it, let's say you wanna set that every time you make an application, React application, it's always gonna be SCSS. So let's do that. So my org app. So these are the settings that we always use for our organization. What is this? Looks like it's doing an npm install. All right. Let's, once again so I'll clear that up. All right let's try it again. OK well anyway, so when you run that generator, it makes this file here. And I'm going to use the narwhal. I'm going to import the narwhal react generators and I'm going to import the application generator. From there. And so it's just a function. An async function, so this tree is a kind of a in memory representation of the file tree. And then schema is the options that the user passes in at when they execute the generator. So I'm going to say I'm going to pass in the. All the schema options. But I'm going to see if we can. It should be there. I'm going to know react. Yeah, there we go application generator. And this schema. So this is the application generator schema for the built-in react application. Let me see if I can, let's go to interface schema. Okay, so that is not exploited anywhere. So I can't, I can't just use that. Well, I'm just going to do this. I'm going to copy this. Well, we'll just set it to any for now. Schema any, so we're going to paste in whatever schema and then we want to set the CSS style to SCSS. So no matter what they pass in, we're going to set the CSS style to, to CSS. Style, yeah, style, and I'm going to set the property to, to CSS because that's what we use at our organization. Then this format file step is just, runs the index format command, which just runs prettier basically, and this can run NPM install at the end if you update any packages. So we're going to try that.

QnA

Workspace Generator and Versioning

Short description:

The workspace generator allows you to pass properties defined in the schema.json file. You can run the generator using the Nx workspace generator command, specifying the app name. The API's tree function operates like a virtual file system, allowing you to make changes and preview the generated files before running the generator. The dry run flag displays the files that will be generated or updated. Versioning in a mono repo depends on the approach taken. The atomic commit philosophy ensures that all packages within the repo should work together on the same commit. Versioning is only necessary for packages published outside the repo. It is recommended to keep all packages in the mono repo at the same version. Troubleshooting in the workshop involves ensuring that all NX packages are at the same version. Thank you for attending the workshop.

And then the other thing is you have this schema.json file, which defines all the properties that you can pass in. And so in our case, our schema would be name, the string, because that matches the, that matches what was defined here. Let me check this. Why is it upset? Okay. So the application generator is expecting some things like skip format, unit test runner, ED test runner and linter. Well, here, well, we'll just sit this back to any and see if it, see if it complains to this.

So then, then to run our workspace generator, we run Nx workspace generator, whether it be my org app, and then give it a name. Can't find apps on that. Yes I do see that user. There's something is going weird in this repository for me, but I think I've created it. Apps API app store. No, it didn't create it. Okay, what's going on? Can't find apps on that user, I don't see. Does your PWD match your current workspace? I've had that happen to me recently with VS code. I think so. Okay. I think it was something with the I am doing weird things there. Okay, well, that is doing weird things. Let me try with andRhinoConsole here. So I can run generate. So this is like the basic task that is running here. It's just rendering. So this workspace generators shows up in the same place that normal generators do. And it even knows based on my schema file what properties I can pass in. You can see you pass in some app. And this is going to work? No, it has the same issue. Okay, I'll make the code simpler, I guess. Okay, let's see. Here we go. Okay, so it's executing it. And it's displaying some app. And if I could figure out why it's not working. It should be able to execute this generator and specify whatever applications. Maybe something weird with that. I bet what it is, it actually does require the things it says it requires. It's my TypeScript Any not really helping me. I know what I'm doing but I don't actually know what I'm doing. Nice. Yeah. So with the API for this, I actually find extremely nice too. Cause like the tree that gets passed into this function operates almost like a virtual file system. So like as you're doing these things, each one of those functions that we're importing here it's just like making one of those changes to a virtual file system that will show you. Yeah Isaac is using the API right now to just show how you would go about doing that. And what this supports is then you can run this with the dry run flag and it will actually, like we saw in VS code, the plugin for NxConsole, before you actually hit run, it'll actually tell you the files I get generated and the files that get updated and stuff like that. So it makes that piece very, very nice. So I just add a, I did a tree that write file to test.txt. And this is a dry run. So it's telling me it's going to make this file test.txt. And if I run it here, I ran it and there's our file that I just made. Cool.

I think this is unrelated Isaac, but there are some interesting questions about versioning. So Jose asks if you can see Jose's question there. It's kind of an interesting question, especially in light of the single version approach versus a Learner approach, if you wanna take the question. Yeah. So the learner style approach is you have multiple package JSON, you have package JSON for each project in your repo. And every time you make a change to a project, you bump the version number for that, and then other packages depend on it, right? Whereas the Google style is one of every project is made to should work with every other project on the same commit. So that's the idea of atomic commits. So if you're going to go with the atomic commit philosophy, then you say that at this commit for this repository, every package should be able to work with every other package. So if you go with that strategy, you don't have to worry about versioning. Versioning doesn't make any sense unless you're going to be publishing to npm for the projects that are outside of this repo. Then you version it and you publish it at that point. But projects within your repository, they should not need a version. They should just work with, if you're on the same commit, they should just work together unless you're doing the learner style and then you have to worry about those things. Yeah, so one interesting caveat to this too is the NX Workspace itself is using NX. And it's, we do publish that to an external repository, to npm. I actually have a little open source project for state management I run myself that does something similar. So the interesting caveat to this, if you are in something that looks similar, is oftentimes whenever I release the package or whenever NX releases the package, we bump every single package that we export, even if that one's not touched, because we wanna keep all those things on the same main version. So, yeah, I don't know, that may be helpful to your situation or it may not. Like in general, Isaac's answer makes the most sense for most of you I would expect. It's like, if this is your mono repo, this is your mono repo, so yeah. And bumping all packages is an interesting problem to ask this question. It's just a script, like you write a node script that does it. Yeah, yeah. Essentially you do that, but you have to bump that across all your package JSON's in the NX and then publish them and then bump the main version and stuff. So it gets a little weird. But NX, if you just check out NX's source code if you're interested and you can see how they're doing it. Yeah. So that's why when we're troubleshooting stuff in our workshop, you want to make sure that your, all your NX packages are all at the same version, because if they're all the same version, then they should all work together. But if they're off, then they'll start referencing things that don't exist in the other packages. Yeah, we're getting, I think we're over time here. Some people are trying to go to bed. Yeah. Thanks everyone for coming.

Watch more workshops on topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Featured WorkshopFree
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
React Summit Remote Edition 2021React Summit Remote Edition 2021
177 min
React Hooks Tips Only the Pros Know
Top Content
Featured Workshop
The addition of the hooks API to React was quite a major change. Before hooks most components had to be class based. Now, with hooks, these are often much simpler functional components. Hooks can be really simple to use. Almost deceptively simple. Because there are still plenty of ways you can mess up with hooks. And it often turns out there are many ways where you can improve your components a better understanding of how each React hook can be used.You will learn all about the pros and cons of the various hooks. You will learn when to use useState() versus useReducer(). We will look at using useContext() efficiently. You will see when to use useLayoutEffect() and when useEffect() is better.
React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
React Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
Featured Workshop
React Testing Library is a great framework for React component tests because there are a lot of questions it answers for you, so you don’t need to worry about those questions. But that doesn’t mean testing is easy. There are still a lot of questions you have to figure out for yourself: How many component tests should you write vs end-to-end tests or lower-level unit tests? How can you test a certain line of code that is tricky to test? And what in the world are you supposed to do about that persistent act() warning?
In this three-hour workshop we’ll introduce React Testing Library along with a mental model for how to think about designing your component tests. This mental model will help you see how to test each bit of logic, whether or not to mock dependencies, and will help improve the design of your components. You’ll walk away with the tools, techniques, and principles you need to implement low-cost, high-value component tests.
Table of contents- The different kinds of React application tests, and where component tests fit in- A mental model for thinking about the inputs and outputs of the components you test- Options for selecting DOM elements to verify and interact with them- The value of mocks and why they shouldn’t be avoided- The challenges with asynchrony in RTL tests and how to handle them
Prerequisites- Familiarity with building applications with React- Basic experience writing automated tests with Jest or another unit testing framework- You do not need any experience with React Testing Library- Machine setup: Node LTS, Yarn
React Summit 2023React Summit 2023
145 min
React at Scale with Nx
Featured WorkshopFree
We're going to be using Nx and some its plugins to accelerate the development of this app.
Some of the things you'll learn:- Generating a pristine Nx workspace- Generating frontend React apps and backend APIs inside your workspace, with pre-configured proxies- Creating shared libs for re-using code- Generating new routed components with all the routes pre-configured by Nx and ready to go- How to organize code in a monorepo- Easily move libs around your folder structure- Creating Storybook stories and e2e Cypress tests for your components
Table of contents: - Lab 1 - Generate an empty workspace- Lab 2 - Generate a React app- Lab 3 - Executors- Lab 3.1 - Migrations- Lab 4 - Generate a component lib- Lab 5 - Generate a utility lib- Lab 6 - Generate a route lib- Lab 7 - Add an Express API- Lab 8 - Displaying a full game in the routed game-detail component- Lab 9 - Generate a type lib that the API and frontend can share- Lab 10 - Generate Storybook stories for the shared ui component- Lab 11 - E2E test the shared component
React Day Berlin 2022React Day Berlin 2022
53 min
Next.js 13: Data Fetching Strategies
Top Content
WorkshopFree
- Introduction- Prerequisites for the workshop- Fetching strategies: fundamentals- Fetching strategies – hands-on: fetch API, cache (static VS dynamic), revalidate, suspense (parallel data fetching)- Test your build and serve it on Vercel- Future: Server components VS Client components- Workshop easter egg (unrelated to the topic, calling out accessibility)- Wrapping up

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Advanced Conference 2021React Advanced Conference 2021
39 min
Don't Solve Problems, Eliminate Them
Top Content
Humans are natural problem solvers and we're good enough at it that we've survived over the centuries and become the dominant species of the planet. Because we're so good at it, we sometimes become problem seekers too–looking for problems we can solve. Those who most successfully accomplish their goals are the problem eliminators. Let's talk about the distinction between solving and eliminating problems with examples from inside and outside the coding world.
React Advanced Conference 2022React Advanced Conference 2022
30 min
Using useEffect Effectively
Top Content
Can useEffect affect your codebase negatively? From fetching data to fighting with imperative APIs, side effects are one of the biggest sources of frustration in web app development. And let’s be honest, putting everything in useEffect hooks doesn’t help much. In this talk, we'll demystify the useEffect hook and get a better understanding of when (and when not) to use it, as well as discover how declarative effects can make effect management more maintainable in even the most complex React apps.
React Advanced Conference 2021React Advanced Conference 2021
47 min
Design Systems: Walking the Line Between Flexibility and Consistency
Top Content
Design systems aim to bring consistency to a brand's design and make the UI development productive. Component libraries with well-thought API can make this a breeze. But, sometimes an API choice can accidentally overstep and slow the team down! There's a balance there... somewhere. Let's explore some of the problems and possible creative solutions.
React Summit 2023React Summit 2023
23 min
React Concurrency, Explained
React 18! Concurrent features! You might’ve already tried the new APIs like useTransition, or you might’ve just heard of them. But do you know how React 18 achieves the performance wins it brings with itself? In this talk, let’s peek under the hood of React 18’s performance features: - How React 18 lowers the time your page stays frozen (aka TBT) - What exactly happens in the main thread when you run useTransition() - What’s the catch with the improvements (there’s no free cake!), and why Vue.js and Preact straight refused to ship anything similar