Compare commits

...

10 Commits

Author SHA1 Message Date
4c347a5bd7 chore: 添加gitea ISSUE/PR模板 2025-12-19 14:57:44 +08:00
9ba162ad2f chore: 调整prettier配置 2025-12-19 14:57:24 +08:00
d197985e6c chore: 添加pre-commit hook
- 提交前执行lint-staged
2025-12-19 14:30:16 +08:00
a2302d4116 chore: 添加commitlint 2025-12-19 14:27:42 +08:00
9bdeca575b chore: 添加lint-staged 2025-12-19 14:13:47 +08:00
dacc130293 chore: 添加husky 2025-12-19 14:09:39 +08:00
f192180d22 chore: 添加editorconfig 2025-12-19 14:05:15 +08:00
5e6e4b2960 chore: 添加prettier 2025-12-19 14:02:50 +08:00
f2214f3b46 chore: 添加svelte eslint模块 2025-12-19 14:01:51 +08:00
754ee32d79 chore: 添加eslint 2025-12-19 14:00:49 +08:00
13 changed files with 2517 additions and 45 deletions

9
.editorconfig Normal file
View File

@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

View File

@ -0,0 +1,61 @@
name: Bug报告
about: 用于报告项目中的Bug帮助我们改进项目
title: '[BUG] ' # 新开 Issue 时默认加的前缀
body:
- type: markdown
attributes:
value: |
请在下方填写Bug的详细信息包括重现步骤、预期结果和实际结果等。
- type: textarea
id: summary
attributes:
label: '问题概述/Summary'
description: '简要描述遇到的问题'
placeholder: '输入问题概述'
validations:
required: true
- type: textarea
id: steps
attributes:
label: '重现步骤/Steps to Reproduce'
description: '列出重现该问题的具体步骤'
placeholder: '输入重现步骤'
validations:
required: true
- type: textarea
id: expected
attributes:
label: '预期结果/Expected Behavior'
description: '描述你期望看到的结果'
placeholder: '输入预期结果'
validations:
required: true
- type: textarea
id: actual
attributes:
label: '实际结果/Actual Behavior'
description: '描述实际发生的情况'
placeholder: '输入实际结果'
validations:
required: true
- type: textarea
id: environment
attributes:
label: '环境信息/Environment'
description: '提供相关环境信息,如操作系统、浏览器版本等'
placeholder: '输入环境信息'
validations:
required: false
- type: checkboxes
id: checklist
attributes:
label: '检查表/Checklist'
description: '提交前,请确认以下事项'
options:
- label: 已搜索过类似问题,确保不是重复报告
required: true
- label: 提供了足够的信息以帮助我们理解和重现问题
required: true
- label: 如果可能,已附上相关截图或日志文件
required: false

View File

@ -0,0 +1,53 @@
name: 功能请求
about: 用于提出新功能或改进建议
title: '[FEATURE] ' # 新开 Issue 时默认加的前缀
body:
- type: markdown
attributes:
value: |
请在下方填写功能请求的详细信息,包括需求背景、预期效果和相关上下文。
- type: textarea
id: summary
attributes:
label: '功能概述/Summary'
description: '简要描述你希望添加的功能'
placeholder: '输入功能概述'
validations:
required: true
- type: textarea
id: motivation
attributes:
label: '需求背景/Motivation'
description: '说明为什么需要这个功能,它将如何帮助用户或改进现有流程'
placeholder: '输入需求背景'
validations:
required: true
- type: textarea
id: proposal
attributes:
label: '解决方案/Proposal'
description: '描述你对该功能的设想或建议的实现方式'
placeholder: '输入解决方案'
validations:
required: false
- type: textarea
id: alternatives
attributes:
label: '替代方案/Alternatives'
description: '如果有其他可行的替代方案,请在此列出'
placeholder: '输入替代方案'
validations:
required: false
- type: checkboxes
id: checklist
attributes:
label: '检查表/Checklist'
description: '提交前,请确认以下事项'
options:
- label: 已搜索过类似功能请求,确保不是重复提交
required: true
- label: 提供了足够的信息以帮助我们理解和评估该请求
required: true
- label: 如果可能,已附上相关截图或示意图
required: false

View File

