ΠΠΌΠΏΠ»Π΅ΠΌΠ΅Π½ΡΠ°ΡΠΈΡ ΠΌΠΎΠ½ΠΎΡΠ΅ΠΏΡ
Π‘Π΅ΠΉΡΠ°Ρ Π±ΡΠ΄Π΅Ρ ΠΏΡΠΈΠΌΠ΅Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΡΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΈ Π΄Π²ΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ
- ΠΠ²Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ React: ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΎΠ΅ ΠΈ Π°Π΄ΠΌΠΈΠ½ΠΈΡΡΡΠ°ΡΠΈΠ²Π½ΠΎΠ΅.
- ΠΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° React Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ common-components, ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ, ΡΠΎΠ²ΠΌΠ΅ΡΡΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠ΅ ΠΏΡΠΎΠ΅ΠΊΡΠ°ΠΌΠΈ React
- Π Node.js ΡΠ΅ΡΠ²Π΅Ρ Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ backend
- ΠΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° TypeScript Ρ ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ ΡΡΠ½ΠΊΡΠΈΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ΄ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΠ΅ΡΠ²Π΅ΡΠ½ΠΎΠΉ ΡΠ°ΡΡΡΡ
Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ°
Π§ΡΠΎΠ±Ρ ΡΠΎΠ·Π΄Π°ΡΡ Π±Π°Π·ΠΎΠ²ΡΠΉ ΠΏΡΠΎΠ΅ΠΊΡ Ρ NX, Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ workspace, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Ρ Π½Π°Ρ Π±ΡΠ΄ΡΡ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡΡ ΠΏΡΠΎΠ΅ΠΊΡΡ
npx create-nx-workspace@latest <project>
Π£ Π½Π°Ρ Π² ΠΏΡΠΎΡΠ΅ΡΡΠ΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΌΠΎΠ½ΠΎΡΠ΅ΠΏΡ Π±ΡΠ΄Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π²ΡΠ±ΡΠ°ΡΡ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΡ Π΄Π»Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ° ΠΈ Π΄Π»Ρ ΠΌΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ ΠΌΠΎΠ½ΠΎΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ. Π‘ΡΠ΅Π΄Π° Π΄Π»Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ° ΡΠΊΠΎΡΠ΅Π΅ Π½ΡΠΆΠ½Π° ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ Π·Π°Π³ΡΡΠ·ΠΊΠΈ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ², ΡΠ±ΠΎΡΠΊΠΈ Π±ΠΈΠ»Π΄ΠΎΠ² ΠΈ CI/CD
ΠΠ°Π»Π΅Π΅ Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΏΠ°ΠΊΠ΅ΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ΄ΡΡ ΠΊΠΎΠ½ΡΡΠΎΠ»ΠΈΡΠΎΠ²Π°ΡΡ ΠΏΡΠΎΠ΅ΠΊΡΡ Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠΌΠΈ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡΠΌΠΈ (ΡΡΡΠ°Π½ΠΎΠ²ΠΈΠ»ΠΈ ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ Π² ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠ°ΠΊΠ΅ΡΡ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ Π½ΠΎΠ΄ΠΎΠΉ, ΡΠΊΡΠΏΡΠ΅ΡΡΠΎΠΌ, Π½Π΅ΡΡΠΎΠΌ, Π½Π΅ΠΊΡΡΠΎΠΌ ΠΈ ΡΠ΅Π°ΠΊΡ). ΠΠ°ΠΆΠ΄ΡΠΉ ΠΈΠ· ΡΡΠΈΡ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ² ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ Π΄Π»Ρ CLI ΠΏΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠ΅ Π½ΠΎΠ²ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ.
# Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡ nextjs ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅
nx add @nx/next
# ΠΡΡΠ³ΠΈΠ΅ ΠΏΠΎΠΏΡΠ»ΡΡΠ½ΡΠ΅ ΡΠ΅ΡΠ°ΠΏΡ
nx add @nx/react
nx add @nx/express
nx add @nx/nest
nx add @nx/node
ΠΠΎΡΠ»Π΅ Π²Π²ΠΎΠ΄Π° Π΄Π°Π½Π½ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΠΌΡ ΡΠΎΠ·Π΄Π°ΡΠΌ Π²ΡΠΎΡΠΎΠΉ ΠΏΡΠΎΠ΅ΠΊΡ. ΠΡΠΎΠ΅ΠΊΡΡ ΡΠΎΠ·Π΄Π°ΡΡΡΡ ΡΠ΅ΡΠ΅Π· Π²ΡΠ·ΠΎΠ² ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ° @nx/react
Ρ ΡΠ»Π°Π³ΠΎΠΌ :app
. ΠΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡ Ρ React ΡΠΎΠ·Π΄Π°ΡΡΡΡ Π² ΠΏΠ°ΠΏΠΊΠ΅ apps/admin
, Π° Π² apps/backend
ΠΏΡΠΎΠ΅ΠΊΡ Ρ Π½ΠΎΠ΄ΠΎΠΉ
npx nx g @nx/react:app admin
npx nx g @nx/node:app backend
Π§ΡΠΎΠ±Ρ ΡΠΎΠ·Π΄Π°ΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ Π΄Π»Ρ React-ΠΏΡΠΎΠ΅ΠΊΡΠΎΠ², Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ Π·Π°Π΄Π°ΡΡ ΡΠ΅ΡΠ΅Π· ΠΏΠ°ΠΊΠ΅Ρ @nx/react
Ρ ΡΠ»Π°Π³ΠΎΠΌ :lib
ΠΏΠ°ΠΏΠΊΡ Ρ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½ΡΠ΅ΠΌΡΠΌΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°ΠΌΠΈ. Π€Π»Π°Π³ :lib
ΡΠΎΠ·Π΄Π°ΡΡ ΠΏΡΠΎΠ΅ΠΊΡ Ρ ΡΠ΅ΠΉΡΠ΅Π±Π» ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°ΠΌΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΏΠΎΠ΄ Π²ΡΠ±ΡΠ°Π½Π½ΡΠΉ ΡΡΠ΅ΠΊ ΠΏΠ°ΠΊΠ΅ΡΠ°. ΠΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎ ΡΡΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ°ΡΠΏΠΎΠ»ΠΎΠΆΠΈΡΡ ΠΎΠ±ΡΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ Π΄Π»Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ
ΠΏΡΠΎΠ΅ΠΊΡΠΎΠ² ΠΈ ΠΎΠ½ΠΈ Π±ΡΠ΄ΡΡ ΡΠΎΠ±ΠΈΡΠ°ΡΡΡΡ ΠΈΠ· ΠΊΠΎΠ½ΡΠΈΠ³Π°, ΠΊΠΎΡΠΎΡΡΠΉ Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡΡ Π²Π½ΡΡΡΠΈ ΠΏΠ°ΠΏΠΊΠΈ lib/common-components
npx nx g @nx/react:lib common-components
ΠΠ°Π½Π½Π°Ρ ΠΊΠΎΠΌΠ°Π½Π΄Π° ΡΠΎΠ·Π΄Π°ΡΡ ΠΎΠ±ΡΠΈΠ΅ Π΄Π»Ρ Π²ΡΠ΅Ρ ΠΏΡΠΎΠ΅ΠΊΡΠΎΠ² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ
npx nx g @nx/js:lib functions
Π Π½Π° Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ ΠΌΡ ΠΈΠΌΠ΅Π΅ΠΌ ΡΠ»Π΅Π΄ΡΡΡΡΡ ΡΡΡΡΠΊΡΡΡΡ:
|__ apps
| |__ admin
| |__ admin-e2e
| |__ backend
| |__ backend-e2e
| |__ customer
| |__ customer-e2e
|__ libs
| |__ custom-components
| |__ functions
Π’Π°ΠΊ ΠΆΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΡΠΎΠ±ΡΠ°Π·ΠΈΡΡ Π³ΡΠ°Ρ Π²Π·Π°ΠΈΠΌΠΎΡΠ²ΡΠ·Π΅ΠΉ Π² ΠΏΡΠΎΠ΅ΠΊΡΠ΅
npx nx graph
ΠΠ°Π»Π΅Π΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΌ Π³Π΅Π½Π΅ΡΠ°ΡΠΎΡΠΎΠΌ ΠΈΠ· nx ΠΈ ΡΠ΄Π΅Π»Π°ΡΡ react-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ Π΄ΠΎΡΡΡΠΏΠ΅Π½ ΡΡΠ°Π·Ρ Π² ΠΎΠ±ΠΎΠΈΡ Π½Π°ΡΠΈΡ react-ΠΏΡΠΎΠ΅ΠΊΡΠ°Ρ
npx nx g @nx/react:component header \
--project=common-components --export
libs/common-components/src/lib/header/header.tsx
import styles from './header.module.css';
/* eslint-disable-next-line */
export interface HeaderProps {
text: string;
}
export function Header(props: HeaderProps) {
return (
<header>{props.text}</header>
);
}
export default Header;
Π‘ΡΠ°Π·Ρ Π½ΡΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ, ΡΡΠΎ Π²ΡΠ΅ ΠΏΠ°ΠΊΠ΅ΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ Π½Π° Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π²ΠΎ Π²ΡΠ΅Ρ Π½Π°ΡΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΡ . Π’ΡΡ ΡΡΠΎΠΈΡ Π°ΠΊΠΊΡΡΠ°ΡΠ½Π΅Π΅ Π²ΡΠ±ΠΈΡΠ°ΡΡ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΠΎΠ½ΠΈ Π±ΡΠ΄ΡΡ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ Π΄Π»Ρ Π²ΡΠ΅Ρ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ²
npm install axios cors date-fns
ΠΠ°Π»Π΅Π΅ Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΡΠ΅ΡΡΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π±ΡΠ΄Π΅Ρ ΠΈΠΌΠ΅ΡΡ Π²Π·Π°ΠΈΠΌΠΎΡΠ²ΡΠ·ΠΈ Π²Π½ΡΡΡΠΈ ΠΌΠΎΠ½ΠΎΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ
apps/admin/src/app/app.tsx
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import styles from './app.module.css';
import { Header } from '@myorg/common-components';
import { useEffect, useState } from 'react';
import axios from 'axios';
export function App() {
const [message, setMessage] = useState('');
useEffect(() => {
axios.get('http://localhost:3000/admin').then((response) => {
setMessage(response.data);
});
}, []);
return (
<div>
<Header text="Welcome to admin!" />
<p>{message}</p>
</div>
);
}
export default App;
apps/customer/src/app/app.tsx
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import styles from './app.module.css';
import { Header } from '@myorg/common-components';
import { useEffect, useState } from 'react';
import axios from 'axios';
export function App() {
const [message, setMessage] = useState('');
useEffect(() => {
axios.get('http://localhost:3000/customer').then((response) => {
setMessage(response.data);
});
}, []);
return (
<div>
<Header text="Welcome to customer!" />
<p>{message}</p>
</div>
);
}
export default App;
libs/functions/src/lib/functions.ts
import { format } from 'date-fns';
export function currentDate(): string {
return format(new Date(), 'yyyy-MM-dd');
}
apps/backend/src/main.ts
import express from 'express';
import { currentDate } from '@myorg/functions';
import cors from 'cors';
const host = process.env.HOST ?? 'localhost';
const port = process.env.PORT ? Number(process.env.PORT) : 3000;
const app = express();
app.use(cors({ origin: '*' }));
app.get('/customer', (req, res) => {
res.send(`[ customer ] ${currentDate()}`);
});
app.get('/admin', (req, res) => {
res.send(`[ admin ] ${currentDate()}`);
});
app.listen(port, host, () => {
console.log(`[ ready ] http://${host}:${port}`);
});
Π ΡΠ΅ΠΏΠ΅ΡΡ ΠΌΡ ΠΈΠΌΠ΅Π΅ΠΌ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ
ΠΠ°Π»Π΅Π΅ Π² ΡΠ°Π·Π½ΡΡ ΡΠ΅ΡΠΌΠΈΠ½Π°Π»Π°Ρ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°ΡΡΡΠ²ΠΈΡΡ Π½Π°ΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
npx nx serve backend
npx nx serve admin
npx nx serve customer
ΠΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ
Π‘ ΠΏΠΎΠΌΠΎΡΡΡ Π³ΠΈΡΠ° Π²ΡΠ΄Π΅Π»ΡΠ΅ΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π² ΠΏΡΠΎΠ΅ΠΊΡΠ΅
git add .
git commit -m "Initial commit"
ΠΠ°Π»Π΅Π΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°ΠΏΡΡΡΠΈΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΡ Π³ΡΠ°ΡΠΎΠΌ, ΠΊΠ°ΠΊΠΈΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ ΡΠΈΡΡΠ΅ΠΌΡ Π±ΡΠ»ΠΈ ΠΏΠΎΠ΄Π²Π΅ΡΠΆΠ΅Π½Ρ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡΠΌ
npx nx affected:graph
ΠΠ°Π½Π½Π°Ρ ΠΊΠΎΠΌΠ°Π½Π΄Π° ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΏΡΠΎΠΈΠ·Π²Π΅ΡΡΠΈ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° ΡΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ»ΠΈ ΠΏΠΎΠ΄Π²Π΅ΡΠΆΠ΅Π½Ρ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡΠΌ
npx nx affected -t test
Π‘Π°ΠΌΠΎΠ΅ ΠΊΠ»ΡΡΠ΅Π²ΠΎΠ΅ ΡΠ»ΠΎΠ²ΠΎ affected:
Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ Π»ΡΠ±ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ ΡΠΈΡΡΠΎ ΡΠΎΠ»ΡΠΊΠΎ Π½Π° ΠΈΠ·ΠΌΠ΅Π½ΡΠ½Π½ΡΡ
ΠΏΡΠΎΠ΅ΠΊΡΠ°Ρ
, Π° Π½Π΅ Π½Π° Π²ΡΡΠΌ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠΈ