React Standalone Tutorial - Part 2: Project Graph

Run the command: npx nx graph. A browser should open up with the following contents:

Loading...

Nx creates the graph based on the source code. The projects are not linked in this diagram because we haven't actually finished our application. Once we use the shared components in another project, Nx will create the dependency in the graph. Let's do that now.

Set Up the Router

Install the react-router-dom package:

npm i react-router-dom

And configure the routes:

src/main.tsx
1import { StrictMode } from 'react'; 2import { BrowserRouter } from 'react-router-dom'; 3import * as ReactDOM from 'react-dom/client'; 4 5import App from './app/app'; 6 7const root = ReactDOM.createRoot( 8 document.getElementById('root') as HTMLElement 9); 10root.render( 11 <StrictMode> 12 <BrowserRouter> 13 <App /> 14 </BrowserRouter> 15 </StrictMode> 16); 17
src/app/app.tsx
1import { Cart } from '@store/cart'; 2import { Route, Routes } from 'react-router-dom'; 3import Shop from './shop/shop'; 4 5export function App() { 6 return ( 7 <> 8 <Routes> 9 <Route path="/" element={<Shop />}></Route> 10 <Route path="/cart" element={<Cart />}></Route> 11 </Routes> 12 </> 13 ); 14} 15 16export default App; 17
Typescript Paths

When a library is created, Nx adds a new Typescript path to the tsconfig.base.json file. The running Typescript server process inside of your editor sometimes doesn't pick up these changes and you have to restart the server to remove inline errors on your import statements. This can be done in VS Code from the command palette when viewing a typescript file (Command-Shift-P) "Typescript: Restart TS server"

shared-ui

Run the @nx/react:component generator with the command:

~/store

npx nx g @nx/react:component banner --project=shared-ui --export

1 2> NX Generating @nx/react:component 3 4CREATE shared/ui/src/lib/banner/banner.module.css 5CREATE shared/ui/src/lib/banner/banner.spec.tsx 6CREATE shared/ui/src/lib/banner/banner.tsx 7UPDATE shared/ui/src/index.ts 8
Nx 15 and lower use @nrwl/ instead of @nx/

Then create a simple Banner component in the generated file:

shared/ui/src/lib/banner/banner.tsx
1export interface BannerProps { 2 text: string; 3} 4 5export function Banner(props: BannerProps) { 6 return <header>{props.text}</header>; 7} 8 9export default Banner; 10

cart

Add the Banner component to the cart route and link back to the main page:

cart/src/lib/cart.tsx
1import { Banner } from '@store/shared/ui'; 2import { Link } from 'react-router-dom'; 3import styles from './cart.module.css'; 4 5/* eslint-disable-next-line */ 6export interface CartProps {} 7 8export function Cart(props: CartProps) { 9 return ( 10 <div className={styles['container']}> 11 <Banner text="Welcome to the cart." /> 12 <Link to="/">Continue Shopping</Link> 13 </div> 14 ); 15} 16 17export default Cart; 18

store

Update the shop component to use the Banner component and link to the cart.

src/app/shop/shop.tsx
1import { Banner } from '@store/shared/ui'; 2import { Link } from 'react-router-dom'; 3import styles from './shop.module.css'; 4 5/* eslint-disable-next-line */ 6export interface ShopProps {} 7 8export function Shop(props: ShopProps) { 9 return ( 10 <div className={styles['container']}> 11 <Banner text="Here is a list of products to buy..." /> 12 <Link to="/cart">View Cart</Link> 13 </div> 14 ); 15} 16 17export default Shop; 18

Now run npx nx graph again:

Loading...

Your graph now shows the dependency lines we expected.

The Project Graph is more than just a visualization - Nx provides tooling to optimize your task-running and even automate your CI based on this graph. This will be covered in more detail in: 4: Task Pipelines.

What's Next