@ -0,0 +1,62 @@
name: 'Standard PR 模板'
about: '用于提交新功能/修复bug/改进重构等合并请求'
title: '[PR] ' # 新开 PR 时默认加的前缀
ref: 'master' # 默认目标分支,可根据你们主分支改为 master/develop 等
body:
- type: markdown
attributes:
value: |
请在下方填写合并请求描述,包括变更目的、主要内容及相关上下文。
- type: textarea
attributes:
label: '关联Issue'
description: '比如: Fixes #123/Closes #456/如果没有可以留空'
placeholder: '输入关联 issue 编号'
validations:
required: false
- type: textarea
attributes:
label: '更改内容/What Changed'
description: '列出本次 PR 的主要变更项,便于 Review'
placeholder: '输入更改内容'
validations:
required: true
- type: textarea
attributes:
label: '测试步骤/How To Test'
description: '提供复现/验证更改的步骤,含环境/命令/预期结果等'
placeholder: '输入测试步骤'
validations:
required: false
- type: checkboxes
attributes:
label: '检查表/Checklist'
description: '提交前,请确认以下事项'
options:
- label: 代码格式符合团队规范
required: true
- label: 已添加或更新单元测试/集成测试
required: true
- label: 文档/README 已更新(如有必要)
required: false
- label: 所有测试通过
required: true
- label: 分支命名正确(feature/xxx或fix/xxx 等)
required: false
- label: 回归风险已评估
required: false
validations:
required: true
- type: textarea
id: impact
attributes:
label: '影响评估/Risk & Rollback'
description: '评估变更是否有破坏性风险,以及如何回滚/缓解'
placeholder: '例如:数据库迁移、依赖变动、兼容性问题等'
validations:
required: false
- type: textarea
attributes:
label: '可选:截图或 Demo(如界面/UI 有变化)'
description: '上传新的界面/UI'

151
.husky/commit-msg Normal file
View File

@ -0,0 +1,151 @@
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
GRAY='\033[0;37m'
NC='\033[0m' # No Color
# 启用调试模式(可选)
DEBUG=${DEBUG:-false}
# 输出函数
print_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_debug() {
if [ "$DEBUG" = "true" ]; then
echo -e "${GRAY}[DEBUG]${NC} $1"
fi
}
print_section() {
echo -e "${PURPLE}[SECTION]${NC} $1"
}
print_command() {
echo -e "${CYAN}[COMMAND]${NC} $1"
}
print_section "开始执行Commit Message Hook..."
print_info "时间: $(date)"
print_info "工作目录: $(pwd)"
print_info "用户: $(whoami)"
echo
# 调试信息
print_debug "接收到的参数: $*"
print_debug "参数数量: $#"
print_debug "第一个参数 (提交消息文件): $1"
print_debug "Shell: $SHELL"
print_debug "PATH: $PATH"
print_debug "当前进程ID: $"
# 检查 commitlint 是否可用
print_section "检查 commitlint..."
if npx commitlint --version >/dev/null 2>&1; then
COMMITLINT_VERSION=$(npx commitlint --version)
print_success "commitlint 可用: $COMMITLINT_VERSION"
else
print_error "commitlint 不可用或配置有误"
exit 1
fi
# 检查提交消息文件
echo
print_section "检查提交消息文件..."
if [ -f "$1" ]; then
print_success "文件存在: $1"
FILE_SIZE=$(wc -c < "$1")
print_info "文件大小: $FILE_SIZE 字节"
print_info "文件内容:"
echo -e "${CYAN}========================================${NC}"
cat "$1"
echo
echo -e "${CYAN}========================================${NC}"
# 检查文件权限
FILE_PERMS=$(ls -l "$1" | awk '{print $1}')
print_debug "文件权限: $FILE_PERMS"
# 检查文件内容是否为空
if [ "$FILE_SIZE" -eq 0 ] || [ -z "$(tr -d '[:space:]' < "$1")" ]; then
print_warning "提交消息为空"
fi
else
print_error "找不到提交消息文件: $1"
print_info "当前目录内容:"
ls -la
exit 1
fi
# 检查 commitlint 配置
echo
print_section "检查 commitlint 配置..."
if [ -f ".commitlintrc.js" ] || [ -f ".commitlintrc.json" ] || [ -f "commitlint.config.js" ] || [ -f "commitlint.config.mjs" ]; then
print_success "找到 commitlint 配置文件"
for config_file in .commitlintrc.js .commitlintrc.json commitlint.config.js; do
if [ -f "$config_file" ]; then
print_info "配置文件: $config_file"
print_debug "$config_file 内容预览:"
print_debug "$(head -10 "$config_file" 2>/dev/null || echo '无法读取文件')"
break
fi
done
else
print_warning "未找到 commitlint 配置文件"
print_info "建议创建 .commitlintrc.js 或 commitlint.config.js/commitlint.config.mjs"
fi
# 运行 commitlint
echo
print_section "执行 commitlint 检查..."
print_command "执行命令: npx commitlint --edit \"$1\""
# 显示详细的执行过程
if [ "$DEBUG" = "true" ]; then
print_debug "详细执行过程:"
npx commitlint --edit "$1" --verbose
RESULT=$?
else
npx commitlint --edit "$1"
RESULT=$?
fi
echo
if [ $RESULT -eq 0 ]; then
print_success "提交消息格式检查通过!"
print_info "准备提交到 Git 仓库..."
print_debug "Hook 执行成功,退出代码: 0"
else
print_error "提交消息格式检查失败! (退出代码: $RESULT)"
echo
print_warning "故障排查建议:"
echo "1. 检查提交消息是否符合约定式提交格式"
echo "2. 确认 commitlint 配置是否正确"
echo "3. 运行 'DEBUG=true git commit' 查看详细调试信息"
echo "4. 手动测试: npx commitlint --edit .git/COMMIT_EDITMSG"
echo
print_debug "Hook 执行失败,退出代码: $RESULT"
fi
print_info "Hook 执行完成: $(date)"
exit $RESULT

