【初始化】前端工程项目

This commit is contained in:
chudong
2025-05-09 15:11:21 +08:00
parent c012704c9a
commit d7c556c3b0
524 changed files with 55595 additions and 112 deletions

View File

@@ -0,0 +1,7 @@
#!/bin/sh
# 查找并删除当前目录及子目录下所有 node_modules 文件夹和pnpm-lock.yaml文件 和 .turbo 文件夹
find . -name "node_modules" -type d -prune -exec rm -rf {} +
find . -name "pnpm-lock.yaml" -type f -delete
find . -name "dist" -type d -prune -exec rm -rf {} +
find . -name ".turbo" -type d -prune -exec rm -rf {} +
echo "删除成功"

View File

@@ -0,0 +1,620 @@
#!/bin/bash
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 检测操作系统并设置相关变量
if [[ "$OSTYPE" == "darwin"* ]]; then
OS="macOS"
SETTINGS_DIR="$HOME/Library/Application Support/Cursor"
EXTENSIONS_DIR="$HOME/.cursor"
USER_DIR="$SETTINGS_DIR/User"
TEMP_ROOT="/tmp"
PATH_SEP="/"
STAT_CMD="stat -f"
STAT_TIME_FORMAT="%Sm"
STAT_SIZE_FORMAT="%z"
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" || "$OSTYPE" == "cygwin" ]]; then
OS="Windows"
# Windows 下使用 APPDATA 环境变量
if [ -n "$APPDATA" ]; then
SETTINGS_DIR="$APPDATA/Cursor"
EXTENSIONS_DIR="$APPDATA/Cursor"
else
SETTINGS_DIR="$HOME/AppData/Roaming/Cursor"
EXTENSIONS_DIR="$HOME/AppData/Roaming/Cursor"
fi
USER_DIR="$SETTINGS_DIR/User"
TEMP_ROOT="$TEMP"
[ -z "$TEMP_ROOT" ] && TEMP_ROOT="$TMP"
[ -z "$TEMP_ROOT" ] && TEMP_ROOT="$HOME/AppData/Local/Temp"
PATH_SEP="/"
STAT_CMD="stat -c"
STAT_TIME_FORMAT="%y"
STAT_SIZE_FORMAT="%s"
else
echo -e "${RED}错误: 不支持的操作系统${NC}"
exit 1
fi
# 规范化路径
normalize_path() {
local path="$1"
echo "$path" | sed 's/\\/\//g'
}
# 备份目录
BACKUP_DIR="$(normalize_path "$HOME/cursor_backups")"
# 检查目录是否存在
if [ ! -d "$SETTINGS_DIR" ] && [ ! -d "$EXTENSIONS_DIR" ]; then
echo -e "${RED}错误: 未找到 Cursor 目录${NC}"
echo -e "${YELLOW}请确保 Cursor 编辑器已经安装并运行过至少一次${NC}"
exit 1
fi
# 创建备份目录
mkdir -p "$BACKUP_DIR"
# 获取文件修改时间
get_file_time() {
local file="$1"
if [[ "$OS" == "Windows" ]]; then
# 对于 Windows使用兼容的时间格式
$STAT_CMD "$STAT_TIME_FORMAT" "$file" 2>/dev/null || echo "Unknown"
else
$STAT_CMD "$STAT_TIME_FORMAT" "$file"
fi
}
# 获取文件大小
get_file_size() {
local file="$1"
if [[ "$OS" == "Windows" ]]; then
# 对于 Windows使用兼容的大小获取方式
$STAT_CMD "$STAT_SIZE_FORMAT" "$file" 2>/dev/null || echo "0"
else
$STAT_CMD "$STAT_SIZE_FORMAT" "$file"
fi
}
# 创建临时目录
create_temp_dir() {
local prefix="$1"
local temp_dir
if [[ "$OS" == "Windows" ]]; then
temp_dir="$(normalize_path "$TEMP_ROOT/$prefix")"
else
temp_dir="$TEMP_ROOT/$prefix"
fi
mkdir -p "$temp_dir"
echo "$temp_dir"
}
# 获取下一个可用的序号
get_next_sequence() {
local date=$1
local max_seq=0
# 查找同一天的备份,获取最大序号
find "$BACKUP_DIR" -maxdepth 1 -type d -name "cursor_${date}_*" | while read -r backup; do
if [ -d "$backup" ]; then
backup_name=$(basename "$backup")
# 提取日期和序号
if [[ $backup_name =~ ^cursor_${date}_([0-9]+)$ ]]; then
seq_num=${BASH_REMATCH[1]}
if (( seq_num > max_seq )); then
max_seq=$seq_num
fi
fi
fi
done
# 返回下一个序号
echo $((max_seq + 1))
}
# 获取插件列表
get_extensions_list() {
local extensions_dir="$(normalize_path "$1")"
local output_file="$(normalize_path "$2")"
if [ ! -d "$extensions_dir/extensions" ]; then
echo -e "${YELLOW}! 未找到插件目录${NC}"
return 1
fi
echo -e "${YELLOW}正在检查插件列表...${NC}"
# 创建一个临时文件来存储插件信息
local temp_list="$(create_temp_dir "cursor_ext_list")/extensions.tmp"
# 遍历插件目录
if [[ "$OS" == "Windows" ]]; then
# Windows 环境使用 dir /b 命令
(cd "$extensions_dir/extensions" && cmd //c "dir /b /ad" 2>/dev/null) | while read -r ext_name; do
local package_json="$extensions_dir/extensions/$ext_name/package.json"
package_json="$(normalize_path "$package_json")"
if [ -f "$package_json" ]; then
# 尝试从 package.json 中提取版本信息
local version=$(grep -o '"version": *"[^"]*"' "$package_json" 2>/dev/null | cut -d'"' -f4)
if [ -n "$version" ]; then
echo "$ext_name@$version" >> "$temp_list"
else
echo "$ext_name" >> "$temp_list"
fi
else
echo "$ext_name" >> "$temp_list"
fi
done
else
# Unix 环境使用 find 命令
find "$extensions_dir/extensions" -maxdepth 1 -type d | while read -r ext_dir; do
if [ "$ext_dir" != "$extensions_dir/extensions" ]; then
local ext_name=$(basename "$ext_dir")
local package_json="$ext_dir/package.json"
if [ -f "$package_json" ]; then
local version=$(grep -o '"version": *"[^"]*"' "$package_json" 2>/dev/null | cut -d'"' -f4)
if [ -n "$version" ]; then
echo "$ext_name@$version" >> "$temp_list"
else
echo "$ext_name" >> "$temp_list"
fi
else
echo "$ext_name" >> "$temp_list"
fi
fi
done
fi
# 排序插件列表
if [ -f "$temp_list" ]; then
sort "$temp_list" > "$output_file"
rm -f "$temp_list"
return 0
fi
rm -f "$temp_list"
return 1
}
# 显示插件列表差异
show_extensions_diff() {
local backup_list="$1"
local current_list="$2"
if [ ! -f "$backup_list" ] || [ ! -f "$current_list" ]; then
return 1
fi
echo -e "\n${YELLOW}插件对比:${NC}"
# 找出新增的插件
echo -e "\n${GREEN}新增的插件:${NC}"
comm -13 "$backup_list" "$current_list" | while read -r ext; do
echo -e "${GREEN}+ $ext${NC}"
done
# 找出删除的插件
echo -e "\n${RED}删除的插件:${NC}"
comm -23 "$backup_list" "$current_list" | while read -r ext; do
echo -e "${RED}- $ext${NC}"
done
# 找出相同的插件
echo -e "\n${YELLOW}保持不变的插件:${NC}"
comm -12 "$backup_list" "$current_list" | while read -r ext; do
echo -e " $ext"
done
}
# 创建备份
create_backup() {
# 生成日期和序号
DATE=$(date +"%Y%m%d")
SEQ=$(get_next_sequence "$DATE")
# 格式化序号为两位数
printf -v SEQ_PADDED "%02d" "$SEQ"
BACKUP_NAME="cursor_${DATE}_${SEQ_PADDED}"
BACKUP_PATH="$BACKUP_DIR/$BACKUP_NAME"
TEMP_PATH="/tmp/$BACKUP_NAME"
echo -e "${YELLOW}正在创建备份...${NC}"
echo -e "${YELLOW}操作系统: $OS${NC}"
echo -e "${YELLOW}设置目录: $SETTINGS_DIR${NC}"
echo -e "${YELLOW}插件目录: $EXTENSIONS_DIR${NC}"
# 创建临时目录
mkdir -p "$TEMP_PATH"
# 获取当前插件列表
local extensions_list="$TEMP_PATH/extensions.list"
if get_extensions_list "$EXTENSIONS_DIR" "$extensions_list"; then
echo -e "${GREEN}✓ 已保存插件列表${NC}"
echo -e "\n${YELLOW}当前安装的插件:${NC}"
cat "$extensions_list" | while read -r ext; do
echo " $ext"
done
echo
fi
# 备份设置文件
if [ -f "$USER_DIR/settings.json" ]; then
mkdir -p "$TEMP_PATH/User"
cp "$USER_DIR/settings.json" "$TEMP_PATH/User/"
echo -e "${GREEN}✓ 已备份设置文件${NC}"
else
echo -e "${YELLOW}! 未找到设置文件${NC}"
fi
# 备份扩展目录
if [ -d "$EXTENSIONS_DIR/extensions" ]; then
cp -r "$EXTENSIONS_DIR/extensions" "$TEMP_PATH/"
echo -e "${GREEN}✓ 已备份扩展目录${NC}"
else
echo -e "${YELLOW}! 未找到扩展目录${NC}"
fi
# 压缩备份
echo -e "${YELLOW}正在压缩备份...${NC}"
tar -czf "${BACKUP_PATH}.tar.gz" -C "/tmp" "$BACKUP_NAME"
# 清理临时目录
rm -rf "$TEMP_PATH"
echo -e "${GREEN}备份创建成功: ${BACKUP_PATH}.tar.gz${NC}"
}
# 还原备份
restore_backup() {
if [ -z "$1" ]; then
echo -e "${RED}错误: 请指定要还原的备份名称${NC}"
echo "用法: $0 restore <backup_name>"
exit 1
fi
BACKUP_NAME="$1"
BACKUP_PATH="$BACKUP_DIR/$BACKUP_NAME"
TEMP_PATH="/tmp/$BACKUP_NAME"
if [ ! -f "${BACKUP_PATH}.tar.gz" ]; then
echo -e "${RED}错误: 未找到备份文件: ${BACKUP_PATH}.tar.gz${NC}"
exit 1
fi
echo -e "${YELLOW}正在还原备份...${NC}"
echo -e "${YELLOW}操作系统: $OS${NC}"
echo -e "${YELLOW}设置目录: $SETTINGS_DIR${NC}"
echo -e "${YELLOW}插件目录: $EXTENSIONS_DIR${NC}"
# 解压备份到临时目录
echo -e "${YELLOW}正在解压备份...${NC}"
rm -rf "$TEMP_PATH"
tar -xzf "${BACKUP_PATH}.tar.gz" -C "/tmp"
# 获取当前插件列表
local current_list=$(mktemp)
local backup_list="$TEMP_PATH/extensions.list"
if get_extensions_list "$EXTENSIONS_DIR" "$current_list"; then
if [ -f "$backup_list" ]; then
show_extensions_diff "$backup_list" "$current_list"
echo
echo -n "是否继续还原? [y/N] "
read -r confirm
if [[ ! $confirm =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}取消还原操作${NC}"
rm -f "$current_list"
rm -rf "$TEMP_PATH"
return
fi
fi
fi
rm -f "$current_list"
# 还原设置文件
if [ -f "$TEMP_PATH/User/settings.json" ]; then
mkdir -p "$USER_DIR"
cp "$TEMP_PATH/User/settings.json" "$USER_DIR/"
echo -e "${GREEN}✓ 已还原设置文件${NC}"
else
echo -e "${YELLOW}! 备份中未找到设置文件${NC}"
fi
# 还原扩展目录
if [ -d "$TEMP_PATH/extensions" ]; then
rm -rf "$EXTENSIONS_DIR/extensions"
cp -r "$TEMP_PATH/extensions" "$EXTENSIONS_DIR/"
echo -e "${GREEN}✓ 已还原扩展目录${NC}"
else
echo -e "${YELLOW}! 备份中未找到扩展目录${NC}"
fi
# 清理临时目录
rm -rf "$TEMP_PATH"
echo -e "${GREEN}备份还原成功${NC}"
echo -e "${YELLOW}请重启 Cursor 编辑器以使更改生效${NC}"
}
# 删除备份
delete_backup() {
if [ -z "$1" ]; then
echo -e "${RED}错误: 请指定要删除的备份名称${NC}"
echo "用法: $0 delete <backup_name>"
exit 1
fi
BACKUP_NAME="$1"
BACKUP_PATH="$BACKUP_DIR/$BACKUP_NAME"
if [ ! -f "${BACKUP_PATH}.tar.gz" ]; then
echo -e "${RED}错误: 未找到备份文件: ${BACKUP_PATH}.tar.gz${NC}"
exit 1
fi
echo -e "${YELLOW}即将删除备份: $BACKUP_NAME${NC}"
echo -n "确认删除? [y/N] "
read -r confirm
if [[ $confirm =~ ^[Yy]$ ]]; then
rm -f "${BACKUP_PATH}.tar.gz"
echo -e "${GREEN}备份已删除: $BACKUP_NAME${NC}"
else
echo -e "${YELLOW}取消删除操作${NC}"
fi
}
# 删除所有备份
delete_all_backups() {
# 检查是否有备份
if ! list_backups; then
return 1
fi
echo -e "${YELLOW}警告: 即将删除所有备份!${NC}"
echo -n "确认删除所有备份? [y/N] "
read -r confirm
if [[ $confirm =~ ^[Yy]$ ]]; then
rm -f "$BACKUP_DIR"/cursor_*.tar.gz
echo -e "${GREEN}已删除所有备份${NC}"
else
echo -e "${YELLOW}取消删除操作${NC}"
fi
}
# 格式化文件大小
format_size() {
local size=$1
local units=("B" "KiB" "MiB" "GiB" "TiB")
local unit=0
while (( size > 1024 && unit < 4 )); do
size=$(( (size + 512) / 1024 ))
((unit++))
done
echo "${size}${units[$unit]}"
}
# 列出备份并返回备份名称数组
list_backups() {
if [ ! -d "$BACKUP_DIR" ]; then
echo -e "${YELLOW}未找到备份${NC}"
return 1
fi
# 创建一个数组来存储备份名称
backup_names=()
echo -e "${YELLOW}可用的备份:${NC}"
id=1
if [[ "$OS" == "Windows" ]]; then
# Windows 环境使用 dir 命令
(cd "$BACKUP_DIR" && cmd //c "dir /b *.tar.gz" 2>/dev/null) | sort -r | while read -r backup_file; do
local backup="$BACKUP_DIR/$backup_file"
backup="$(normalize_path "$backup")"
if [ -f "$backup" ]; then
local backup_name=$(basename "$backup" .tar.gz)
backup_names+=("$backup_name")
local backup_time=$(get_file_time "$backup")
local backup_size=$(get_file_size "$backup")
local formatted_size=$(format_size "$backup_size")
printf "%2d) %s (%s) [%8s]\n" $id "$backup_name" "$backup_time" "$formatted_size"
((id++))
fi
done
else
# Unix 环境使用 find 命令
find "$BACKUP_DIR" -maxdepth 1 -type f -name "cursor_*.tar.gz" | sort -r | while read -r backup; do
if [ -f "$backup" ]; then
local backup_name=$(basename "$backup" .tar.gz)
backup_names+=("$backup_name")
local backup_time=$(get_file_time "$backup")
local backup_size=$(get_file_size "$backup")
local formatted_size=$(format_size "$backup_size")
printf "%2d) %s (%s) [%8s]\n" $id "$backup_name" "$backup_time" "$formatted_size"
((id++))
fi
done
fi
# 如果没有找到备份
if [ ${#backup_names[@]} -eq 0 ]; then
echo -e "${YELLOW}没有可用的备份${NC}"
return 1
fi
return 0
}
# 根据ID获取备份名称
get_backup_by_id() {
local id=$1
local -a backup_names=()
# 获取所有备份名称并排序
find "$BACKUP_DIR" -maxdepth 1 -type f -name "cursor_*.tar.gz" | sort -r | while read -r backup; do
if [ -f "$backup" ]; then
backup_name=$(basename "$backup" .tar.gz)
backup_names+=("$backup_name")
fi
done
# 检查ID是否有效
if [ "$id" -le 0 ] || [ "$id" -gt "${#backup_names[@]}" ]; then
return 1
fi
# 返回对应的备份名称
echo "${backup_names[$((id-1))]}"
return 0
}
# 显示帮助信息
show_help() {
echo -e "${GREEN}Cursor 编辑器备份工具${NC}"
echo -e "${YELLOW}当前操作系统: $OS${NC}"
if [[ "$OS" == "macOS" ]]; then
echo -e "${YELLOW}设置目录: $SETTINGS_DIR${NC}"
echo -e "${YELLOW}插件目录: $EXTENSIONS_DIR${NC}"
else
echo -e "${YELLOW}Cursor 目录: $SETTINGS_DIR${NC}"
fi
echo -e "${YELLOW}备份目录: $BACKUP_DIR${NC}"
echo
echo "用法:"
echo " 创建备份: $0 backup"
echo " 还原备份: $0 restore <backup_name>"
echo " 删除备份: $0 delete <backup_name>"
echo " 删除所有: $0 delete-all"
echo " 列出备份: $0 list"
echo " 显示帮助: $0 help"
}
# 显示菜单并获取用户选择
show_menu() {
clear
echo -e "${GREEN}Cursor 编辑器备份工具${NC}"
echo -e "${YELLOW}当前操作系统: $OS${NC}"
if [[ "$OS" == "macOS" ]]; then
echo -e "${YELLOW}设置目录: $SETTINGS_DIR${NC}"
echo -e "${YELLOW}插件目录: $EXTENSIONS_DIR${NC}"
else
echo -e "${YELLOW}Cursor 目录: $SETTINGS_DIR${NC}"
fi
echo -e "${YELLOW}备份目录: $BACKUP_DIR${NC}"
echo
echo "请选择操作:"
echo "1) 创建备份"
echo "2) 还原备份"
echo "3) 删除备份"
echo "4) 删除所有备份"
echo "5) 列出备份"
echo "0) 退出"
echo
echo -n "请输入选项 [0-5]: "
read -r choice
case $choice in
1)
create_backup
;;
2)
# 显示可用备份并获取用户选择
echo
if list_backups; then
echo
echo -n "请输入要还原的备份ID: "
read -r backup_id
if [[ "$backup_id" =~ ^[0-9]+$ ]]; then
backup_name=$(get_backup_by_id "$backup_id")
if [ -n "$backup_name" ]; then
restore_backup "$backup_name"
else
echo -e "${RED}错误: 无效的备份ID${NC}"
fi
else
echo -e "${RED}错误: 请输入有效的数字ID${NC}"
fi
fi
;;
3)
# 显示可用备份并获取用户选择
echo
if list_backups; then
echo
echo -n "请输入要删除的备份ID: "
read -r backup_id
if [[ "$backup_id" =~ ^[0-9]+$ ]]; then
backup_name=$(get_backup_by_id "$backup_id")
if [ -n "$backup_name" ]; then
delete_backup "$backup_name"
else
echo -e "${RED}错误: 无效的备份ID${NC}"
fi
else
echo -e "${RED}错误: 请输入有效的数字ID${NC}"
fi
fi
;;
4)
delete_all_backups
;;
5)
list_backups
;;
0)
echo "退出程序"
exit 0
;;
*)
echo -e "${RED}无效的选项${NC}"
;;
esac
echo
echo -n "按回车键继续..."
read -r
show_menu
}
# 主程序
if [ $# -eq 0 ]; then
# 如果没有命令行参数,显示交互式菜单
show_menu
else
# 保持原有的命令行参数支持
case "$1" in
"backup")
create_backup
;;
"restore")
restore_backup "$2"
;;
"delete")
delete_backup "$2"
;;
"delete-all")
delete_all_backups
;;
"list")
list_backups
;;
"help"|"--help"|"-h")
show_help
;;
*)
echo -e "${RED}未知命令: $1${NC}"
show_help
exit 1
;;
esac
fi

