@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 CHANGED
@@ -1,8 +1,8 @@
1
1
  <div align="center">
2
2
 
3
- # 🚀 create-fsd
3
+ # 🚀 @t1ep1l0t/create-fsd
4
4
 
5
- **Scaffold modern React applications with Feature-Sliced Design architecture**
5
+ **Scaffold modern frontend applications with Feature-Sliced Design architecture**
6
6
 
7
7
  [![npm version](https://img.shields.io/npm/v/@t1ep1l0t/create-fsd.svg)](https://www.npmjs.com/package/@t1ep1l0t/create-fsd)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
@@ -14,9 +14,9 @@
14
14
 
15
15
  ## 📖 About
16
16
 
17
- **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!
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.js, Nuxt, Svelte) coming soon!
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t1ep1l0t/create-fsd",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "CLI tool to create React projects with FSD architecture",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,12 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ indent_size = 2
7
+ indent_style = space
8
+ insert_final_newline = true
9
+ trim_trailing_whitespace = true
10
+
11
+ [*.md]
12
+ trim_trailing_whitespace = false
@@ -0,0 +1,7 @@
1
+ node_modules
2
+ dist
3
+ build
4
+ .vite
5
+ coverage
6
+ *.min.js
7
+ package-lock.json
@@ -0,0 +1,10 @@
1
+ {
2
+ "semi": false,
3
+ "singleQuote": true,
4
+ "tabWidth": 2,
5
+ "trailingComma": "es5",
6
+ "printWidth": 80,
7
+ "arrowParens": "always",
8
+ "endOfLine": "lf",
9
+ "plugins": ["prettier-plugin-tailwindcss"]
10
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "recommendations": [
3
+ "dbaeumer.vscode-eslint",
4
+ "esbenp.prettier-vscode",
5
+ "bradlc.vscode-tailwindcss"
6
+ ]
7
+ }
@@ -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: { react: { version: '18.3' } },
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
- 'react/prop-types': 'off',
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
  }
@@ -0,0 +1,9 @@
1
+ {
2
+ "welcome": "Welcome to FSD React App",
3
+ "home": "Home",
4
+ "about": "About",
5
+ "counter": "Counter",
6
+ "increment": "Increment",
7
+ "decrement": "Decrement",
8
+ "reset": "Reset"
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "welcome": "Добро пожаловать в FSD React приложение",
3
+ "home": "Главная",
4
+ "about": "О нас",
5
+ "counter": "Счетчик",
6
+ "increment": "Увеличить",
7
+ "decrement": "Уменьшить",
8
+ "reset": "Сбросить"
9
+ }
@@ -1,40 +1,37 @@
1
1
  import i18n from 'i18next';
2
2
  import { initReactI18next } from 'react-i18next';
3
-
4
- const resources = {
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 { defineConfig } from 'vite';
2
- import react from '@vitejs/plugin-react';
3
- import tailwindcss from '@tailwindcss/vite';
4
- import path from 'path';
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
+ })