1
.husky/pre-commit Normal file
View File

@ -0,0 +1 @@
pnpm exec lint-staged

9
.prettierignore Normal file
View File

@ -0,0 +1,9 @@
# Package Managers
package-lock.json
pnpm-lock.yaml
yarn.lock
bun.lock
bun.lockb
# Miscellaneous
/static/

7
commitlint.config.ts Normal file
View File

@ -0,0 +1,7 @@
import type { UserConfig } from '@commitlint/types';
const Configuration: UserConfig = {
extends: ['@commitlint/config-conventional']
};
export default Configuration;

41
eslint.config.js Normal file
View File

@ -0,0 +1,41 @@
import prettier from 'eslint-config-prettier';
import { fileURLToPath } from 'node:url';
import { includeIgnoreFile } from '@eslint/compat';
import js from '@eslint/js';
import svelte from 'eslint-plugin-svelte';
import { defineConfig } from 'eslint/config';
import globals from 'globals';
import ts from 'typescript-eslint';
import svelteConfig from './svelte.config.js';
const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url));
export default defineConfig(
includeIgnoreFile(gitignorePath),
js.configs.recommended,
...ts.configs.recommended,
...svelte.configs.recommended,
prettier,
...svelte.configs.prettier,
{
languageOptions: { globals: { ...globals.browser, ...globals.node } },
rules: {
// typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects.
// see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
"no-undef": 'off'
}
},
{
files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
languageOptions: {
parserOptions: {
projectService: true,
extraFileExtensions: ['.svelte'],
parser: ts.parser,
svelteConfig
}
}
}
);

8
lint-staged.config.js Normal file
View File

@ -0,0 +1,8 @@
/**
* @filename: lint-staged.config.js
* @type {import('lint-staged').Configuration}
*/
export default {
'*.{ts,tsx,svelte,js,jsx}': ['eslint --fix'],
'*.{css,scss,md,json,yaml,yml}': ['prettier --write']
};

View File

@ -7,9 +7,12 @@
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"prepare": "svelte-kit sync || echo ''",
"prepare": "svelte-kit sync || echo '' && husky",
"prepare-husky": "husky",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "eslint . && prettier --check .",
"format": "prettier --write ."
},
"engines": {
"node": ">=20",
@ -17,12 +20,27 @@
},
"packageManager": "pnpm@10.18.2",
"devDependencies": {
"@commitlint/cli": "^20.2.0",
"@commitlint/config-conventional": "^20.2.0",
"@commitlint/types": "^20.2.0",
"@eslint/compat": "^1.4.0",
"@eslint/js": "^9.39.1",
"@sveltejs/adapter-auto": "^7.0.0",
"@sveltejs/kit": "^2.49.1",
"@sveltejs/vite-plugin-svelte": "^6.2.1",
"@types/node": "^22",
"eslint": "^9.39.1",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-svelte": "^3.13.1",
"globals": "^16.5.0",
"husky": "^9.1.7",
"lint-staged": "^16.2.7",
"prettier": "^3.7.4",
"prettier-plugin-svelte": "^3.4.0",
"svelte": "^5.45.6",
"svelte-check": "^4.3.4",
"typescript": "^5.9.3",
"typescript-eslint": "^8.48.1",
"vite": "^7.2.6"
}
}

2042
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

48
prettier.config.mjs Normal file
View File

@ -0,0 +1,48 @@
/**
* @see https://prettier.io/docs/en/configuration.html
* @type {import('prettier').Config}
*/
export default {
// 打印宽度
printWidth: 80,
// 缩进空格数
tabWidth: 2,
// 使用制表符而不是空格缩进
useTabs: false,
// 句尾添加分号
semi: true,
// 使用单引号
singleQuote: true,
// 尾随逗号
trailingComma: 'es5',
// 对象大括号内的空格
bracketSpacing: true,
// 箭头函数参数括号
arrowParens: 'always',
// 括号行位置
bracketSameLine: false,
// 换行符使用 lf
endOfLine: 'lf',
// HTML 空格敏感度
htmlWhitespaceSensitivity: 'css',
plugins: ['prettier-plugin-svelte'],
overrides: [
{
files: '*.svelte',
options: {
parser: 'svelte',
},
},
{
// 对 CSS 文件使用双引号
files: '*.css',
options: { singleQuote: false },
},
{
// 对 SCSS 文件使用双引号
files: '*.scss',
options: { singleQuote: false },
},
],
};