View File

@@ -0,0 +1,16 @@
{
"extensions": [
"akamud.vscode-theme-onedark",
"atommaterial.a-file-icon-vscode",
"dbaeumer.vscode-eslint",
"donjayamanne.githistory",
"eamodio.gitlens",
"esbenp.prettier-vscode",
"lokalise.i18n-ally",
"maggie.eslint-rules-zh-plugin",
"ms-ceintl.vscode-language-pack-zh-hans",
"ms-vscode-remote.remote-containers",
"rvest.vs-code-prettier-eslint",
"vue.volar"
]
}

View File

@@ -0,0 +1,65 @@
{
"workbench.colorTheme": "Atom One Dark", // 工作台 设置主题
"workbench.iconTheme": "a-file-icon-vscode", // 工作台 设置图标主题
"workbench.editor.enablePreview": true, // 工作台 设置预览
"workbench.settings.applyToAllProfiles": [], // 工作台 设置应用到所有配置文件
"editor.fontSize": 14, // 编辑器 设置字体大小
"editor.tabSize": 2, // 编辑器 设置制表符大小
"editor.formatOnSave": false, // 编辑器 设置保存时自动格式化
"editor.formatOnType": true, // 编辑器 设置输入时自动格式化
"editor.formatOnPaste": true, // 编辑器 设置粘贴时自动格式化
"editor.detectIndentation": false, // 编辑器 设置自动检测缩进
"editor.insertSpaces": false, // 编辑器 设置插入空格
"editor.bracketPairColorization.enabled": true, // 编辑器 设置括号颜色
"editor.guides.bracketPairs": "active", // 编辑器 设置括号对齐
"editor.quickSuggestions": {
"strings": true // 编辑器 设置快速建议
},
"editor.unicodeHighlight.allowedLocales": {
// 编辑器 设置允许的语言
"zh-hant": true,
"de": true,
"zh-hans": true
},
"editor.unicodeHighlight.invisibleCharacters": false, // 编辑器 设置隐藏字符
"editor.inlineSuggest.enabled": true, // 设置内联建议
"editor.codeActionsOnSave": {
// 编辑器 设置保存时自动执行
"quickfix.biome": "explicit"
},
"editor.suggestSelection": "first", // 编辑器 设置建议选择
"explorer.compactFolders": false, // 资源管理器 设置紧凑文件夹
"explorer.confirmDelete": true, // 资源管理器 设置确认删除
"git.autofetch": true, // git 设置自动获取
"git.enableSmartCommit": true, // git 设置智能提交
"git.confirmSync": false, // git 设置确认同步
"git.useEditorAsCommitInput": false, // git 设置使用编辑器作为提交输入
"git.autoRepositoryDetection": "subFolders", // git 设置自动检测仓库
"window.menuBarVisibility": "classic", // 视图 设置菜单栏可见性
"files.eol": "\n", // 设置行
"terminal.integrated.defaultProfile.windows": "Command Prompt", // 设置默认终端
"typescript.updateImportsOnFileMove.enabled": "always", // 设置更新导入
"i18n-ally.displayLanguage": "zh-cn", // i18n-ally 设置显示语言
"security.workspace.trust.untrustedFiles": "open", // 设置信任未受信任的文件
"security.promptForLocalFileProtocolHandling": false, // 安全 设置提示本地文件协议处理
"gitlens.graph.minimap.enabled": false, // gitlens 设置最小地图
"chat.editing.alwaysSaveWithGeneratedChanges": true, // chat 设置总是保存生成的更改
"cursor.cpp.disabledLanguages": [
// cursor cpp 设置禁用语言
"plaintext",
"scminput"
],
"files.autoSave": "afterDelay", // 自动保存
"files.autoSaveDelay": 1000,
"remote.autoForwardPortsSource": "hybrid",
"workbench.activityBar.orientation": "vertical",
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}