@t1ep1l0t/create-fsd 1.0.1 → 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 +5 -5
- 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,8 +1,8 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
# 🚀 create-fsd
|
|
3
|
+
# 🚀 @t1ep1l0t/create-fsd
|
|
4
4
|
|
|
5
|
-
**Scaffold modern
|
|
5
|
+
**Scaffold modern frontend applications with Feature-Sliced Design architecture**
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/@t1ep1l0t/create-fsd)
|
|
8
8
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
## 📖 About
|
|
16
16
|
|
|
17
|
-
|
|
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
18
|
|
|
19
|
-
> 🎯 Currently supports **React** template. More frameworks (Vue, Next
|
|
19
|
+
> 🎯 Currently supports **React** template. More frameworks (Vue, Next, Nuxt, Svelte) coming soon!
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
- **Axios** - HTTP client with interceptors configured
|
|
39
39
|
- **React Query** - Powerful server state management
|
|
40
40
|
- **i18next** - Internationalization (i18n) support
|
|
41
|
-
- **ESLint** - Code quality and consistency
|
|
41
|
+
- **ESLint & Prettier** - Code quality and consistency
|
|
42
42
|
|
|
43
43
|
### 🎨 **Developer Experience**
|
|
44
44
|
- Path aliases configured (`@app`, `@pages`, `@widgets`, `@features`, `@entities`, `@shared`)
|
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
|
+
})
|