React Nx Tutorial - Step 8: Create Libs
Libraries are not just a way to share code in Nx. They are also useful for factoring out code into small units with a well-defined public API.
Public API
Every library has an index.ts
file, which defines its public API. Other applications and libraries should only access what the index.ts
exports. Everything else in the library is private.
UI libraries
To illustrate how useful libraries can be, create a library of React components.
Run
npx nx g @nrwl/react:lib ui
You should see the following:
myorg/
├── apps/
│ ├── todos/
│ ├── todos-e2e/
│ └── api/
├── libs/
│ ├── data/
│ └── ui/
│ ├── src/
│ │ ├── lib/
│ │ │ ├── ui.module.css
│ │ │ ├── ui.spec.tsx
│ │ │ └── ui.tsx
│ │ └── index.ts
│ ├── jest.config.js
│ ├── project.json
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ └── tsconfig.spec.json
├── tools/
├── nx.json
├── package.json
└── tsconfig.base.json
The libs/ui/src/lib/ui.tsx
file looks like this:
1import './ui.module.css';
2
3/* eslint-disable-next-line */
4export interface UiProps {}
5
6export function Ui(props: UiProps) {
7 return (
8 <div>
9 <h1>Welcome to Ui!</h1>
10 </div>
11 );
12}
13
14export default Ui;
Add a component
Here, you can either change the UI component or generate a new one.
Add a component to the newly created ui library by running:
npx nx g @nrwl/react:component todos --project=ui --export
myorg/
├── apps/
│ ├── todos/
│ ├── todos-e2e/
│ └── api/
├── libs/
│ ├── data/
│ └── ui/
│ ├── src/
│ │ ├── lib/
│ │ │ └── todos/
│ │ │ │ ├── todos.module.css
│ │ │ │ ├── todos.spec.tsx
│ │ │ │ └── todos.tsx
│ │ │ ├── ui.css
│ │ │ ├── ui.spec.tsx
│ │ │ └── ui.tsx
│ │ └── index.ts
│ ├── jest.conf.js
│ ├── project.json
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ └── tsconfig.spec.json
├── tools/
├── workspace.json
├── nx.json
├── package.json
└── tsconfig.base.json
Implement the Todos component.
libs/ui/src/lib/todos/todos.tsx
1import { Todo } from '@myorg/data';
2import './todos.module.css';
3
4export interface TodosProps {
5 todos: Todo[];
6}
7
8export function Todos(props: TodosProps) {
9 return (
10 <ul>
11 {props.todos.map((t) => (
12 <li className={'todo'}>{t.title}</li>
13 ))}
14 </ul>
15 );
16}
17
18export default Todos;
Use the UI library
Now import Todos
into apps/todos/src/app/app.tsx
.
1import { useEffect, useState } from 'react';
2import { Todo } from '@myorg/data';
3import { Todos } from '@myorg/ui';
4
5const App = () => {
6 const [todos, setTodos] = useState<Todo[]>([]);
7
8 useEffect(() => {
9 fetch('/api/todos')
10 .then((_) => _.json())
11 .then(setTodos);
12 }, []);
13
14 function addTodo() {
15 fetch('/api/addTodo', {
16 method: 'POST',
17 body: '',
18 })
19 .then((_) => _.json())
20 .then((newTodo) => {
21 setTodos([...todos, newTodo]);
22 });
23 }
24
25 return (
26 <>
27 <h1>Todos</h1>
28 <Todos todos={todos} />
29 <button id={'add-todo'} onClick={addTodo}>
30 Add Todo
31 </button>
32 </>
33 );
34};
35
36export default App;
Restart both npx nx serve api
and npx nx serve todos
and you should see the application running.
Nx helps you explore code generation options. Run
npx nx g @nrwl/react:component --help
to see all options available. Pass--dry-run
to the command to see what would be generated without actually changing anything, like this:npx nx g @nrwl/react:component mycmp --project=ui --dry-run
.