@pplancq/react-template 2.8.17 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/_README.md +57 -52
- package/mise.toml +2 -2
- package/package.json +25 -24
- package/scripts/removeDemo.cjs +105 -66
- package/src/README.md +81 -0
- package/src/app/App.tsx +18 -0
- package/src/{bootstrap.tsx → app/AppHTMLElement.tsx} +2 -2
- package/src/app/README.md +69 -0
- package/src/{__tests__/bootstraps.test.tsx → app/__tests__/AppHTMLElement.test.tsx} +5 -5
- package/src/app/config/serviceContainer.ts +6 -0
- package/src/app/providers/Providers/Providers.tsx +18 -0
- package/src/{providers → app/providers}/QueryClientProvider/QueryClientProvider.tsx +3 -3
- package/src/app/providers/ServiceProvider/ServiceContext.ts +8 -0
- package/src/app/providers/ServiceProvider/ServiceProvider.tsx +14 -0
- package/src/app/routing/Router.tsx +14 -0
- package/src/app/routing/appRoutes.ts +3 -0
- package/src/app/routing/routes.tsx +9 -0
- package/src/demo/README.md +148 -0
- package/src/demo/application/dtos/ArchitecturePrinciple.ts +5 -0
- package/src/{types/profileTypes.ts → demo/application/dtos/ProfileFormValues.ts} +1 -1
- package/src/demo/application/use-cases/GetArchitecturePrinciplesUseCase.ts +11 -0
- package/src/demo/application/use-cases/GetArchitecturePrinciplesUseCaseInterface.ts +5 -0
- package/src/demo/application/use-cases/GetDemoUsersUseCase.ts +11 -0
- package/src/demo/application/use-cases/GetDemoUsersUseCaseInterface.ts +5 -0
- package/src/demo/domain/entities/DemoUser.ts +7 -0
- package/src/demo/domain/repositories/ArchitecturePrincipleRepositoryInterface.d.ts +5 -0
- package/src/demo/domain/repositories/DemoUserRepositoryInterface.d.ts +5 -0
- package/src/demo/infrastructure/repositories/HttpDemoUserRepository.ts +29 -0
- package/src/demo/infrastructure/repositories/StaticArchitecturePrincipleRepository.ts +33 -0
- package/src/demo/serviceDemo.ts +39 -0
- package/src/demo/serviceIdentifiers.ts +6 -0
- package/src/demo/ui/components/DemoFooter/DemoFooter.tsx +17 -0
- package/src/{components/Footer → demo/ui/components/DemoFooter}/__tests__/Footer.test.tsx +2 -2
- package/src/{components/Footer → demo/ui/components/DemoFooter}/__tests__/__snapshots__/Footer.test.tsx.snap +3 -3
- package/src/demo/ui/components/DemoFooter/index.ts +1 -0
- package/src/demo/ui/components/DemoHeader/DemoHeader.tsx +25 -0
- package/src/{components/Header → demo/ui/components/DemoHeader}/__tests__/Header.test.tsx +2 -2
- package/src/demo/ui/components/DemoHeader/__tests__/__snapshots__/Header.test.tsx.snap +64 -0
- package/src/demo/ui/components/DemoHeader/index.ts +1 -0
- package/src/{ui/molecules/Navigation/Navigation.tsx → demo/ui/components/DemoNavigation/DemoNavigation.tsx} +4 -4
- package/src/demo/ui/components/DemoNavigation/index.ts +1 -0
- package/src/{components → demo/ui/components}/TextInput/TextInput.tsx +3 -3
- package/src/{forms → demo/ui/forms}/ProfileForm/ProfileForm.tsx +7 -7
- package/src/demo/ui/hooks/useDemoUsersQuery/useDemoUsersQuery.ts +13 -0
- package/src/demo/ui/layouts/DemoLayout/DemoLayout.tsx +12 -0
- package/src/demo/ui/layouts/MainTemplate/MainTemplate.module.css +21 -0
- package/src/{ui/templates → demo/ui/layouts}/MainTemplate/MainTemplate.tsx +7 -7
- package/src/demo/ui/pages/DemoHome/DemoHome.tsx +117 -0
- package/src/demo/ui/pages/DependencyInjectionDemo/DependencyInjectionDemo.tsx +47 -0
- package/src/{pages/Demo → demo/ui/pages}/ReactHookFormDemo/ReactHookFormDemo.tsx +7 -7
- package/src/demo/ui/pages/ReactQueryDemo/ReactQueryDemo.module.scss +38 -0
- package/src/{pages/Demo → demo/ui/pages}/ReactQueryDemo/ReactQueryDemo.tsx +5 -4
- package/src/demo/ui/routing/demoAppRoutes.ts +6 -0
- package/src/demo/ui/routing/demoRoutes.tsx +31 -0
- package/src/main.ts +2 -2
- package/src/shared/README.md +53 -0
- package/src/shared/application/README.md +49 -0
- package/src/shared/domain/README.md +52 -0
- package/src/shared/infrastructure/README.md +51 -0
- package/src/{api → shared/infrastructure/http}/fetchApi.ts +1 -1
- package/src/shared/ui/README.md +50 -0
- package/src/shared/ui/hooks/useService/useService.ts +13 -0
- package/tsconfig.json +3 -1
- package/vitest.config.mts +5 -1
- package/src/api/README.md +0 -65
- package/src/api/demoApi.ts +0 -10
- package/src/assets/README.md +0 -54
- package/src/components/App/App.tsx +0 -18
- package/src/components/App/index.ts +0 -1
- package/src/components/Footer/Footer.tsx +0 -16
- package/src/components/Footer/index.ts +0 -1
- package/src/components/Header/Header.tsx +0 -17
- package/src/components/Header/__tests__/__snapshots__/Header.test.tsx.snap +0 -37
- package/src/components/Header/index.ts +0 -1
- package/src/components/README.md +0 -33
- package/src/config/README.md +0 -63
- package/src/config/index.ts +0 -1
- package/src/forms/README.md +0 -142
- package/src/hooks/README.md +0 -83
- package/src/hooks/api/queryKey.ts +0 -1
- package/src/hooks/api/useDemoApi.ts +0 -16
- package/src/pages/Demo/Demo.tsx +0 -236
- package/src/pages/Demo/ReactHookFormDemo/index.ts +0 -1
- package/src/pages/Demo/ReactHookFormDemo/routes.tsx +0 -7
- package/src/pages/Demo/ReactQueryDemo/index.ts +0 -1
- package/src/pages/Demo/ReactQueryDemo/routes.tsx +0 -7
- package/src/pages/Demo/__tests__/Demo.test.tsx +0 -15
- package/src/pages/Demo/__tests__/__snapshots__/Demo.test.tsx.snap +0 -557
- package/src/pages/Demo/index.ts +0 -1
- package/src/pages/Demo/routes.tsx +0 -8
- package/src/pages/Layout/Layout.tsx +0 -12
- package/src/pages/Layout/index.ts +0 -1
- package/src/pages/README.md +0 -91
- package/src/pages/UnexpectedError/UnexpectedError.module.css +0 -8
- package/src/pages/UnexpectedError/UnexpectedError.tsx +0 -22
- package/src/pages/UnexpectedError/index.ts +0 -1
- package/src/providers/QueryClientProvider/index.ts +0 -1
- package/src/providers/README.md +0 -112
- package/src/providers/index.ts +0 -1
- package/src/providers/withProviders/index.ts +0 -1
- package/src/providers/withProviders/withProviders.tsx +0 -18
- package/src/routing/README.md +0 -76
- package/src/routing/appRoutes.ts +0 -5
- package/src/routing/routerFactory.ts +0 -12
- package/src/routing/routes.tsx +0 -13
- package/src/types/README.md +0 -62
- package/src/types/demoApi.ts +0 -25
- package/src/ui/README.md +0 -144
- package/src/ui/molecules/Navigation/index.ts +0 -1
- package/src/ui/organisms/Footer/Footer.module.css +0 -10
- package/src/ui/organisms/Footer/Footer.tsx +0 -10
- package/src/ui/organisms/Footer/index.ts +0 -1
- package/src/ui/organisms/Header/Header.module.css +0 -17
- package/src/ui/organisms/Header/Header.tsx +0 -16
- package/src/ui/organisms/Header/index.ts +0 -1
- package/src/ui/organisms/MainContent/MainContent.module.css +0 -3
- package/src/ui/organisms/MainContent/MainContent.tsx +0 -6
- package/src/ui/organisms/MainContent/index.ts +0 -1
- package/src/ui/templates/MainTemplate/MainTemplate.module.css +0 -5
- package/src/utils/README.md +0 -70
- /package/src/{assets → app/assets}/css/index.ts +0 -0
- /package/src/{assets → app/assets}/css/mainBody.css +0 -0
- /package/src/{assets → app/assets}/css/reset.css +0 -0
- /package/src/{config → app/config}/queryClientConfig.ts +0 -0
- /package/src/{assets → demo/ui/assets}/images/logo.png +0 -0
- /package/src/{assets → demo/ui/assets}/images/templatePlugins.png +0 -0
- /package/src/{components/Footer/Footer.module.css → demo/ui/components/DemoFooter/DemoFooter.module.css} +0 -0
- /package/src/{components/Header/Header.module.css → demo/ui/components/DemoHeader/DemoHeader.module.css} +0 -0
- /package/src/{ui/molecules/Navigation/Navigation.module.css → demo/ui/components/DemoNavigation/DemoNavigation.module.css} +0 -0
- /package/src/{ui/atoms → demo/ui/components}/Input/Input.module.scss +0 -0
- /package/src/{ui/atoms → demo/ui/components}/Input/Input.tsx +0 -0
- /package/src/{ui/atoms → demo/ui/components}/Input/index.ts +0 -0
- /package/src/{ui/atoms → demo/ui/components}/Logo/Logo.module.css +0 -0
- /package/src/{ui/atoms → demo/ui/components}/Logo/Logo.tsx +0 -0
- /package/src/{ui/atoms → demo/ui/components}/Logo/__tests__/Logo.test.tsx +0 -0
- /package/src/{ui/atoms → demo/ui/components}/Logo/index.ts +0 -0
- /package/src/{ui/atoms → demo/ui/components}/NavLink/NavLink.tsx +0 -0
- /package/src/{ui/atoms → demo/ui/components}/NavLink/index.ts +0 -0
- /package/src/{components → demo/ui/components}/TextInput/index.ts +0 -0
- /package/src/{forms → demo/ui/forms}/ProfileForm/ProfileForm.module.scss +0 -0
- /package/src/{forms → demo/ui/forms}/ProfileForm/index.ts +0 -0
- /package/src/{ui/templates → demo/ui/layouts}/MainTemplate/index.ts +0 -0
- /package/src/{pages/Demo/Demo.module.scss → demo/ui/pages/DemoHome/DemoHome.module.scss} +0 -0
- /package/src/{pages/Demo/ReactQueryDemo/ReactQueryDemo.module.scss → demo/ui/pages/DependencyInjectionDemo/DependencyInjectionDemo.module.scss} +0 -0
- /package/src/{pages/Demo/ReactHookFormDemo/ReactHookFormDemo.module.css → demo/ui/pages/ReactHookFormDemo/ReactHookFormDemo.module.scss} +0 -0
- /package/src/{api → shared/infrastructure/http}/constant.ts +0 -0
- /package/src/{types/api.ts → shared/infrastructure/http/fetchApi.type.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
## @pplancq/react-template [2.9.0](https://github.com/pplancq/dev-tools/compare/@pplancq/react-template@2.8.17...@pplancq/react-template@2.9.0) (2026-06-15)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* **react-template:** restructure react-template to Clean Architecture and DDD bounded contexts ([#1742](https://github.com/pplancq/dev-tools/issues/1742)) ([bbd8a9d](https://github.com/pplancq/dev-tools/commit/bbd8a9da2028a3f070993e38bd7140a5edbe6d2c))
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
* **deps:** update commitlint monorepo to ^21.0.2 ([#1769](https://github.com/pplancq/dev-tools/issues/1769)) ([f3c7f42](https://github.com/pplancq/dev-tools/commit/f3c7f42c1229060f6471d68a3bdfc0517543ef3a))
|
|
10
|
+
* **deps:** update dependency @hookform/resolvers to ^5.4.0 ([#1755](https://github.com/pplancq/dev-tools/issues/1755)) ([e7f1d68](https://github.com/pplancq/dev-tools/commit/e7f1d68a868fba6247fe360b8e8b5e9fc6275be4))
|
|
11
|
+
* **deps:** update dependency @rsbuild/core to ^2.0.12 ([#1744](https://github.com/pplancq/dev-tools/issues/1744)) ([22a93b3](https://github.com/pplancq/dev-tools/commit/22a93b3d027b2a88c4bc9f80ecbeb4af91e3f0e6))
|
|
12
|
+
* **deps:** update dependency @rsbuild/plugin-eslint to ^2.0.2 ([#1759](https://github.com/pplancq/dev-tools/issues/1759)) ([eeaa6cb](https://github.com/pplancq/dev-tools/commit/eeaa6cbe616a365066611c39a3ccc36db6598b7c))
|
|
13
|
+
* **deps:** update dependency @rsbuild/plugin-react to ^2.0.1 ([#1766](https://github.com/pplancq/dev-tools/issues/1766)) ([b1527e6](https://github.com/pplancq/dev-tools/commit/b1527e6097daf03e8dbe82959e14899cf11d1086))
|
|
14
|
+
* **deps:** update dependency @rsbuild/plugin-sass to ^1.5.3 ([#1767](https://github.com/pplancq/dev-tools/issues/1767)) ([b25e848](https://github.com/pplancq/dev-tools/commit/b25e848e00e384b3a378ec243ce69c7151ff4c8c))
|
|
15
|
+
* **deps:** update dependency monocart-coverage-reports to ^2.12.12 ([#1768](https://github.com/pplancq/dev-tools/issues/1768)) ([8a5ba24](https://github.com/pplancq/dev-tools/commit/8a5ba24051ff8f7eb6409b5ab6738ebdb01055d9))
|
|
16
|
+
* **deps:** update dependency react-hook-form to ^7.78.0 ([#1756](https://github.com/pplancq/dev-tools/issues/1756)) ([2cccd51](https://github.com/pplancq/dev-tools/commit/2cccd5144d875d0accf485b256ef3d91ca8fe893))
|
|
17
|
+
* **deps:** update dependency stylelint to ^17.13.0 ([#1752](https://github.com/pplancq/dev-tools/issues/1752)) ([acfc13f](https://github.com/pplancq/dev-tools/commit/acfc13f61041ffc9323a3e469c1b2e51fbf3bf9f))
|
|
18
|
+
* **deps:** update react monorepo ([#1745](https://github.com/pplancq/dev-tools/issues/1745)) ([8424cfe](https://github.com/pplancq/dev-tools/commit/8424cfed2645554410e1e7df2632376b26b1fb04))
|
|
19
|
+
* **deps:** update react-query mono repo to ^5.101.0 ([#1749](https://github.com/pplancq/dev-tools/issues/1749)) ([31d0cfd](https://github.com/pplancq/dev-tools/commit/31d0cfdedf9a5c1ed2779cff2a0b8a0fd8a8ac5d))
|
|
20
|
+
* **deps:** update react-router monorepo to ^7.17.0 ([#1763](https://github.com/pplancq/dev-tools/issues/1763)) ([6cfffba](https://github.com/pplancq/dev-tools/commit/6cfffba0a99f0c0dcb4f271ace035e60b2d951d3))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Dependencies
|
|
24
|
+
|
|
25
|
+
* **@pplancq/commitlint-config:** upgraded to 4.0.2
|
|
26
|
+
* **@pplancq/eslint-config:** upgraded to 6.0.17
|
|
27
|
+
|
|
1
28
|
## @pplancq/react-template [2.8.17](https://github.com/pplancq/dev-tools/compare/@pplancq/react-template@2.8.16...@pplancq/react-template@2.8.17) (2026-05-19)
|
|
2
29
|
|
|
3
30
|
### Bug Fixes
|
package/_README.md
CHANGED
|
@@ -81,64 +81,69 @@ Allows you to fix prettier lint errors.
|
|
|
81
81
|
|
|
82
82
|
To remove the demo application.
|
|
83
83
|
|
|
84
|
-
### `npm run migrate:vite`
|
|
85
|
-
|
|
86
|
-
To migrate from webpack to vite.
|
|
87
|
-
|
|
88
84
|
## 🏗 <span id="project-structure">Project Structure</span>
|
|
89
85
|
|
|
90
|
-
```
|
|
91
|
-
📁 my-
|
|
86
|
+
```text
|
|
87
|
+
📁 my-project
|
|
92
88
|
├── 📁 src
|
|
93
|
-
│ ├──
|
|
94
|
-
│
|
|
95
|
-
│ │ ├──
|
|
96
|
-
│ │ ├──
|
|
97
|
-
│ │ ├──
|
|
98
|
-
│ ├── 📁
|
|
99
|
-
│ │ ├── 📁
|
|
100
|
-
│ ├── 📁 providers
|
|
101
|
-
│
|
|
102
|
-
│
|
|
103
|
-
│ │ ├──
|
|
104
|
-
│ │
|
|
105
|
-
│
|
|
106
|
-
│ │ ├── 📁
|
|
107
|
-
│ │
|
|
108
|
-
│ │ ├── 📁
|
|
109
|
-
│
|
|
110
|
-
│ │
|
|
111
|
-
│ │
|
|
112
|
-
│
|
|
113
|
-
│ ├──
|
|
114
|
-
│ │ ├── 📁
|
|
115
|
-
│ │ ├── 📁
|
|
116
|
-
│ │ ├── 📁
|
|
117
|
-
│ ├── 📁
|
|
118
|
-
│ ├── 📁
|
|
119
|
-
│ ├── 📁
|
|
120
|
-
│ ├── 📁
|
|
121
|
-
│ ├── 📁
|
|
89
|
+
│ ├── 📄 README.md
|
|
90
|
+
│ ├── 📁 app
|
|
91
|
+
│ │ ├── 📄 README.md
|
|
92
|
+
│ │ ├── 📄 App.tsx
|
|
93
|
+
│ │ ├── 📄 AppHTMLElement.tsx
|
|
94
|
+
│ │ ├── 📁 assets
|
|
95
|
+
│ │ ├── 📁 config
|
|
96
|
+
│ │ ├── 📁 providers
|
|
97
|
+
│ │ └── 📁 routing
|
|
98
|
+
│ ├── 📁 shared
|
|
99
|
+
│ │ ├── 📄 README.md
|
|
100
|
+
│ │ ├── 📁 application
|
|
101
|
+
│ │ │ └── 📄 README.md
|
|
102
|
+
│ │ ├── 📁 domain
|
|
103
|
+
│ │ │ └── 📄 README.md
|
|
104
|
+
│ │ ├── 📁 infrastructure
|
|
105
|
+
│ │ │ └── 📄 README.md
|
|
106
|
+
│ │ └── 📁 ui
|
|
107
|
+
│ │ └── 📄 README.md
|
|
108
|
+
│ ├── 📁 demo
|
|
109
|
+
│ │ ├── 📄 README.md
|
|
110
|
+
│ │ ├── 📁 application
|
|
111
|
+
│ │ ├── 📁 domain
|
|
112
|
+
│ │ ├── 📁 infrastructure
|
|
113
|
+
│ │ ├── 📁 ui
|
|
114
|
+
│ │ │ ├── 📁 assets
|
|
115
|
+
│ │ │ ├── 📁 components
|
|
116
|
+
│ │ │ ├── 📁 forms
|
|
117
|
+
│ │ │ ├── 📁 hooks
|
|
118
|
+
│ │ │ ├── 📁 layouts
|
|
119
|
+
│ │ │ ├── 📁 pages
|
|
120
|
+
│ │ │ └── 📁 routing
|
|
121
|
+
│ │ ├── 📄 serviceDemo.ts
|
|
122
|
+
│ │ └── 📄 serviceIdentifiers.ts
|
|
123
|
+
│ ├── 📄 main.ts
|
|
124
|
+
│ └── 📄 react-app-env.d.ts
|
|
122
125
|
```
|
|
123
126
|
|
|
124
127
|
### 📚 Folder Definitions
|
|
125
128
|
|
|
126
129
|
Here is the project folder structure, with a brief description of each folder:
|
|
127
130
|
|
|
128
|
-
| Folder
|
|
129
|
-
|
|
|
130
|
-
| **📁 src**
|
|
131
|
-
| [**📁
|
|
132
|
-
| [
|
|
133
|
-
| [**📁
|
|
134
|
-
| [**📁
|
|
135
|
-
| [**📁
|
|
136
|
-
| [**📁
|
|
137
|
-
| [**📁
|
|
138
|
-
|
|
|
139
|
-
|
|
|
140
|
-
|
|
|
141
|
-
|
|
|
131
|
+
| Folder | Description |
|
|
132
|
+
| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
133
|
+
| **📁 src** | **_The root directory of the application source code._** It also contains [`src/README.md`](./src/README.md), which serves as the documentation index. |
|
|
134
|
+
| [**📁 app**](./src/app/README.md) | Owns the application bootstrap layer: root app composition, custom element entry point, routing, providers, global configuration, and app-wide assets. |
|
|
135
|
+
| [**📁 shared**](./src/shared/README.md) | Contains only genuinely reusable cross-context code. In this starter it is intentionally conservative and avoids hosting demo-specific UI. |
|
|
136
|
+
| [**📁 shared/application**](./src/shared/application/README.md) | Shared application-layer abstractions, DTO helpers, or orchestration utilities that can be reused by several bounded contexts. |
|
|
137
|
+
| [**📁 shared/domain**](./src/shared/domain/README.md) | Shared pure types and contracts. This folder must stay framework-free and focused on stable, reusable domain-facing definitions. |
|
|
138
|
+
| [**📁 shared/infrastructure**](./src/shared/infrastructure/README.md) | Shared technical helpers backed by external tools or browser APIs, such as generic HTTP utilities. |
|
|
139
|
+
| [**📁 shared/ui**](./src/shared/ui/README.md) | Shared UI-facing helpers with no feature identity. In the current template it mainly exists for common hooks such as DI-to-React integration. |
|
|
140
|
+
| [**📁 demo**](./src/demo/README.md) | The example bounded context included in the starter. It demonstrates how to structure a feature using `application`, `domain`, `infrastructure`, and `ui`. |
|
|
141
|
+
| **📁 demo/ui/components** | Demo visual components and building blocks. The structure stays practical and readable instead of exposing `atoms`, `molecules`, or `organisms` folders. |
|
|
142
|
+
| **📁 demo/ui/layouts** | Demo layouts used to compose pages. |
|
|
143
|
+
| **📁 demo/ui/pages** | Demo pages such as the overview page and the example feature pages. |
|
|
144
|
+
| **📁 demo/ui/forms** | Demo form composition and form-related UI pieces. |
|
|
145
|
+
| **📁 demo/ui/hooks** | Demo-specific React hooks, such as query hooks that connect the UI to the application layer. |
|
|
146
|
+
| **📁 demo/ui/routing** | Demo route definitions and route path constants consumed by the app router. |
|
|
142
147
|
|
|
143
148
|
## 🏗 <span id="component-structure">React Component Structure</span>
|
|
144
149
|
|
|
@@ -171,7 +176,7 @@ export { ComponentName } from './ComponentName';
|
|
|
171
176
|
This will allow importing a component like this:
|
|
172
177
|
|
|
173
178
|
```typescript
|
|
174
|
-
import { ComponentName } from '@
|
|
179
|
+
import { ComponentName } from '@Demo/ui/components/ComponentName';
|
|
175
180
|
```
|
|
176
181
|
|
|
177
182
|
#### 📄 ComponentName.tsx
|
|
@@ -236,13 +241,13 @@ export const ComponentName = () => {
|
|
|
236
241
|
|
|
237
242
|
## ⚠️ Caution with Environment Variables
|
|
238
243
|
|
|
239
|
-
The
|
|
244
|
+
The build configuration of this project allows for environment variables to be included in the application bundle. This could potentially expose sensitive information if the bundle is publicly accessible.
|
|
240
245
|
|
|
241
246
|
It is recommended to only include non-sensitive environment variables in the application bundle. Sensitive information should not be exposed even if the bundle is publicly accessible.
|
|
242
247
|
|
|
243
248
|
Ensure you understand the security implications before including environment variables in your bundle.
|
|
244
249
|
|
|
245
|
-
Please note that the
|
|
250
|
+
Please note that the build configuration pre-filters environment variables via the default prefix `FRONT*`. This means that only environment variables starting with `FRONT*` will be included in the bundle. This is an additional layer of security to prevent the accidental exposure of sensitive environment variables.
|
|
246
251
|
|
|
247
252
|
## 🙇 <span id="learnmore">Learn More</span>
|
|
248
253
|
|
package/mise.toml
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
[tools]
|
|
2
|
-
node = "24.
|
|
3
|
-
npm = "11.
|
|
2
|
+
node = "24.16.0"
|
|
3
|
+
npm = "11.17.0"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pplancq/react-template",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "react template",
|
|
6
6
|
"author": "pplancq <paul.plancq@outlook.fr>",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"bin": {
|
|
14
14
|
"template-install": "bin/template-install.js"
|
|
15
15
|
},
|
|
16
|
-
"packageManager": "npm@11.
|
|
16
|
+
"packageManager": "npm@11.17.0",
|
|
17
17
|
"scripts": {
|
|
18
18
|
"start": "rsbuild dev",
|
|
19
19
|
"start:mock": "rsbuild dev --env-mode mock",
|
|
@@ -49,18 +49,19 @@
|
|
|
49
49
|
"template"
|
|
50
50
|
],
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@hookform/resolvers": "^5.
|
|
53
|
-
"@tanstack/react-query": "^5.
|
|
54
|
-
"@tanstack/react-query-devtools": "^5.
|
|
55
|
-
"
|
|
56
|
-
"react
|
|
57
|
-
"react-
|
|
58
|
-
"react-
|
|
52
|
+
"@hookform/resolvers": "^5.4.0",
|
|
53
|
+
"@tanstack/react-query": "^5.101.0",
|
|
54
|
+
"@tanstack/react-query-devtools": "^5.101.0",
|
|
55
|
+
"inversify": "^8.1.0",
|
|
56
|
+
"react": "^19.2.7",
|
|
57
|
+
"react-dom": "^19.2.7",
|
|
58
|
+
"react-hook-form": "^7.78.0",
|
|
59
|
+
"react-router": "^7.17.0",
|
|
59
60
|
"yup": "^1.7.1"
|
|
60
61
|
},
|
|
61
62
|
"devDependencies": {
|
|
62
|
-
"@bdellegrazie/playwright-sonar-reporter": "^0.5.
|
|
63
|
-
"@commitlint/cli": "^21.0.
|
|
63
|
+
"@bdellegrazie/playwright-sonar-reporter": "^0.5.1",
|
|
64
|
+
"@commitlint/cli": "^21.0.2",
|
|
64
65
|
"@msw/playwright": "^0.6.7",
|
|
65
66
|
"@playwright/test": "^1.60.0",
|
|
66
67
|
"@pplancq/commitlint-config": "*",
|
|
@@ -68,34 +69,34 @@
|
|
|
68
69
|
"@pplancq/postcss-config": "*",
|
|
69
70
|
"@pplancq/prettier-config": "*",
|
|
70
71
|
"@pplancq/stylelint-config": "*",
|
|
71
|
-
"@rsbuild/core": "^2.0.
|
|
72
|
-
"@rsbuild/plugin-eslint": "^2.0.
|
|
73
|
-
"@rsbuild/plugin-react": "^2.0.
|
|
74
|
-
"@rsbuild/plugin-sass": "^1.5.
|
|
72
|
+
"@rsbuild/core": "^2.0.12",
|
|
73
|
+
"@rsbuild/plugin-eslint": "^2.0.2",
|
|
74
|
+
"@rsbuild/plugin-react": "^2.0.1",
|
|
75
|
+
"@rsbuild/plugin-sass": "^1.5.3",
|
|
75
76
|
"@testing-library/jest-dom": "^6.9.1",
|
|
76
77
|
"@testing-library/react": "^16.3.2",
|
|
77
78
|
"@testing-library/user-event": "^14.6.1",
|
|
78
|
-
"@types/react": "^19.2.
|
|
79
|
+
"@types/react": "^19.2.17",
|
|
79
80
|
"@types/react-dom": "^19.2.3",
|
|
80
81
|
"@vitejs/plugin-react": "^6.0.2",
|
|
81
|
-
"@vitest/coverage-v8": "^4.1.
|
|
82
|
-
"concurrently": "^
|
|
82
|
+
"@vitest/coverage-v8": "^4.1.8",
|
|
83
|
+
"concurrently": "^10.0.3",
|
|
83
84
|
"eslint": "^9.39.4",
|
|
84
|
-
"eslint-plugin-prettier": "^5.5.
|
|
85
|
+
"eslint-plugin-prettier": "^5.5.6",
|
|
85
86
|
"husky": "^9.1.7",
|
|
86
87
|
"jsdom": "^29.1.1",
|
|
87
|
-
"lint-staged": "^17.0.
|
|
88
|
-
"monocart-coverage-reports": "^2.12.
|
|
88
|
+
"lint-staged": "^17.0.7",
|
|
89
|
+
"monocart-coverage-reports": "^2.12.12",
|
|
89
90
|
"msw": "^2.14.6",
|
|
90
91
|
"nodemon": "^3.1.14",
|
|
91
|
-
"prettier": "^3.8.
|
|
92
|
+
"prettier": "^3.8.4",
|
|
92
93
|
"rsbuild-plugin-stylelint": "^1.2.0",
|
|
93
|
-
"stylelint": "^17.
|
|
94
|
+
"stylelint": "^17.13.0",
|
|
94
95
|
"stylelint-prettier": "^5.0.3",
|
|
95
96
|
"tsc-files": "^1.1.4",
|
|
96
97
|
"typescript": "^6.0.3",
|
|
97
98
|
"vite-plugin-svgr": "^5.2.0",
|
|
98
|
-
"vitest": "^4.1.
|
|
99
|
+
"vitest": "^4.1.8",
|
|
99
100
|
"vitest-axe": "^1.0.0-pre.5",
|
|
100
101
|
"vitest-sonar-reporter": "^3.0.0"
|
|
101
102
|
},
|
package/scripts/removeDemo.cjs
CHANGED
|
@@ -4,79 +4,118 @@ const { resolve } = require('node:path');
|
|
|
4
4
|
|
|
5
5
|
const resolveSrc = path => resolve(__dirname, `../src${path}`);
|
|
6
6
|
|
|
7
|
-
rmSync(resolveSrc('/
|
|
8
|
-
|
|
9
|
-
rmSync(resolveSrc('/assets/css/mainBody.css'));
|
|
10
|
-
|
|
11
|
-
writeFileSync(resolveSrc('/assets/css/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
writeFileSync(resolveSrc('/hooks/api/queryKey.ts'), queryKey, { encoding: 'utf-8' });
|
|
29
|
-
|
|
30
|
-
rmSync(resolveSrc('/pages/Demo'), { recursive: true });
|
|
31
|
-
rmSync(resolveSrc('/pages/Layout'), { recursive: true });
|
|
32
|
-
rmSync(resolveSrc('/pages/UnexpectedError'), { recursive: true });
|
|
33
|
-
mkdirSync(resolveSrc('/pages/Home'));
|
|
34
|
-
writeFileSync(resolveSrc('/pages/Home/index.ts'), "export { homeRoutes } from './routes';\n", { encoding: 'utf-8' });
|
|
7
|
+
rmSync(resolveSrc('/demo'), { recursive: true, force: true });
|
|
8
|
+
|
|
9
|
+
rmSync(resolveSrc('/app/assets/css/mainBody.css'), { force: true });
|
|
10
|
+
writeFileSync(resolveSrc('/app/assets/css/global.css'), ':root {\n --white-color: #fff;\n}\n', { encoding: 'utf-8' });
|
|
11
|
+
writeFileSync(resolveSrc('/app/assets/css/index.ts'), "import './reset.css';\nimport './global.css';\n", {
|
|
12
|
+
encoding: 'utf-8',
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
mkdirSync(resolveSrc('/home/domain'), { recursive: true });
|
|
16
|
+
writeFileSync(resolveSrc('/home/domain/.gitkeep'), '', { encoding: 'utf-8' });
|
|
17
|
+
|
|
18
|
+
mkdirSync(resolveSrc('/home/application'), { recursive: true });
|
|
19
|
+
writeFileSync(resolveSrc('/home/application/.gitkeep'), '', { encoding: 'utf-8' });
|
|
20
|
+
|
|
21
|
+
mkdirSync(resolveSrc('/home/infrastructure'), { recursive: true });
|
|
22
|
+
writeFileSync(resolveSrc('/home/infrastructure/.gitkeep'), '', { encoding: 'utf-8' });
|
|
23
|
+
|
|
24
|
+
writeFileSync(resolveSrc('/home/serviceIdentifiers.ts'), 'export const HOME_SERVICES = Object.freeze({});\n', {
|
|
25
|
+
encoding: 'utf-8',
|
|
26
|
+
});
|
|
27
|
+
|
|
35
28
|
writeFileSync(
|
|
36
|
-
resolveSrc('/
|
|
37
|
-
|
|
38
|
-
"import {
|
|
39
|
-
'
|
|
40
|
-
'export const
|
|
41
|
-
'
|
|
42
|
-
'
|
|
43
|
-
'
|
|
29
|
+
resolveSrc('/home/serviceHome.ts'),
|
|
30
|
+
[
|
|
31
|
+
"import { ContainerModule } from 'inversify';",
|
|
32
|
+
'',
|
|
33
|
+
'export const serviceHome: ContainerModule = new ContainerModule(_options => {',
|
|
34
|
+
' // Register your home context services here',
|
|
35
|
+
'});',
|
|
36
|
+
'',
|
|
37
|
+
].join('\n'),
|
|
44
38
|
{ encoding: 'utf-8' },
|
|
45
39
|
);
|
|
46
|
-
writeFileSync(resolveSrc('/pages/Home/Home.tsx'), 'export const Home = () => {\n return <div>HomePage</div>;\n};\n', {
|
|
47
|
-
encoding: 'utf-8',
|
|
48
|
-
});
|
|
49
40
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
41
|
+
mkdirSync(resolveSrc('/home/ui/pages/Home'), { recursive: true });
|
|
42
|
+
writeFileSync(
|
|
43
|
+
resolveSrc('/home/ui/pages/Home/Home.tsx'),
|
|
44
|
+
[
|
|
45
|
+
'export const Home = () => {',
|
|
46
|
+
' return (',
|
|
47
|
+
' <section>',
|
|
48
|
+
' <h1>Home</h1>',
|
|
49
|
+
' <p>Your demo context has been removed. Start building your first bounded context from here.</p>',
|
|
50
|
+
' </section>',
|
|
51
|
+
' );',
|
|
52
|
+
'};',
|
|
53
|
+
'',
|
|
54
|
+
].join('\n'),
|
|
55
|
+
{ encoding: 'utf-8' },
|
|
54
56
|
);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
|
|
58
|
+
mkdirSync(resolveSrc('/home/ui/routing'), { recursive: true });
|
|
59
|
+
writeFileSync(
|
|
60
|
+
resolveSrc('/home/ui/routing/homeAppRoutes.ts'),
|
|
61
|
+
['export const homeAppRoutes = Object.freeze({', " home: '/',", '});', ''].join('\n'),
|
|
62
|
+
{ encoding: 'utf-8' },
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
writeFileSync(
|
|
66
|
+
resolveSrc('/home/ui/routing/homeRoutes.tsx'),
|
|
67
|
+
[
|
|
68
|
+
"import { Home } from '@Home/ui/pages/Home/Home';",
|
|
69
|
+
"import type { RouteObject } from 'react-router';",
|
|
70
|
+
'',
|
|
71
|
+
'export const homeRoutes: RouteObject = {',
|
|
72
|
+
' children: [',
|
|
73
|
+
' {',
|
|
74
|
+
' index: true,',
|
|
75
|
+
' element: <Home />,',
|
|
76
|
+
' },',
|
|
77
|
+
' ],',
|
|
78
|
+
'};',
|
|
79
|
+
'',
|
|
80
|
+
].join('\n'),
|
|
81
|
+
{ encoding: 'utf-8' },
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
writeFileSync(
|
|
85
|
+
resolveSrc('/app/config/serviceContainer.ts'),
|
|
86
|
+
[
|
|
87
|
+
"import { serviceHome } from '@Home/serviceHome';",
|
|
88
|
+
"import { Container } from 'inversify';",
|
|
89
|
+
'',
|
|
90
|
+
'export const serviceContainer = new Container();',
|
|
91
|
+
'',
|
|
92
|
+
'serviceContainer.load(serviceHome);',
|
|
93
|
+
'',
|
|
94
|
+
].join('\n'),
|
|
95
|
+
{ encoding: 'utf-8' },
|
|
60
96
|
);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
routes
|
|
64
|
-
|
|
65
|
-
|
|
97
|
+
|
|
98
|
+
writeFileSync(
|
|
99
|
+
resolveSrc('/app/routing/routes.tsx'),
|
|
100
|
+
[
|
|
101
|
+
"import { homeRoutes } from '@Home/ui/routing/homeRoutes';",
|
|
102
|
+
"import type { RouteObject } from 'react-router';",
|
|
103
|
+
'',
|
|
104
|
+
'export const routeObject: RouteObject[] = [',
|
|
105
|
+
' {',
|
|
106
|
+
" path: '/',",
|
|
107
|
+
' children: [homeRoutes],',
|
|
108
|
+
' },',
|
|
109
|
+
'];',
|
|
110
|
+
'',
|
|
111
|
+
].join('\n'),
|
|
112
|
+
{ encoding: 'utf-8' },
|
|
66
113
|
);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
rmSync(resolveSrc('/ui/atoms/Input'), { recursive: true });
|
|
73
|
-
rmSync(resolveSrc('/ui/atoms/Logo'), { recursive: true });
|
|
74
|
-
rmSync(resolveSrc('/ui/atoms/NavLink'), { recursive: true });
|
|
75
|
-
rmSync(resolveSrc('/ui/molecules/Navigation'), { recursive: true });
|
|
76
|
-
rmSync(resolveSrc('/ui/organisms/Footer'), { recursive: true });
|
|
77
|
-
rmSync(resolveSrc('/ui/organisms/Header'), { recursive: true });
|
|
78
|
-
rmSync(resolveSrc('/ui/organisms/MainContent'), { recursive: true });
|
|
79
|
-
rmSync(resolveSrc('/ui/templates/MainTemplate'), { recursive: true });
|
|
114
|
+
|
|
115
|
+
const tsconfigJson = JSON.parse(readFileSync(resolve(__dirname, '../tsconfig.json'), { encoding: 'utf-8' }));
|
|
116
|
+
delete tsconfigJson.compilerOptions.paths['@Demo/*'];
|
|
117
|
+
tsconfigJson.compilerOptions.paths['@Home/*'] = ['./src/home/*'];
|
|
118
|
+
writeFileSync(resolve(__dirname, '../tsconfig.json'), JSON.stringify(tsconfigJson, null, 2), { encoding: 'utf-8' });
|
|
80
119
|
|
|
81
120
|
const packagesJson = JSON.parse(readFileSync(resolve(__dirname, '../package.json'), { encoding: 'utf-8' }));
|
|
82
121
|
const { 'remove:demo': _, ...scripts } = packagesJson.scripts;
|
package/src/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# `src`
|
|
2
|
+
|
|
3
|
+
This directory contains the template source code and its explanatory documentation.
|
|
4
|
+
|
|
5
|
+
## Architecture Philosophy
|
|
6
|
+
|
|
7
|
+
This starter follows a **hybrid architecture** combining two complementary patterns:
|
|
8
|
+
|
|
9
|
+
- **Clean Architecture** (Robert C. Martin) — code is organized into horizontal layers that enforce a strict
|
|
10
|
+
dependency direction. Dependencies always flow **inward toward the domain**. The domain is the most protected
|
|
11
|
+
layer; it has zero external dependencies.
|
|
12
|
+
- **DDD Bounded Contexts** — code is also organized into vertical slices, each representing an isolated business
|
|
13
|
+
domain. A bounded context owns its full stack: domain, application, infrastructure, and UI.
|
|
14
|
+
|
|
15
|
+
The result is a structure where every folder belongs to either a **horizontal layer** (domain, application,
|
|
16
|
+
infrastructure, ui) or a **vertical slice** (a bounded context such as `demo`), and both dimensions are always
|
|
17
|
+
visible.
|
|
18
|
+
|
|
19
|
+
## Top-level structure
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
src/
|
|
23
|
+
├── app/ # Application bootstrap layer (not a bounded context)
|
|
24
|
+
├── shared/ # Shared kernel — genuinely cross-context code
|
|
25
|
+
│ ├── domain/
|
|
26
|
+
│ ├── application/
|
|
27
|
+
│ ├── infrastructure/
|
|
28
|
+
│ └── ui/
|
|
29
|
+
└── demo/ # Example bounded context (domain / application / infrastructure / ui)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Fundamental dependency rule
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
UI → Application → Domain
|
|
36
|
+
Infrastructure -.→ Domain (implements its interfaces)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- **Domain** depends on nothing. Pure TypeScript.
|
|
40
|
+
- **Application** depends on Domain only. Orchestrates use cases, defines infrastructure interfaces.
|
|
41
|
+
- **Infrastructure** implements interfaces defined by Domain/Application. May use external libraries.
|
|
42
|
+
- **UI** depends on Application (use cases) and Domain (DTOs). No business logic.
|
|
43
|
+
|
|
44
|
+
This rule applies **within each bounded context** and **within the shared kernel**.
|
|
45
|
+
|
|
46
|
+
## Path aliases
|
|
47
|
+
|
|
48
|
+
Each first-class section of the source tree has a TypeScript path alias. Use these aliases instead of long
|
|
49
|
+
relative paths; they signal architectural intent and prevent accidental cross-context coupling.
|
|
50
|
+
|
|
51
|
+
| Alias | Maps to |
|
|
52
|
+
| ----------- | -------------- |
|
|
53
|
+
| `@App/*` | `src/app/*` |
|
|
54
|
+
| `@Shared/*` | `src/shared/*` |
|
|
55
|
+
| `@Demo/*` | `src/demo/*` |
|
|
56
|
+
| `@Mocks/*` | `mocks/*` |
|
|
57
|
+
|
|
58
|
+
When you add a real bounded context alongside `demo`, add its own alias to `tsconfig.json`.
|
|
59
|
+
|
|
60
|
+
## Table of contents
|
|
61
|
+
|
|
62
|
+
1. [`app/README.md`](./app/README.md) — application bootstrap, composition root, routing, and providers
|
|
63
|
+
2. [`shared/README.md`](./shared/README.md) — shared kernel concept and usage rules
|
|
64
|
+
3. [`shared/domain/README.md`](./shared/domain/README.md) — shared pure contracts, types, and domain rules
|
|
65
|
+
4. [`shared/application/README.md`](./shared/application/README.md) — shared application-layer abstractions
|
|
66
|
+
5. [`shared/infrastructure/README.md`](./shared/infrastructure/README.md) — shared technical adapters and helpers
|
|
67
|
+
6. [`shared/ui/README.md`](./shared/ui/README.md) — shared UI-facing hooks and utilities
|
|
68
|
+
7. [`demo/README.md`](./demo/README.md) — the example bounded context and how to replicate it
|
|
69
|
+
|
|
70
|
+
## Suggested reading order
|
|
71
|
+
|
|
72
|
+
If you are discovering the template for the first time:
|
|
73
|
+
|
|
74
|
+
1. This file — understand the big picture
|
|
75
|
+
2. `app` — see how the application boots and wires everything together
|
|
76
|
+
3. `shared/domain` — understand why the domain layer is the most protected
|
|
77
|
+
4. `shared` — understand what the shared kernel is and what it must not become
|
|
78
|
+
5. `demo` — walk through a complete bounded context layer by layer
|
|
79
|
+
|
|
80
|
+
That sequence starts with the overall architecture, moves to the heart of Clean Architecture (domain purity),
|
|
81
|
+
then shows how a real bounded context puts all the pieces together.
|
package/src/app/App.tsx
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { queryClient } from '@App/config/queryClientConfig';
|
|
2
|
+
import { serviceContainer } from '@App/config/serviceContainer';
|
|
3
|
+
import { Providers } from '@App/providers/Providers/Providers';
|
|
4
|
+
import { Router } from '@App/routing/Router';
|
|
5
|
+
|
|
6
|
+
import '@App/assets/css';
|
|
7
|
+
|
|
8
|
+
type AppProps = {
|
|
9
|
+
basename?: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const App = ({ basename }: AppProps) => {
|
|
13
|
+
return (
|
|
14
|
+
<Providers queryClient={queryClient} container={serviceContainer}>
|
|
15
|
+
<Router basename={basename} />
|
|
16
|
+
</Providers>
|
|
17
|
+
);
|
|
18
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { App } from '@
|
|
1
|
+
import { App } from '@App/App';
|
|
2
2
|
import { StrictMode } from 'react';
|
|
3
3
|
import { createRoot, type Root } from 'react-dom/client';
|
|
4
4
|
|
|
5
5
|
// eslint-disable-next-line import/no-default-export
|
|
6
|
-
export default class
|
|
6
|
+
export default class AppHTMLElement extends HTMLElement {
|
|
7
7
|
private readonly root: Root;
|
|
8
8
|
|
|
9
9
|
private isMounted = false;
|