nsbp-cli 0.2.27 → 0.2.30
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 +1 -1
- package/bin/nsbp.js +97 -74
- package/package.json +1 -1
- package/templates/basic/.husky/README.md +47 -0
- package/templates/basic/.husky/commit-msg +17 -0
- package/templates/basic/.husky/pre-commit +4 -0
- package/templates/basic/.husky/pre-push +4 -0
- package/templates/basic/.prettierrc.js +13 -0
- package/templates/basic/README.md +43 -0
- package/templates/basic/docs/DEVELOPMENT_GUIDE.md +290 -0
- package/templates/basic/docs/ESLINT_AND_PRETTIER.md +184 -0
- package/templates/basic/docs/HUSKY_9_UPGRADE.md +76 -0
- package/templates/basic/docs/HUSKY_ESLINT_SETUP.md +293 -0
- package/templates/basic/docs/SETUP_GIT_HOOKS.md +106 -0
- package/templates/basic/eslint.config.js +98 -0
- package/templates/basic/gitignore +3 -0
- package/templates/basic/package.json +27 -3
- package/templates/basic/scripts/setup-husky.js +24 -0
- package/templates/basic/src/Routers.tsx +4 -5
- package/templates/basic/src/client/index.tsx +5 -1
- package/templates/basic/src/component/Header.tsx +10 -10
- package/templates/basic/src/component/Layout.tsx +9 -3
- package/templates/basic/src/component/Theme.tsx +5 -1
- package/templates/basic/src/containers/Home.tsx +141 -76
- package/templates/basic/src/containers/Photo.tsx +30 -18
- package/templates/basic/src/externals/window.d.ts +3 -1
- package/templates/basic/src/reducers/photo.ts +7 -2
- package/templates/basic/src/server/index.ts +35 -26
- package/templates/basic/src/server/photo.ts +14 -7
- package/templates/basic/src/server/utils.tsx +9 -7
- package/templates/basic/src/services/home.ts +1 -1
- package/templates/basic/src/services/photo.ts +28 -30
- package/templates/basic/src/store/constants.ts +1 -1
- package/templates/basic/src/store/index.ts +2 -1
- package/templates/basic/src/styled/component/header.ts +5 -1
- package/templates/basic/src/styled/home.ts +100 -24
- package/templates/basic/src/styled/photo.ts +2 -2
- package/templates/basic/src/utils/config.ts +1 -1
- package/templates/basic/src/utils/fetch.ts +4 -8
- package/templates/basic/src/utils/index.ts +1 -1
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# Husky 和 ESLint 配置总结
|
|
2
|
+
|
|
3
|
+
> **Husky 9.x 升级说明**:Husky 9.x 简化了安装方式,无需手动运行 `husky install`。Hooks 在 `pnpm install` 时自动创建。
|
|
4
|
+
|
|
5
|
+
## ✅ 已完成的配置
|
|
6
|
+
|
|
7
|
+
### 1. 创建的配置文件
|
|
8
|
+
|
|
9
|
+
#### ESLint 配置
|
|
10
|
+
- **`.eslintrc.js`** - ESLint 主配置文件
|
|
11
|
+
- TypeScript 支持(@typescript-eslint/parser)
|
|
12
|
+
- React 支持(eslint-plugin-react)
|
|
13
|
+
- React Hooks 支持(eslint-plugin-react-hooks)
|
|
14
|
+
- Prettier 集成(eslint-config-prettier)
|
|
15
|
+
|
|
16
|
+
- **`.eslintignore`** - ESLint 忽略规则
|
|
17
|
+
- 忽略构建产物(build, dist, public)
|
|
18
|
+
- 忽略缓存(.temp_cache)
|
|
19
|
+
- 忽略 Webpack 配置文件
|
|
20
|
+
|
|
21
|
+
#### Prettier 配置
|
|
22
|
+
- **`.prettierrc.js`** - Prettier 格式化配置
|
|
23
|
+
- 2 空格缩进
|
|
24
|
+
- 单引号
|
|
25
|
+
- 无分号
|
|
26
|
+
- 100 字符换行
|
|
27
|
+
- Unix 换行符
|
|
28
|
+
- import 组织(prettier-plugin-organize-imports)
|
|
29
|
+
|
|
30
|
+
#### Husky Git Hooks
|
|
31
|
+
- **`.husky/pre-commit`** - 提交前钩子
|
|
32
|
+
- 运行 `pnpm run lint-staged`
|
|
33
|
+
- 自动修复和格式化暂存文件
|
|
34
|
+
|
|
35
|
+
- **`.husky/pre-push`** - 推送前钩子
|
|
36
|
+
- 运行完整 lint 检查
|
|
37
|
+
- 防止推送有问题的代码
|
|
38
|
+
|
|
39
|
+
- **`.husky/commit-msg`** - 提交信息验证
|
|
40
|
+
- 验证 Conventional Commits 格式
|
|
41
|
+
- 支持的类型:feat, fix, docs, style, refactor, test, chore, build, ci, perf, revert
|
|
42
|
+
|
|
43
|
+
- **`.husky/README.md`** - Git hooks 使用说明
|
|
44
|
+
|
|
45
|
+
#### VSCode 配置
|
|
46
|
+
- **`.vscode/settings.json`** - 编辑器设置
|
|
47
|
+
- 保存时自动格式化
|
|
48
|
+
- 保存时自动修复 ESLint 问题
|
|
49
|
+
- 配置 Prettier 作为默认格式化器
|
|
50
|
+
- TypeScript 和 React 文件支持
|
|
51
|
+
|
|
52
|
+
- **`.vscode/extensions.json`** - 推荐扩展
|
|
53
|
+
- ESLint
|
|
54
|
+
- Prettier
|
|
55
|
+
- TypeScript Importer
|
|
56
|
+
- Error Lens
|
|
57
|
+
|
|
58
|
+
- **`.vscode/.gitignore`** - Git 忽略规则
|
|
59
|
+
- 允许提交 settings.json 和扩展配置
|
|
60
|
+
- 忽略 workspace 配置
|
|
61
|
+
|
|
62
|
+
### 2. 更新的文件
|
|
63
|
+
|
|
64
|
+
#### package.json
|
|
65
|
+
- **添加的依赖**:
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
69
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
70
|
+
"eslint": "^9.0.0",
|
|
71
|
+
"eslint-config-prettier": "^9.0.0",
|
|
72
|
+
"eslint-plugin-react": "^7.37.0",
|
|
73
|
+
"eslint-plugin-react-hooks": "^5.0.0",
|
|
74
|
+
"husky": "^9.0.0",
|
|
75
|
+
"lint-staged": "^15.0.0",
|
|
76
|
+
"prettier-plugin-organize-imports": "^4.0.0"
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
- **添加的脚本**:
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"lint": "eslint src --ext .ts,.tsx,.js,.jsx",
|
|
84
|
+
"lint:fix": "eslint src --ext .ts,.tsx,.js,.jsx --fix",
|
|
85
|
+
"prepare": "husky"
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- **添加的 lint-staged 配置**:
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"*.{ts,tsx,js,jsx}": [
|
|
93
|
+
"eslint --fix",
|
|
94
|
+
"prettier --write"
|
|
95
|
+
],
|
|
96
|
+
"*.{css,less,scss}": [
|
|
97
|
+
"prettier --write"
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
#### .gitignore
|
|
103
|
+
- 添加了 `.husky/_` 忽略规则(Husky 内部文件)
|
|
104
|
+
|
|
105
|
+
#### README.md
|
|
106
|
+
- 添加了快速开始部分
|
|
107
|
+
- 添加了开发工具说明
|
|
108
|
+
- 添加了文档链接
|
|
109
|
+
|
|
110
|
+
### 3. 创建的文档
|
|
111
|
+
|
|
112
|
+
- **`docs/ESLINT_AND_PRETTIER.md`** - ESLint 和 Prettier 详细配置说明
|
|
113
|
+
- **`docs/SETUP_GIT_HOOKS.md`** - Git hooks 配置和使用说明
|
|
114
|
+
- **`docs/DEVELOPMENT_GUIDE.md`** - 完整开发指南
|
|
115
|
+
- **`docs/HUSKY_ESLINT_SETUP.md`** - 本文档
|
|
116
|
+
|
|
117
|
+
### 4. 创建的辅助脚本
|
|
118
|
+
|
|
119
|
+
- **`scripts/setup-husky.js`** - Husky 初始化脚本(备用)
|
|
120
|
+
|
|
121
|
+
## 📦 依赖版本
|
|
122
|
+
|
|
123
|
+
| 包名 | 版本 | 用途 |
|
|
124
|
+
|------|------|------|
|
|
125
|
+
| eslint | ^9.0.0 | 代码质量检查 |
|
|
126
|
+
| eslint-config-prettier | ^9.0.0 | Prettier 集成 |
|
|
127
|
+
| eslint-plugin-react | ^7.37.0 | React 规则 |
|
|
128
|
+
| eslint-plugin-react-hooks | ^5.0.0 | React Hooks 规则 |
|
|
129
|
+
| @typescript-eslint/eslint-plugin | ^8.0.0 | TypeScript 规则 |
|
|
130
|
+
| @typescript-eslint/parser | ^8.0.0 | TypeScript 解析 |
|
|
131
|
+
| prettier | ^3.3.0 | 代码格式化 |
|
|
132
|
+
| prettier-plugin-organize-imports | ^4.0.0 | import 排序 |
|
|
133
|
+
| husky | ^9.0.0 | Git hooks |
|
|
134
|
+
| lint-staged | ^15.0.0 | 暂存文件处理 |
|
|
135
|
+
|
|
136
|
+
## 🔧 ESLint 规则配置
|
|
137
|
+
|
|
138
|
+
### 主要规则
|
|
139
|
+
|
|
140
|
+
```javascript
|
|
141
|
+
{
|
|
142
|
+
'prettier/prettier': 'error', // Prettier 冲突报错
|
|
143
|
+
'react/react-in-jsx-scope': 'off', // 不需要 React 导入
|
|
144
|
+
'react/prop-types': 'off', // 使用 TypeScript
|
|
145
|
+
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
146
|
+
'@typescript-eslint/no-explicit-any': 'warn', // 允许 any
|
|
147
|
+
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
|
|
148
|
+
'react-hooks/rules-of-hooks': 'error', // Hooks 规则
|
|
149
|
+
'react-hooks/exhaustive-deps': 'warn', // 依赖检查
|
|
150
|
+
'no-console': ['warn', { allow: ['warn', 'error'] }] // 允许 console
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## 🎨 Prettier 配置
|
|
155
|
+
|
|
156
|
+
```javascript
|
|
157
|
+
{
|
|
158
|
+
semi: false, // 不使用分号
|
|
159
|
+
singleQuote: true, // 使用单引号
|
|
160
|
+
tabWidth: 2, // 2 空格缩进
|
|
161
|
+
trailingComma: 'es5', // ES5 尾部逗号
|
|
162
|
+
printWidth: 100, // 100 字符换行
|
|
163
|
+
arrowParens: 'always', // 箭头函数加括号
|
|
164
|
+
endOfLine: 'lf', // Unix 换行符
|
|
165
|
+
plugins: ['prettier-plugin-organize-imports'],
|
|
166
|
+
importOrder: ['^react', '^@/(.*)$', '^[./]'],
|
|
167
|
+
importOrderSeparation: true,
|
|
168
|
+
importOrderSortSpecifiers: true
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## 🔄 Git Hooks 工作流程
|
|
173
|
+
|
|
174
|
+
### 提交前(pre-commit)
|
|
175
|
+
|
|
176
|
+
1. `lint-staged` 检测暂存文件
|
|
177
|
+
2. 对 TypeScript/JS 文件运行 `eslint --fix`
|
|
178
|
+
3. 对所有文件运行 `prettier --write`
|
|
179
|
+
4. 重新暂存修复后的文件
|
|
180
|
+
5. 如果有错误,阻止提交
|
|
181
|
+
|
|
182
|
+
### 推送前(pre-push)
|
|
183
|
+
|
|
184
|
+
1. 运行完整 `pnpm run lint`
|
|
185
|
+
2. 如果有错误,阻止推送
|
|
186
|
+
|
|
187
|
+
### 提交信息验证(commit-msg)
|
|
188
|
+
|
|
189
|
+
1. 检查提交信息格式:`<type>(<scope>): <subject>`
|
|
190
|
+
2. 支持的类型:feat, fix, docs, style, refactor, test, chore, build, ci, perf, revert
|
|
191
|
+
3. 如果格式不正确,阻止提交并显示帮助信息
|
|
192
|
+
|
|
193
|
+
## 📝 提交信息示例
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# 功能
|
|
197
|
+
git commit -m "feat(core): add SSR data preloading support"
|
|
198
|
+
|
|
199
|
+
# Bug 修复
|
|
200
|
+
git commit -m "fix(client): resolve hydration mismatch error"
|
|
201
|
+
|
|
202
|
+
# 文档
|
|
203
|
+
git commit -m "docs(readme): update installation instructions"
|
|
204
|
+
|
|
205
|
+
# 样式
|
|
206
|
+
git commit -m "style: format code with prettier"
|
|
207
|
+
|
|
208
|
+
# 重构
|
|
209
|
+
git commit -m "refactor(components): simplify layout component"
|
|
210
|
+
|
|
211
|
+
# 测试
|
|
212
|
+
git commit -m "test(add): add unit tests for utils"
|
|
213
|
+
|
|
214
|
+
# 构建
|
|
215
|
+
git commit -m "build(webpack): optimize production bundle"
|
|
216
|
+
|
|
217
|
+
# CI
|
|
218
|
+
git commit -m "ci(github): update workflow configuration"
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## 🚀 使用方法
|
|
222
|
+
|
|
223
|
+
### 初始化(首次使用)
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
# 1. 安装依赖
|
|
227
|
+
pnpm install
|
|
228
|
+
|
|
229
|
+
# 2. 初始化 Git hooks(会自动运行 prepare 脚本)
|
|
230
|
+
pnpm run prepare
|
|
231
|
+
|
|
232
|
+
# 3. 验证 hooks 安装
|
|
233
|
+
ls .husky
|
|
234
|
+
# 应该看到: pre-commit, pre-push, commit-msg
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### 日常开发
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
# 开发
|
|
241
|
+
pnpm run dev
|
|
242
|
+
|
|
243
|
+
# 修改代码...
|
|
244
|
+
|
|
245
|
+
# 提交(hooks 自动运行)
|
|
246
|
+
git add .
|
|
247
|
+
git commit -m "feat: add new feature"
|
|
248
|
+
# pre-commit 自动运行: eslint --fix + prettier --write
|
|
249
|
+
|
|
250
|
+
# 如果有错误
|
|
251
|
+
pnpm run lint:fix
|
|
252
|
+
git add .
|
|
253
|
+
git commit --amend
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### 跳过 hooks(不推荐)
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
# 跳过 pre-commit
|
|
260
|
+
git commit --no-verify -m "message"
|
|
261
|
+
|
|
262
|
+
# 跳过 pre-push
|
|
263
|
+
git push --no-verify
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
⚠️ **警告**: 仅在紧急情况下使用!
|
|
267
|
+
|
|
268
|
+
## 📚 相关文档
|
|
269
|
+
|
|
270
|
+
- [README.md](../README.md) - 项目总览
|
|
271
|
+
- [ESLINT_AND_PRETTIER.md](./ESLINT_AND_PRETTIER.md) - ESLint 和 Prettier 详细配置
|
|
272
|
+
- [SETUP_GIT_HOOKS.md](./SETUP_GIT_HOOKS.md) - Git hooks 使用说明
|
|
273
|
+
- [DEVELOPMENT_GUIDE.md](./DEVELOPMENT_GUIDE.md) - 完整开发指南
|
|
274
|
+
|
|
275
|
+
## ✨ 特性
|
|
276
|
+
|
|
277
|
+
- ✅ TypeScript + React 完整支持
|
|
278
|
+
- ✅ 自动代码格式化(保存时自动运行)
|
|
279
|
+
- ✅ 提交前自动 lint 和格式化
|
|
280
|
+
- ✅ 提交信息格式验证
|
|
281
|
+
- ✅ VSCode 集成(自动格式化 + 修复)
|
|
282
|
+
- ✅ import 自动排序
|
|
283
|
+
- ✅ 支持 Conventional Commits
|
|
284
|
+
- ✅ React Hooks 规则检查
|
|
285
|
+
|
|
286
|
+
## 🎯 下一步建议
|
|
287
|
+
|
|
288
|
+
- [ ] 添加单元测试框架(Jest 或 Vitest)
|
|
289
|
+
- [ ] 配置 CI/CD 流程
|
|
290
|
+
- [ ] 添加代码覆盖率报告
|
|
291
|
+
- [ ] 配置自动化部署
|
|
292
|
+
- [ ] 添加 Commitlint 更严格的提交规范
|
|
293
|
+
- [ ] 配置 Release Please 自动化版本发布
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Git Hooks Setup
|
|
2
|
+
|
|
3
|
+
This project uses **Husky** for managing Git hooks.
|
|
4
|
+
|
|
5
|
+
## Quick Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install dependencies
|
|
9
|
+
pnpm install
|
|
10
|
+
|
|
11
|
+
# Initialize Git hooks (optional, runs automatically on prepare)
|
|
12
|
+
pnpm run prepare
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## How It Works
|
|
16
|
+
|
|
17
|
+
Husky automatically creates Git hooks in the `.husky` directory:
|
|
18
|
+
|
|
19
|
+
- **pre-commit**: Runs linting on staged files
|
|
20
|
+
- **pre-push**: Runs full lint check before pushing
|
|
21
|
+
- **commit-msg**: Validates commit message format
|
|
22
|
+
|
|
23
|
+
## Commit Message Format
|
|
24
|
+
|
|
25
|
+
Follow the [Conventional Commits](https://www.conventionalcommits.org/) specification:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
<type>(<scope>): <subject>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Type Options
|
|
32
|
+
|
|
33
|
+
- `feat`: A new feature
|
|
34
|
+
- `fix`: A bug fix
|
|
35
|
+
- `docs`: Documentation only changes
|
|
36
|
+
- `style`: Code style changes (formatting, etc.)
|
|
37
|
+
- `refactor`: Code change that neither fixes a bug nor adds a feature
|
|
38
|
+
- `test`: Adding missing tests or correcting existing tests
|
|
39
|
+
- `chore`: Maintenance tasks
|
|
40
|
+
- `build`: Changes that affect the build system
|
|
41
|
+
- `ci`: Changes to CI configuration files
|
|
42
|
+
- `perf`: Performance improvements
|
|
43
|
+
- `revert`: Reverts a previous commit
|
|
44
|
+
|
|
45
|
+
### Examples
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Feature
|
|
49
|
+
git commit -m "feat(core): add SSR data preloading support"
|
|
50
|
+
|
|
51
|
+
# Bug fix
|
|
52
|
+
git commit -m "fix(client): resolve hydration mismatch error"
|
|
53
|
+
|
|
54
|
+
# Documentation
|
|
55
|
+
git commit -m "docs(readme): update installation instructions"
|
|
56
|
+
|
|
57
|
+
# Style (formatting)
|
|
58
|
+
git commit -m "style: format code with prettier"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Available Scripts
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Lint all files
|
|
65
|
+
pnpm run lint
|
|
66
|
+
|
|
67
|
+
# Lint and fix issues
|
|
68
|
+
pnpm run lint:fix
|
|
69
|
+
|
|
70
|
+
# Format code
|
|
71
|
+
pnpm run format
|
|
72
|
+
|
|
73
|
+
# Reinstall Git hooks
|
|
74
|
+
pnpm run prepare
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Troubleshooting
|
|
78
|
+
|
|
79
|
+
### Hooks not working?
|
|
80
|
+
|
|
81
|
+
1. Make sure hooks are executable:
|
|
82
|
+
```bash
|
|
83
|
+
chmod +x .husky/*
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
2. Reinstall hooks:
|
|
87
|
+
```bash
|
|
88
|
+
pnpm run prepare
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
3. Check `.git/config` for hooks path:
|
|
92
|
+
```bash
|
|
93
|
+
git config core.hooksPath
|
|
94
|
+
```
|
|
95
|
+
Should output: `.husky`
|
|
96
|
+
|
|
97
|
+
### Skip hooks (not recommended)
|
|
98
|
+
|
|
99
|
+
If you need to bypass hooks temporarily:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
git commit --no-verify
|
|
103
|
+
git push --no-verify
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
⚠️ **Warning**: Use `--no-verify` only in emergencies!
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const js = require('@eslint/js')
|
|
2
|
+
const typescriptEslint = require('@typescript-eslint/eslint-plugin')
|
|
3
|
+
const typescriptParser = require('@typescript-eslint/parser')
|
|
4
|
+
const reactPlugin = require('eslint-plugin-react')
|
|
5
|
+
const reactHooksPlugin = require('eslint-plugin-react-hooks')
|
|
6
|
+
const prettierPlugin = require('eslint-plugin-prettier')
|
|
7
|
+
const prettierConfig = require('eslint-config-prettier')
|
|
8
|
+
|
|
9
|
+
module.exports = [
|
|
10
|
+
js.configs.recommended,
|
|
11
|
+
{
|
|
12
|
+
ignores: [
|
|
13
|
+
'node_modules/**',
|
|
14
|
+
'build/**',
|
|
15
|
+
'dist/**',
|
|
16
|
+
'.temp_cache/**',
|
|
17
|
+
'public/js/**',
|
|
18
|
+
'public/css/**',
|
|
19
|
+
'public/*.js',
|
|
20
|
+
'public/*.js.map',
|
|
21
|
+
'public/*.css.map',
|
|
22
|
+
'*.bundle.js',
|
|
23
|
+
'loadable-stats.json',
|
|
24
|
+
'coverage/**',
|
|
25
|
+
'.nyc_output/**',
|
|
26
|
+
'*.config.js',
|
|
27
|
+
'webpack.base.js',
|
|
28
|
+
'webpack.client.js',
|
|
29
|
+
'webpack.server.js',
|
|
30
|
+
'.prettierrc.js',
|
|
31
|
+
'cli/**',
|
|
32
|
+
'scripts/**'
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
files: ['**/*.{ts,tsx,js,jsx}'],
|
|
37
|
+
languageOptions: {
|
|
38
|
+
parser: typescriptParser,
|
|
39
|
+
parserOptions: {
|
|
40
|
+
ecmaFeatures: {
|
|
41
|
+
jsx: true
|
|
42
|
+
},
|
|
43
|
+
ecmaVersion: 'latest',
|
|
44
|
+
sourceType: 'module',
|
|
45
|
+
project: './tsconfig.json',
|
|
46
|
+
tsconfigRootDir: __dirname
|
|
47
|
+
},
|
|
48
|
+
globals: {
|
|
49
|
+
window: 'readonly',
|
|
50
|
+
document: 'readonly',
|
|
51
|
+
console: 'readonly',
|
|
52
|
+
process: 'readonly',
|
|
53
|
+
module: 'readonly',
|
|
54
|
+
require: 'readonly',
|
|
55
|
+
__dirname: 'readonly',
|
|
56
|
+
__filename: 'readonly',
|
|
57
|
+
global: 'readonly',
|
|
58
|
+
setTimeout: 'readonly',
|
|
59
|
+
clearTimeout: 'readonly',
|
|
60
|
+
setInterval: 'readonly',
|
|
61
|
+
clearInterval: 'readonly',
|
|
62
|
+
fetch: 'readonly',
|
|
63
|
+
setTimeout: 'readonly'
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
plugins: {
|
|
67
|
+
'@typescript-eslint': typescriptEslint,
|
|
68
|
+
react: reactPlugin,
|
|
69
|
+
'react-hooks': reactHooksPlugin,
|
|
70
|
+
prettier: prettierPlugin
|
|
71
|
+
},
|
|
72
|
+
settings: {
|
|
73
|
+
react: {
|
|
74
|
+
version: 'detect'
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
rules: {
|
|
78
|
+
...typescriptEslint.configs.recommended.rules,
|
|
79
|
+
...reactPlugin.configs.recommended.rules,
|
|
80
|
+
...reactHooksPlugin.configs.recommended.rules,
|
|
81
|
+
...prettierConfig.rules,
|
|
82
|
+
'prettier/prettier': 'error',
|
|
83
|
+
'react/react-in-jsx-scope': 'off',
|
|
84
|
+
'react/prop-types': 'off',
|
|
85
|
+
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
86
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
87
|
+
'@typescript-eslint/no-unused-vars': [
|
|
88
|
+
'warn',
|
|
89
|
+
{ argsIgnorePattern: '^_' }
|
|
90
|
+
],
|
|
91
|
+
'@typescript-eslint/no-unused-expressions': 'off',
|
|
92
|
+
'react-hooks/rules-of-hooks': 'error',
|
|
93
|
+
'react-hooks/exhaustive-deps': 'warn',
|
|
94
|
+
'no-console': ['warn', { allow: ['warn', 'error'] }],
|
|
95
|
+
'no-undef': 'off'
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
]
|
|
@@ -14,9 +14,12 @@
|
|
|
14
14
|
"build:server": "webpack --config config/webpack.server.js --mode production",
|
|
15
15
|
"build:client": "webpack --config config/webpack.client.js --mode production",
|
|
16
16
|
"start": "node ./scripts/start.js",
|
|
17
|
-
"clean": "rimraf build && rimraf public/js && rimraf public/css && rimraf public/client.* && rimraf public/*.js && rimraf public/*.js.map && rimraf public/*.txt && rimraf public/*.json && rimraf
|
|
17
|
+
"clean": "rimraf build && rimraf public/js && rimraf public/css && rimraf public/client.* && rimraf public/*.js && rimraf public/*.js.map && rimraf public/*.txt && rimraf public/*.json && rimraf config/.temp_cache",
|
|
18
18
|
"format": "prettier --write **/*.{js,css,less,scss,ts,tsx}",
|
|
19
|
-
"
|
|
19
|
+
"lint": "eslint src --ext .ts,.tsx,.js,.jsx",
|
|
20
|
+
"lint:fix": "eslint src --ext .ts,.tsx,.js,.jsx --fix",
|
|
21
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
22
|
+
"prepare": "husky"
|
|
20
23
|
},
|
|
21
24
|
"keywords": [
|
|
22
25
|
"react",
|
|
@@ -29,7 +32,7 @@
|
|
|
29
32
|
],
|
|
30
33
|
"author": "Erishen Sun",
|
|
31
34
|
"license": "ISC",
|
|
32
|
-
"packageManager": "pnpm@10.
|
|
35
|
+
"packageManager": "pnpm@10.28.0",
|
|
33
36
|
"dependencies": {
|
|
34
37
|
"@loadable/component": "^5.15.0",
|
|
35
38
|
"@loadable/server": "^5.15.0",
|
|
@@ -60,6 +63,7 @@
|
|
|
60
63
|
"@babel/plugin-transform-optional-chaining": "^7.25.0",
|
|
61
64
|
"@babel/preset-env": "^7.25.0",
|
|
62
65
|
"@babel/preset-react": "^7.24.0",
|
|
66
|
+
"@eslint/js": "^9.39.2",
|
|
63
67
|
"@loadable/babel-plugin": "^5.13.2",
|
|
64
68
|
"@loadable/webpack-plugin": "^5.15.0",
|
|
65
69
|
"@types/express": "^5.0.6",
|
|
@@ -73,6 +77,8 @@
|
|
|
73
77
|
"@types/react-router-dom": "^5.3.3",
|
|
74
78
|
"@types/serialize-javascript": "^5.0.3",
|
|
75
79
|
"@types/styled-components": "^5.1.36",
|
|
80
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
81
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
76
82
|
"babel-loader": "^10.0.0",
|
|
77
83
|
"babel-plugin-styled-components": "^2.1.4",
|
|
78
84
|
"browser-sync": "^3.0.4",
|
|
@@ -81,15 +87,24 @@
|
|
|
81
87
|
"cross-spawn": "^7.0.6",
|
|
82
88
|
"css-loader": "^7.1.0",
|
|
83
89
|
"css-minimizer-webpack-plugin": "^7.0.0",
|
|
90
|
+
"eslint": "^9.0.0",
|
|
91
|
+
"eslint-config-prettier": "^9.0.0",
|
|
92
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
93
|
+
"eslint-plugin-react": "^7.37.0",
|
|
94
|
+
"eslint-plugin-react-hooks": "^5.0.0",
|
|
95
|
+
"globals": "^17.0.0",
|
|
84
96
|
"html-webpack-plugin": "^5.6.0",
|
|
97
|
+
"husky": "^9.0.0",
|
|
85
98
|
"less": "^4.2.0",
|
|
86
99
|
"less-loader": "^12.0.0",
|
|
100
|
+
"lint-staged": "^15.0.0",
|
|
87
101
|
"mini-css-extract-plugin": "^2.9.0",
|
|
88
102
|
"nodemon": "^3.1.0",
|
|
89
103
|
"npm-run-all": "^4.1.5",
|
|
90
104
|
"postcss-loader": "^8.1.0",
|
|
91
105
|
"postcss-preset-env": "^10.6.1",
|
|
92
106
|
"prettier": "^3.3.0",
|
|
107
|
+
"prettier-plugin-organize-imports": "^4.0.0",
|
|
93
108
|
"rimraf": "^6.1.2",
|
|
94
109
|
"sass-loader": "^16.0.0",
|
|
95
110
|
"style-loader": "^4.0.0",
|
|
@@ -101,5 +116,14 @@
|
|
|
101
116
|
"webpack-cli": "^6.0.1",
|
|
102
117
|
"webpack-dev-server": "^5.1.0",
|
|
103
118
|
"webpack-node-externals": "^3.0.0"
|
|
119
|
+
},
|
|
120
|
+
"lint-staged": {
|
|
121
|
+
"*.{ts,tsx,js,jsx}": [
|
|
122
|
+
"eslint --fix",
|
|
123
|
+
"prettier --write"
|
|
124
|
+
],
|
|
125
|
+
"*.{css,less,scss}": [
|
|
126
|
+
"prettier --write"
|
|
127
|
+
]
|
|
104
128
|
}
|
|
105
129
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Setup Husky Git Hooks
|
|
5
|
+
*
|
|
6
|
+
* Note: Husky 9.x doesn't need manual installation.
|
|
7
|
+
* Hooks are automatically created during pnpm install.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
console.log('🔧 Husky Git Hooks Setup\n')
|
|
11
|
+
|
|
12
|
+
console.log('ℹ️ Husky 9.x Information:')
|
|
13
|
+
console.log(' Hooks are automatically created during pnpm install')
|
|
14
|
+
console.log(' No manual setup required!\n')
|
|
15
|
+
|
|
16
|
+
console.log('📝 Configured Git Hooks:')
|
|
17
|
+
console.log(' • pre-commit - Lint staged files before commit')
|
|
18
|
+
console.log(' • pre-push - Run full lint check before push')
|
|
19
|
+
console.log(' • commit-msg - Validate commit message format\n')
|
|
20
|
+
|
|
21
|
+
console.log('💡 Commit message format: type(scope): description')
|
|
22
|
+
console.log(' Types: feat, fix, docs, style, refactor, test, chore, etc.\n')
|
|
23
|
+
|
|
24
|
+
console.log('✅ Setup complete! Git hooks are ready to use.\n')
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { loadData as homeLoadData } from '@services/home'
|
|
3
|
-
import
|
|
4
|
-
import loadable from "@loadable/component"
|
|
3
|
+
import loadable from '@loadable/component'
|
|
5
4
|
|
|
6
5
|
const Loading = () => {
|
|
7
6
|
return <div>Loading...</div>
|
|
8
7
|
}
|
|
9
8
|
|
|
10
|
-
const Home = loadable(() => import(
|
|
9
|
+
const Home = loadable(() => import('@containers/Home'), {
|
|
11
10
|
fallback: <Loading />
|
|
12
11
|
})
|
|
13
12
|
|
|
14
|
-
const Login = loadable(() => import(
|
|
13
|
+
const Login = loadable(() => import('@containers/Login'), {
|
|
15
14
|
fallback: <Loading />
|
|
16
15
|
})
|
|
17
16
|
|
|
18
|
-
const Photo = loadable(() => import(
|
|
17
|
+
const Photo = loadable(() => import('@containers/Photo'), {
|
|
19
18
|
fallback: <Loading />
|
|
20
19
|
})
|
|
21
20
|
|
|
@@ -23,7 +23,11 @@ const App = () => {
|
|
|
23
23
|
<BrowserRouter>
|
|
24
24
|
<Routes>
|
|
25
25
|
{routers.map((router) => (
|
|
26
|
-
<Route
|
|
26
|
+
<Route
|
|
27
|
+
key={router.key}
|
|
28
|
+
path={router.path}
|
|
29
|
+
element={router.element}
|
|
30
|
+
/>
|
|
27
31
|
))}
|
|
28
32
|
</Routes>
|
|
29
33
|
</BrowserRouter>
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { Link, useLocation } from 'react-router-dom'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Container,
|
|
5
|
+
LogoWrapper as Logo,
|
|
6
|
+
Nav,
|
|
7
|
+
NavLink,
|
|
8
|
+
Brand
|
|
9
|
+
} from '@styled/component/header'
|
|
4
10
|
|
|
5
11
|
const Header = () => {
|
|
6
12
|
const location = useLocation()
|
|
@@ -16,19 +22,13 @@ const Header = () => {
|
|
|
16
22
|
</Brand>
|
|
17
23
|
<Nav>
|
|
18
24
|
<Link to="/">
|
|
19
|
-
<NavLink $active={location.pathname === '/'}>
|
|
20
|
-
🏠 首页
|
|
21
|
-
</NavLink>
|
|
25
|
+
<NavLink $active={location.pathname === '/'}>🏠 首页</NavLink>
|
|
22
26
|
</Link>
|
|
23
27
|
<Link to="/login">
|
|
24
|
-
<NavLink $active={location.pathname === '/login'}>
|
|
25
|
-
🔐 登录
|
|
26
|
-
</NavLink>
|
|
28
|
+
<NavLink $active={location.pathname === '/login'}>🔐 登录</NavLink>
|
|
27
29
|
</Link>
|
|
28
30
|
<Link to="/photo">
|
|
29
|
-
<NavLink $active={location.pathname === '/photo'}>
|
|
30
|
-
🖼️ 图片
|
|
31
|
-
</NavLink>
|
|
31
|
+
<NavLink $active={location.pathname === '/photo'}>🖼️ 图片</NavLink>
|
|
32
32
|
</Link>
|
|
33
33
|
</Nav>
|
|
34
34
|
</Container>
|