From ff639864c7b0f860c69b7e98e2097f00036683cd Mon Sep 17 00:00:00 2001 From: Wisdom Date: Thu, 9 May 2024 11:24:29 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=8E=A3=20=20chore:=20support=20husky?= =?UTF-8?q?=20lint=20staged?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .husky/post-merge | 9 ++ .husky/pre-commit | 47 +++++++++++ .vscode/extensions.json | 1 + .vscode/settings.json | 38 +++++++-- lint-staged.config.js | 3 + package.json | 5 +- pnpm-lock.yaml | 176 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 269 insertions(+), 10 deletions(-) create mode 100755 .husky/post-merge create mode 100755 .husky/pre-commit create mode 100644 lint-staged.config.js diff --git a/.husky/post-merge b/.husky/post-merge new file mode 100755 index 0000000..fe3227b --- /dev/null +++ b/.husky/post-merge @@ -0,0 +1,9 @@ +#!/bin/sh + +# 检查 pnpm-lock.yaml 是否发生变化 +if git diff --name-only HEAD@{1} HEAD | grep -E 'pnpm-lock.yaml'; then + echo "Detected changes in dependencies, running pnpm install..." + pnpm install +else + echo "No dependency changes detected, skipping pnpm install." +fi diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..689581a --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,47 @@ +#!/bin/sh + +BOLD='\033[1m' +GREEN='\033[32m' +RED='\033[31m' +RESET='\033[0m' + +# 检查是否在 Git 仓库目录下 +git rev-parse --git-dir >/dev/null 2>&1 || { + echo >&2 "${RED}❌ 错误: 当前目录不是 Git 仓库${RESET}" + exit 1 +} + + +# 检查是否为 --amend +IS_AMEND=$(git rev-parse --verify --quiet HEAD >/dev/null 2>&1; echo $?) + +# 检查暂存区与 HEAD 之间是否有变化 +HAS_DIFF=$(git diff --cached HEAD) + + +if [ "$IS_AMEND" -eq 0 ] && [ -z "$HAS_DIFF" ]; then + echo "可能是 amend 操作" + exit 0 +fi + + +# 运行 lint-staged +if pnpm lint-staged; then + # 检查 Git 暂存区是否有变化 + if [ -z "$(git diff --cached)" ]; then + # 暂存区为空,输出警告信息 + echo "\n${RED}❌ Commit 失败,请检查以下可能原因:\n" + echo "\t1. lint-staged 修复后代码与上次提交一致,无新变更" + echo "\t2. 代码未添加到暂存区" + echo "\t3. ESLint 插件未生效,请检查插件状态" + echo "\n请检查代码,并重新 add 后再尝试提交。 ${RESET}\n" + exit 1 + else + # 暂存区有变化,可继续提交 + echo "\n${GREEN}✅ ESLint 校验成功,可以继续提交${RESET}\n" + fi +else + # lint-staged 失败 + echo "${BOLD}${RED}🥴 ESLint 校验失败,请尝试修复错误后再重新执行 add、commit。${RESET}\n" + exit 1 +fi diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 4a333c2..24ab6ab 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,6 +1,7 @@ { "recommendations": [ "vue.volar", + "antfu.iconify", "dbaeumer.vscode-eslint", "stylelint.vscode-stylelint" ] diff --git a/.vscode/settings.json b/.vscode/settings.json index a126c0d..226d3d7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,18 +1,38 @@ { - "stylelint.validate": [ + "editor.formatOnSave": false, + + // Auto fix + + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit", + "source.organizeImports": "never", + "source.fixAll.stylelint": "explicit" + }, + "eslint.run": "onType", + "eslint.format.enable": true, + "stylelint.validate": [ "vue", "scss" ], "css.validate": false, "less.validate": false, - "editor.formatOnSave": false, - "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit", - "eslint.autoFixOnSave": "explicit", - "source.fixAll.stylelint": "explicit" - }, "files.autoSaveDelay": 500, - "typescript.tsdk": "node_modules/typescript/lib", - "vue.codeActions.enabled": false, + + // Enable eslint for all supported languages + "eslint.validate": [ + "javascript", + "javascriptreact", + "typescript", + "typescriptreact", + "vue", + "html", + "markdown", + "json", + "jsonc", + "yaml", + "toml", + "gql", + "graphql" + ] } diff --git a/lint-staged.config.js b/lint-staged.config.js new file mode 100644 index 0000000..86b6007 --- /dev/null +++ b/lint-staged.config.js @@ -0,0 +1,3 @@ +export default { + '*.{js,ts,vue}': 'eslint --quiet --fix' +} diff --git a/package.json b/package.json index 8ab6423..1ccc7d8 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "test": "vitest", "test:coverage": "vitest run --coverage", "stylelint": "stylelint .scss, .vue ./src", - "stylelint:fix": "stylelint --fix .scss, .vue ./src" + "stylelint:fix": "stylelint --fix .scss, .vue ./src", + "prepare": "husky" }, "engines": { "node": ">= 16.15.x", @@ -98,8 +99,10 @@ "eslint-plugin-import": "^2.29.1", "eslint-plugin-vue": "^9.25.0", "globals": "^15.0.0", + "husky": "^9.0.11", "identity-obj-proxy": "^3.0.0", "jsdom": "^24.0.0", + "lint-staged": "^15.2.2", "postcss": "^8.4.38", "postcss-html": "^1.6.0", "postcss-scss": "^4.0.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8b8e0c5..23215d3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -151,12 +151,18 @@ devDependencies: globals: specifier: ^15.0.0 version: 15.0.0 + husky: + specifier: ^9.0.11 + version: 9.0.11 identity-obj-proxy: specifier: ^3.0.0 version: 3.0.0 jsdom: specifier: ^24.0.0 version: 24.0.0 + lint-staged: + specifier: ^15.2.2 + version: 15.2.2 postcss: specifier: ^8.4.38 version: 8.4.38 @@ -2946,6 +2952,11 @@ packages: uri-js: 4.4.1 dev: true + /ansi-escapes@6.2.1: + resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} + engines: {node: '>=14.16'} + dev: true + /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -3246,6 +3257,11 @@ packages: supports-color: 7.2.0 dev: true + /chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true + /check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} dependencies: @@ -3267,6 +3283,21 @@ packages: fsevents: 2.3.3 dev: true + /cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + restore-cursor: 4.0.0 + dev: true + + /cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} + dependencies: + slice-ansi: 5.0.0 + string-width: 7.1.0 + dev: true + /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: @@ -3307,6 +3338,11 @@ packages: engines: {node: '>=14'} dev: true + /commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + dev: true + /commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -3652,6 +3688,10 @@ packages: resolution: {integrity: sha512-9ItEpeu15hW5m8jKdriL+BQrgwDTXEL9pn4SkillWFu73ZNNNQ2BKKLS+ZHv2vC9UkNhosAeyfxOf/5OSeTCPA==} dev: true + /emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + dev: true + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true @@ -4046,6 +4086,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + dev: true + /evtd@0.2.4: resolution: {integrity: sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==} dev: false @@ -4215,6 +4259,11 @@ packages: engines: {node: '>=6.9.0'} dev: true + /get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + dev: true + /get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} dev: true @@ -4481,6 +4530,12 @@ packages: engines: {node: '>=16.17.0'} dev: true + /husky@9.0.11: + resolution: {integrity: sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==} + engines: {node: '>=18'} + hasBin: true + dev: true + /iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -4609,6 +4664,18 @@ packages: engines: {node: '>=8'} dev: true + /is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + dev: true + + /is-fullwidth-code-point@5.0.0: + resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + engines: {node: '>=18'} + dependencies: + get-east-asian-width: 1.2.0 + dev: true + /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -4900,10 +4967,46 @@ packages: type-check: 0.4.0 dev: true + /lilconfig@3.0.0: + resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} + engines: {node: '>=14'} + dev: true + /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: true + /lint-staged@15.2.2: + resolution: {integrity: sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==} + engines: {node: '>=18.12.0'} + hasBin: true + dependencies: + chalk: 5.3.0 + commander: 11.1.0 + debug: 4.3.4 + execa: 8.0.1 + lilconfig: 3.0.0 + listr2: 8.0.1 + micromatch: 4.0.5 + pidtree: 0.6.0 + string-argv: 0.3.2 + yaml: 2.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /listr2@8.0.1: + resolution: {integrity: sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==} + engines: {node: '>=18.0.0'} + dependencies: + cli-truncate: 4.0.0 + colorette: 2.0.20 + eventemitter3: 5.0.1 + log-update: 6.0.0 + rfdc: 1.3.1 + wrap-ansi: 9.0.0 + dev: true + /local-pkg@0.4.3: resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} engines: {node: '>=14'} @@ -4943,6 +5046,17 @@ packages: /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + /log-update@6.0.0: + resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==} + engines: {node: '>=18'} + dependencies: + ansi-escapes: 6.2.1 + cli-cursor: 4.0.0 + slice-ansi: 7.1.0 + strip-ansi: 7.1.0 + wrap-ansi: 9.0.0 + dev: true + /loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} dependencies: @@ -5390,6 +5504,12 @@ packages: engines: {node: '>=12'} dev: true + /pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + dev: true + /pinia@2.1.7(typescript@5.4.5)(vue@3.4.25): resolution: {integrity: sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==} peerDependencies: @@ -5618,11 +5738,23 @@ packages: supports-preserve-symlinks-flag: 1.0.0 dev: true + /restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: true + /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} dev: true + /rfdc@1.3.1: + resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} + dev: true + /rollup@4.17.0: resolution: {integrity: sha512-wZJSn0WMtWrxhYKQRt5Z6GIXlziOoMDFmbHmRfL3v+sBTAshx2DBq1AfMArB7eIjF63r4ocn2ZTAyUptg/7kmQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -5800,6 +5932,22 @@ packages: is-fullwidth-code-point: 3.0.0 dev: true + /slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + dev: true + + /slice-ansi@7.1.0: + resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + engines: {node: '>=18'} + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 5.0.0 + dev: true + /source-map-js@1.2.0: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} @@ -5812,6 +5960,11 @@ packages: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} dev: true + /string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + dev: true + /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -5830,6 +5983,15 @@ packages: strip-ansi: 7.1.0 dev: true + /string-width@7.1.0: + resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==} + engines: {node: '>=18'} + dependencies: + emoji-regex: 10.3.0 + get-east-asian-width: 1.2.0 + strip-ansi: 7.1.0 + dev: true + /string.prototype.trim@1.2.9: resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} engines: {node: '>= 0.4'} @@ -6825,6 +6987,15 @@ packages: strip-ansi: 7.1.0 dev: true + /wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + dependencies: + ansi-styles: 6.2.1 + string-width: 7.1.0 + strip-ansi: 7.1.0 + dev: true + /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true @@ -6872,6 +7043,11 @@ packages: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true + /yaml@2.3.4: + resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} + engines: {node: '>= 14'} + dev: true + /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} From a57fe9ac2b9fd901ca7669c1614b24d56eab0056 Mon Sep 17 00:00:00 2001 From: Wisdom Date: Thu, 9 May 2024 13:29:10 +0800 Subject: [PATCH 2/2] docs: update readme --- README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 035512e..c8cb9d0 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ## 简介 -🗂️ 一个基于 Vite5 + Vue3 + Naive UI + TS + ESLint(v9) 的 Tab 切换选项卡演示项目,其内部抽象出了一个**比较贴近实战**的**项目管理系统**的业务场景,虽不涉及特别复杂的业务逻辑但也不失灵活,旨在更好地理解和展示如何使用 Tab 标签页组件,项目基于原子化 UnoCSS 框架配置主题,还自带一个模块化的组件开发环境,使页面组件、路由组件、状态管理和样式等模块可以根据 Modules 目录进行解耦,它是一个开箱即用的解决方案,也适合作为快速开发中后台前端,可用于学习和参考 +🗂️ 一个基于 Vite5 + Vue3 + Naive UI + Pinia + TS + ESLint(v9) + Unplugin + Husky 的 Tab 切换选项卡演示项目,其内部抽象出了一个**比较贴近实战**的**项目管理系统**的业务场景,虽不涉及特别复杂的业务逻辑但也不失灵活,旨在更好地理解和展示如何使用 Tab 标签页组件,项目基于原子化 UnoCSS 框架配置主题,还自带一个模块化的组件开发环境,使页面组件、路由组件、状态管理和样式等模块可以根据 Modules 目录进行解耦,它是一个开箱即用的解决方案,也适合作为快速开发中后台前端,可用于学习和参考 __[🌈 Live Demo 在线体验](https://pdsuwwz.github.io/vue3-tab-demo)__ @@ -21,10 +21,12 @@ __[🌈 Live Demo 在线体验](https://pdsuwwz.github.io/vue3-tab-demo)__ * Naive UI 2.x * Vue 3.4.x -* Vite 5.x +* Vite 5.x + Vitest * Pinia 2.x -* TypeScript 5.x +* TypeScript 5.x * ESLint 9.x + Stylistic +* Husky + lint-staged +* Lodash * VueUse * Unplugin + UnoCSS @@ -234,7 +236,9 @@ export interface WorkTab { * Vue 组件名称需要与对应路由名称保持一致,否则 Keep Alive 将会失效 * 由于 Tab 组件自身解耦了所有的业务逻辑,所以涉及到路由一级动态 ID 这种跟业务路由强耦合的地方都需要再自行传入,嫌麻烦的可以直接修改源码中的所有 `dynamicCacheSpacePrefixKey` 字段或将相关 hook 二次封装一下。具体参考这两个位置:[源码1](src/widgets/WorkTabs/store.ts#L85) 和 [源码2](src/hooks/useTabRouter.ts#L50) -* 推荐使用本项目进行二次改造和开发实际的业务项目 +* 若 Husky 未生效,可能是由于未完成初始化,执行 `pnpm run prepare` 进行初始化再尝试 +* 推荐使用本项目进行二次开发和定制实际的业务项目 + ## 说明 @@ -247,9 +251,9 @@ export interface WorkTab { * 如有问题请直接在 Issues 中提, 或者您发现问题并有非常好的解决方案, 欢迎 PR 👍 -* 推荐一个 Vue3 + TS + Element Plus 开源入门项目, 对 Element Plus UI 库感兴趣的朋友可以去看看。[地址在这里](https://github.com/pdsuwwz/vite-ts-starter) +* 推荐一个 Vite5 + Vue3 + TS + Element Plus 开源入门项目, 对 Element Plus UI 库感兴趣的朋友可以去看看。[地址在这里](https://github.com/pdsuwwz/vite-ts-starter) -* 另外一个 Vue3 + Naive UI + TS 的入门项目, 比当前项目简洁很多, 非常适合入门练习和二次开发。[地址在这里](https://github.com/pdsuwwz/vite-naive-template) +* 另外一个 Vite5 + Vue3 + Naive UI + TS 的入门项目, 比当前项目简洁很多, 非常适合入门练习和二次开发。[地址在这里](https://github.com/pdsuwwz/vite-naive-template) ## License