@t1ep1l0t/create-fsd 1.0.0 → 1.0.2
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/README.md +146 -100
- package/package.json +1 -1
- package/templates/react/.editorconfig +12 -0
- package/templates/react/.prettierignore +7 -0
- package/templates/react/.prettierrc +10 -0
- package/templates/react/.vscode/extensions.json +7 -0
- package/templates/react/eslint.config.js +102 -3
- package/templates/react/package.json +16 -1
- package/templates/react/public/locales/en/basic.json +9 -0
- package/templates/react/public/locales/ru/basic.json +9 -0
- package/templates/react/src/app/providers/i18n/index.js +23 -26
- package/templates/react/vite.config.js +9 -5
package/README.md
CHANGED
|
@@ -1,28 +1,58 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# 🚀 @t1ep1l0t/create-fsd
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Scaffold modern frontend applications with Feature-Sliced Design architecture**
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
- React Router DOM (routing)
|
|
11
|
-
- Zustand (state management)
|
|
12
|
-
- Axios (HTTP client with interceptors)
|
|
13
|
-
- React Query (server state management)
|
|
14
|
-
- i18next (internationalization)
|
|
15
|
-
- TailwindCSS v4 (styling)
|
|
16
|
-
- Example code for all libraries
|
|
17
|
-
- Path aliases configured (@app, @pages, @widgets, @features, @entities, @shared)
|
|
18
|
-
- ESLint configured
|
|
7
|
+
[](https://www.npmjs.com/package/@t1ep1l0t/create-fsd)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://nodejs.org/)
|
|
19
10
|
|
|
20
|
-
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 📖 About
|
|
16
|
+
|
|
17
|
+
**@t1ep1l0t/create-fsd** is a powerful CLI tool that helps you quickly bootstrap production-ready React applications following the [Feature-Sliced Design (FSD)](https://feature-sliced.design/) architectural methodology. Get started with a fully configured project in seconds!
|
|
18
|
+
|
|
19
|
+
> 🎯 Currently supports **React** template. More frameworks (Vue, Next, Nuxt, Svelte) coming soon!
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## ✨ Features
|
|
24
|
+
|
|
25
|
+
### 🏗️ **Architecture**
|
|
26
|
+
- **Feature-Sliced Design (FSD)** - Scalable and maintainable project structure
|
|
27
|
+
- Clear separation of concerns across layers
|
|
28
|
+
- Ready-to-use folder structure
|
|
29
|
+
|
|
30
|
+
### ⚡ **Modern Stack**
|
|
31
|
+
- **React 18** - Latest React with concurrent features
|
|
32
|
+
- **Vite** - Lightning-fast build tool and dev server
|
|
33
|
+
- **TailwindCSS v4** - Utility-first CSS framework
|
|
34
|
+
|
|
35
|
+
### 📦 **Pre-configured Libraries**
|
|
36
|
+
- **React Router DOM** - Declarative routing
|
|
37
|
+
- **Zustand** - Lightweight state management
|
|
38
|
+
- **Axios** - HTTP client with interceptors configured
|
|
39
|
+
- **React Query** - Powerful server state management
|
|
40
|
+
- **i18next** - Internationalization (i18n) support
|
|
41
|
+
- **ESLint & Prettier** - Code quality and consistency
|
|
42
|
+
|
|
43
|
+
### 🎨 **Developer Experience**
|
|
44
|
+
- Path aliases configured (`@app`, `@pages`, `@widgets`, `@features`, `@entities`, `@shared`)
|
|
45
|
+
- Example code demonstrating best practices
|
|
46
|
+
- Zero configuration needed - start coding immediately
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 🚀 Quick Start
|
|
21
51
|
|
|
22
52
|
### Using npm
|
|
23
53
|
|
|
24
54
|
```bash
|
|
25
|
-
npm create fsd my-app
|
|
55
|
+
npm create @t1ep1l0t/fsd my-app
|
|
26
56
|
cd my-app
|
|
27
57
|
npm run dev
|
|
28
58
|
```
|
|
@@ -30,132 +60,148 @@ npm run dev
|
|
|
30
60
|
### Using npx
|
|
31
61
|
|
|
32
62
|
```bash
|
|
33
|
-
npx create-fsd my-app
|
|
63
|
+
npx @t1ep1l0t/create-fsd my-app
|
|
34
64
|
cd my-app
|
|
35
65
|
npm run dev
|
|
36
66
|
```
|
|
37
67
|
|
|
38
|
-
###
|
|
68
|
+
### With template option
|
|
39
69
|
|
|
40
70
|
```bash
|
|
41
|
-
|
|
42
|
-
cd my-app
|
|
43
|
-
npm run dev
|
|
71
|
+
npx @t1ep1l0t/create-fsd my-app --template react
|
|
44
72
|
```
|
|
45
73
|
|
|
46
|
-
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## 📂 Project Structure
|
|
77
|
+
|
|
78
|
+
The generated project follows the FSD architecture with clear layer separation:
|
|
47
79
|
|
|
48
|
-
```
|
|
49
|
-
|
|
80
|
+
```
|
|
81
|
+
src/
|
|
82
|
+
├── 📱 app/ # Application initialization layer
|
|
83
|
+
│ ├── providers/ # App providers (Router, i18n, Query Client)
|
|
84
|
+
│ ├── styles/ # Global styles
|
|
85
|
+
│ └── App.jsx # Root component
|
|
86
|
+
│
|
|
87
|
+
├── 📄 pages/ # Pages layer - route components
|
|
88
|
+
│ ├── home/ # Home page
|
|
89
|
+
│ └── about/ # About page
|
|
90
|
+
│
|
|
91
|
+
├── 🧩 widgets/ # Widgets layer - composite UI blocks
|
|
92
|
+
│ ├── Header/ # Header widget
|
|
93
|
+
│ └── layouts/ # Layout components
|
|
94
|
+
│
|
|
95
|
+
├── ⚙️ features/ # Features layer - user scenarios
|
|
96
|
+
│ └── .gitkeep # (Ready for your features)
|
|
97
|
+
│
|
|
98
|
+
├── 🗂️ entities/ # Entities layer - business entities
|
|
99
|
+
│ └── .gitkeep # (Ready for your entities)
|
|
100
|
+
│
|
|
101
|
+
└── 🔧 shared/ # Shared layer - reusable code
|
|
102
|
+
├── api/ # API client configuration
|
|
103
|
+
├── store/ # Zustand stores
|
|
104
|
+
└── ui/ # UI kit components
|
|
50
105
|
```
|
|
51
106
|
|
|
52
|
-
###
|
|
107
|
+
### Layer Responsibilities
|
|
53
108
|
|
|
54
|
-
|
|
109
|
+
| Layer | Purpose | Examples |
|
|
110
|
+
|-------|---------|----------|
|
|
111
|
+
| **app** | Application initialization and setup | Providers, global styles, routing setup |
|
|
112
|
+
| **pages** | Route-level components | HomePage, AboutPage, ProfilePage |
|
|
113
|
+
| **widgets** | Complex composite components | Header, Footer, Sidebar, UserCard |
|
|
114
|
+
| **features** | User interactions and business features | LoginForm, CommentsList, ProductFilters |
|
|
115
|
+
| **entities** | Business domain models | User, Product, Order |
|
|
116
|
+
| **shared** | Reusable utilities and UI | Button, Input, formatDate, API client |
|
|
55
117
|
|
|
56
|
-
|
|
118
|
+
---
|
|
57
119
|
|
|
58
|
-
|
|
59
|
-
# Create a new React project with FSD architecture
|
|
60
|
-
create-fsd my-awesome-app --template react
|
|
120
|
+
## 🎯 What's Included
|
|
61
121
|
|
|
62
|
-
|
|
63
|
-
create-fsd my-awesome-app -t react
|
|
64
|
-
```
|
|
122
|
+
### Example Implementations
|
|
65
123
|
|
|
66
|
-
|
|
124
|
+
The generated project includes working examples for all included libraries:
|
|
67
125
|
|
|
68
|
-
|
|
126
|
+
- ✅ **Routing** - Multi-page setup with React Router
|
|
127
|
+
- ✅ **State Management** - Counter example with Zustand
|
|
128
|
+
- ✅ **API Integration** - Axios client with interceptors
|
|
129
|
+
- ✅ **Data Fetching** - React Query setup and usage
|
|
130
|
+
- ✅ **Internationalization** - i18n configuration with language switching
|
|
131
|
+
- ✅ **Styling** - TailwindCSS components and utilities
|
|
132
|
+
- ✅ **Code Quality** - ESLint rules configured
|
|
69
133
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
│ └── layouts/
|
|
82
|
-
├── features/ # Business features (empty, ready for your code)
|
|
83
|
-
├── entities/ # Business entities (empty, ready for your code)
|
|
84
|
-
└── shared/ # Shared code
|
|
85
|
-
├── api/ # API client & query configuration
|
|
86
|
-
├── store/ # Zustand stores
|
|
87
|
-
└── ui/ # Reusable UI components
|
|
88
|
-
```
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 🛠️ Available Templates
|
|
137
|
+
|
|
138
|
+
| Template | Status | Description |
|
|
139
|
+
|----------|--------|-------------|
|
|
140
|
+
| **React** | ✅ Available | React 18 + Vite + FSD architecture |
|
|
141
|
+
| **Vue** | 🔜 Coming Soon | Vue 3 + Vite + FSD architecture |
|
|
142
|
+
| **Next.js** | 🔜 Coming Soon | Next.js + FSD architecture |
|
|
143
|
+
| **Nuxt** | 🔜 Coming Soon | Nuxt 3 + FSD architecture |
|
|
144
|
+
| **Svelte** | 🔜 Coming Soon | Svelte + Vite + FSD architecture |
|
|
89
145
|
|
|
90
|
-
|
|
146
|
+
---
|
|
91
147
|
|
|
92
|
-
|
|
148
|
+
## 📋 CLI Options
|
|
93
149
|
|
|
94
150
|
```bash
|
|
95
|
-
|
|
151
|
+
create-fsd <project-name> [options]
|
|
96
152
|
```
|
|
97
153
|
|
|
98
|
-
###
|
|
154
|
+
### Options
|
|
99
155
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
- Valid author information
|
|
156
|
+
| Option | Alias | Description | Default |
|
|
157
|
+
|--------|-------|-------------|---------|
|
|
158
|
+
| `--template <name>` | `-t` | Template to use | `react` |
|
|
104
159
|
|
|
105
|
-
###
|
|
160
|
+
### Examples
|
|
106
161
|
|
|
107
162
|
```bash
|
|
108
|
-
|
|
109
|
-
|
|
163
|
+
# Create project with React template (default)
|
|
164
|
+
npx @t1ep1l0t/create-fsd my-app
|
|
110
165
|
|
|
111
|
-
|
|
166
|
+
# Explicitly specify template
|
|
167
|
+
npx @t1ep1l0t/create-fsd my-app --template react
|
|
112
168
|
|
|
113
|
-
|
|
114
|
-
|
|
169
|
+
# Short form
|
|
170
|
+
npx @t1ep1l0t/create-fsd my-app -t react
|
|
115
171
|
```
|
|
116
172
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
### Install dependencies
|
|
173
|
+
---
|
|
120
174
|
|
|
121
|
-
|
|
122
|
-
npm install
|
|
123
|
-
```
|
|
175
|
+
## 🎓 Learn More
|
|
124
176
|
|
|
125
|
-
|
|
177
|
+
- [Feature-Sliced Design Documentation](https://feature-sliced.design/)
|
|
178
|
+
- [React Documentation](https://react.dev/)
|
|
179
|
+
- [Vite Documentation](https://vitejs.dev/)
|
|
180
|
+
- [TailwindCSS Documentation](https://tailwindcss.com/)
|
|
126
181
|
|
|
127
|
-
|
|
128
|
-
npm test
|
|
129
|
-
# or
|
|
130
|
-
node bin/cli.js test-project --template react
|
|
131
|
-
```
|
|
182
|
+
---
|
|
132
183
|
|
|
133
|
-
|
|
184
|
+
## 🤝 Contributing
|
|
134
185
|
|
|
135
|
-
|
|
136
|
-
2. Add all necessary files for the template
|
|
137
|
-
3. Update CLI help text if needed
|
|
186
|
+
Contributions are welcome! Feel free to:
|
|
138
187
|
|
|
139
|
-
|
|
188
|
+
- Report bugs
|
|
189
|
+
- Suggest new features
|
|
190
|
+
- Submit pull requests
|
|
191
|
+
- Add new framework templates
|
|
140
192
|
|
|
141
|
-
|
|
193
|
+
---
|
|
142
194
|
|
|
143
|
-
|
|
144
|
-
2. Create example usage in the appropriate FSD layer
|
|
145
|
-
3. Add configuration if needed (e.g., in `src/app/providers/`)
|
|
146
|
-
4. Update the template README with the new library
|
|
195
|
+
## 📄 License
|
|
147
196
|
|
|
148
|
-
|
|
197
|
+
MIT © [t1ep1l0t](https://github.com/t1ep1l0t)
|
|
149
198
|
|
|
150
|
-
|
|
151
|
-
```json
|
|
152
|
-
"react-hook-form": "^7.50.0"
|
|
153
|
-
```
|
|
199
|
+
---
|
|
154
200
|
|
|
155
|
-
|
|
201
|
+
<div align="center">
|
|
156
202
|
|
|
157
|
-
|
|
203
|
+
**Made with ❤️ for the developer community**
|
|
158
204
|
|
|
159
|
-
|
|
205
|
+
[Report Bug](https://github.com/t1ep1l0t/create-fsd/issues) · [Request Feature](https://github.com/t1ep1l0t/create-fsd/issues)
|
|
160
206
|
|
|
161
|
-
|
|
207
|
+
</div>
|
package/package.json
CHANGED
|
@@ -3,9 +3,14 @@ import globals from 'globals'
|
|
|
3
3
|
import react from 'eslint-plugin-react'
|
|
4
4
|
import reactHooks from 'eslint-plugin-react-hooks'
|
|
5
5
|
import reactRefresh from 'eslint-plugin-react-refresh'
|
|
6
|
+
import reactQuery from '@tanstack/eslint-plugin-query'
|
|
7
|
+
import importPlugin from 'eslint-plugin-import'
|
|
8
|
+
import jsxA11y from 'eslint-plugin-jsx-a11y'
|
|
9
|
+
import prettier from 'eslint-plugin-prettier'
|
|
10
|
+
import prettierConfig from 'eslint-config-prettier'
|
|
6
11
|
|
|
7
12
|
export default [
|
|
8
|
-
{ ignores: ['dist'] },
|
|
13
|
+
{ ignores: ['dist', 'node_modules', '.vite'] },
|
|
9
14
|
{
|
|
10
15
|
files: ['**/*.{js,jsx}'],
|
|
11
16
|
languageOptions: {
|
|
@@ -17,23 +22,117 @@ export default [
|
|
|
17
22
|
sourceType: 'module',
|
|
18
23
|
},
|
|
19
24
|
},
|
|
20
|
-
settings: {
|
|
25
|
+
settings: {
|
|
26
|
+
react: { version: '18.3' },
|
|
27
|
+
'import/resolver': {
|
|
28
|
+
node: {
|
|
29
|
+
extensions: ['.js', '.jsx'],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
21
33
|
plugins: {
|
|
22
34
|
react,
|
|
23
35
|
'react-hooks': reactHooks,
|
|
24
36
|
'react-refresh': reactRefresh,
|
|
37
|
+
'@tanstack/query': reactQuery,
|
|
38
|
+
import: importPlugin,
|
|
39
|
+
'jsx-a11y': jsxA11y,
|
|
40
|
+
prettier,
|
|
25
41
|
},
|
|
26
42
|
rules: {
|
|
27
43
|
...js.configs.recommended.rules,
|
|
28
44
|
...react.configs.recommended.rules,
|
|
29
45
|
...react.configs['jsx-runtime'].rules,
|
|
30
46
|
...reactHooks.configs.recommended.rules,
|
|
47
|
+
...jsxA11y.configs.recommended.rules,
|
|
48
|
+
...prettierConfig.rules,
|
|
49
|
+
|
|
50
|
+
// React rules
|
|
31
51
|
'react/jsx-no-target-blank': 'off',
|
|
52
|
+
'react/prop-types': 'off',
|
|
32
53
|
'react-refresh/only-export-components': [
|
|
33
54
|
'warn',
|
|
34
55
|
{ allowConstantExport: true },
|
|
35
56
|
],
|
|
36
|
-
|
|
57
|
+
|
|
58
|
+
// React Query rules
|
|
59
|
+
'@tanstack/query/exhaustive-deps': 'error',
|
|
60
|
+
'@tanstack/query/no-rest-destructuring': 'warn',
|
|
61
|
+
'@tanstack/query/stable-query-client': 'error',
|
|
62
|
+
|
|
63
|
+
// Import rules
|
|
64
|
+
'import/order': [
|
|
65
|
+
'error',
|
|
66
|
+
{
|
|
67
|
+
groups: [
|
|
68
|
+
'builtin',
|
|
69
|
+
'external',
|
|
70
|
+
'internal',
|
|
71
|
+
['parent', 'sibling'],
|
|
72
|
+
'index',
|
|
73
|
+
'object',
|
|
74
|
+
'type',
|
|
75
|
+
],
|
|
76
|
+
'newlines-between': 'always',
|
|
77
|
+
alphabetize: {
|
|
78
|
+
order: 'asc',
|
|
79
|
+
caseInsensitive: true,
|
|
80
|
+
},
|
|
81
|
+
pathGroups: [
|
|
82
|
+
{
|
|
83
|
+
pattern: 'react',
|
|
84
|
+
group: 'external',
|
|
85
|
+
position: 'before',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
pattern: '@app/**',
|
|
89
|
+
group: 'internal',
|
|
90
|
+
position: 'before',
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
pattern: '@pages/**',
|
|
94
|
+
group: 'internal',
|
|
95
|
+
position: 'before',
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
pattern: '@widgets/**',
|
|
99
|
+
group: 'internal',
|
|
100
|
+
position: 'before',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
pattern: '@features/**',
|
|
104
|
+
group: 'internal',
|
|
105
|
+
position: 'before',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
pattern: '@entities/**',
|
|
109
|
+
group: 'internal',
|
|
110
|
+
position: 'before',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
pattern: '@shared/**',
|
|
114
|
+
group: 'internal',
|
|
115
|
+
position: 'before',
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
pathGroupsExcludedImportTypes: ['react'],
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
'import/no-unresolved': 'off',
|
|
122
|
+
'import/no-duplicates': 'error',
|
|
123
|
+
'import/newline-after-import': 'error',
|
|
124
|
+
|
|
125
|
+
// Accessibility rules
|
|
126
|
+
'jsx-a11y/anchor-is-valid': [
|
|
127
|
+
'error',
|
|
128
|
+
{
|
|
129
|
+
components: ['Link'],
|
|
130
|
+
specialLink: ['to'],
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
|
|
134
|
+
// Prettier integration
|
|
135
|
+
'prettier/prettier': 'error',
|
|
37
136
|
},
|
|
38
137
|
},
|
|
39
138
|
]
|
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
"dev": "vite",
|
|
8
8
|
"build": "vite build",
|
|
9
9
|
"lint": "eslint .",
|
|
10
|
+
"lint:fix": "eslint . --fix",
|
|
11
|
+
"format": "prettier --write \"src/**/*.{js,jsx,json,css}\"",
|
|
12
|
+
"format:check": "prettier --check \"src/**/*.{js,jsx,json,css}\"",
|
|
10
13
|
"preview": "vite preview"
|
|
11
14
|
},
|
|
12
15
|
"dependencies": {
|
|
@@ -16,8 +19,13 @@
|
|
|
16
19
|
"zustand": "^4.5.0",
|
|
17
20
|
"axios": "^1.6.7",
|
|
18
21
|
"i18next": "^23.8.2",
|
|
22
|
+
"i18next-browser-languagedetector": "^8.2.0",
|
|
23
|
+
"i18next-http-backend": "^3.0.2",
|
|
19
24
|
"react-i18next": "^14.0.5",
|
|
20
|
-
"@tanstack/react-query": "^5.22.2"
|
|
25
|
+
"@tanstack/react-query": "^5.22.2",
|
|
26
|
+
"classnames": "^2.5.1",
|
|
27
|
+
"react-hook-form": "^7.65.0",
|
|
28
|
+
"@hookform/resolvers": "^5.2.2"
|
|
21
29
|
},
|
|
22
30
|
"devDependencies": {
|
|
23
31
|
"@types/react": "^18.3.12",
|
|
@@ -30,6 +38,13 @@
|
|
|
30
38
|
"eslint-plugin-react": "^7.37.2",
|
|
31
39
|
"eslint-plugin-react-hooks": "^5.0.0",
|
|
32
40
|
"eslint-plugin-react-refresh": "^0.4.16",
|
|
41
|
+
"@tanstack/eslint-plugin-query": "^5.62.3",
|
|
42
|
+
"eslint-plugin-import": "^2.31.0",
|
|
43
|
+
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
44
|
+
"eslint-config-prettier": "^9.1.0",
|
|
45
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
46
|
+
"prettier": "^3.4.2",
|
|
47
|
+
"prettier-plugin-tailwindcss": "^0.6.9",
|
|
33
48
|
"@tailwindcss/vite": "^4.0.0",
|
|
34
49
|
"tailwindcss": "^4.0.0"
|
|
35
50
|
}
|
|
@@ -1,40 +1,37 @@
|
|
|
1
1
|
import i18n from 'i18next';
|
|
2
2
|
import { initReactI18next } from 'react-i18next';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
en: {
|
|
6
|
-
translation: {
|
|
7
|
-
welcome: 'Welcome to FSD React App',
|
|
8
|
-
home: 'Home',
|
|
9
|
-
about: 'About',
|
|
10
|
-
counter: 'Counter',
|
|
11
|
-
increment: 'Increment',
|
|
12
|
-
decrement: 'Decrement',
|
|
13
|
-
reset: 'Reset',
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
ru: {
|
|
17
|
-
translation: {
|
|
18
|
-
welcome: 'Добро пожаловать в FSD React приложение',
|
|
19
|
-
home: 'Главная',
|
|
20
|
-
about: 'О нас',
|
|
21
|
-
counter: 'Счетчик',
|
|
22
|
-
increment: 'Увеличить',
|
|
23
|
-
decrement: 'Уменьшить',
|
|
24
|
-
reset: 'Сбросить',
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
};
|
|
3
|
+
import LanguageDetector from 'i18next-browser-languagedetector';
|
|
4
|
+
import Backend from 'i18next-http-backend';
|
|
28
5
|
|
|
29
6
|
i18n
|
|
7
|
+
.use(Backend)
|
|
8
|
+
.use(LanguageDetector)
|
|
30
9
|
.use(initReactI18next)
|
|
31
10
|
.init({
|
|
32
|
-
resources,
|
|
33
11
|
lng: 'en',
|
|
34
12
|
fallbackLng: 'en',
|
|
35
13
|
interpolation: {
|
|
36
14
|
escapeValue: false,
|
|
37
15
|
},
|
|
16
|
+
detection: {
|
|
17
|
+
order: ['path', 'cookie', 'localStorage'],
|
|
18
|
+
caches: ['cookie', 'localStorage'],
|
|
19
|
+
},
|
|
20
|
+
fallbackNS: 'basic',
|
|
21
|
+
ns: ['basic'],
|
|
22
|
+
defaultNS: 'basic',
|
|
23
|
+
backend: {
|
|
24
|
+
loadPath: '/locales/{{lng}}/{{ns}}.json',
|
|
25
|
+
},
|
|
26
|
+
missingKeyHandler: (lng, ns, key) => {
|
|
27
|
+
console.warn(`Missing translation: ${lng}:${ns}:${key}`);
|
|
28
|
+
},
|
|
38
29
|
});
|
|
39
30
|
|
|
31
|
+
document.documentElement.lang = i18n.language;
|
|
32
|
+
|
|
33
|
+
i18n.on('languageChanged', (lng) => {
|
|
34
|
+
document.documentElement.lang = lng;
|
|
35
|
+
});
|
|
36
|
+
|
|
40
37
|
export default i18n;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
import
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import { fileURLToPath } from 'url'
|
|
3
|
+
|
|
4
|
+
import tailwindcss from '@tailwindcss/vite'
|
|
5
|
+
import react from '@vitejs/plugin-react'
|
|
6
|
+
import { defineConfig } from 'vite'
|
|
7
|
+
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
5
9
|
|
|
6
10
|
export default defineConfig({
|
|
7
11
|
plugins: [react(), tailwindcss()],
|
|
@@ -16,4 +20,4 @@ export default defineConfig({
|
|
|
16
20
|
'@shared': path.resolve(__dirname, './src/shared'),
|
|
17
21
|
},
|
|
18
22
|
},
|
|
19
|
-
})
|
|
23
|
+
})
|