From ada975a8f5e6d8df9a4234e55f42ab9e71214fa7 Mon Sep 17 00:00:00 2001 From: Riley Ho Date: Wed, 26 Nov 2025 21:35:13 +0800 Subject: [PATCH 1/3] chore: add types to ssgOptions in vite.config.ts See https://github.com/antfu-collective/vite-ssg/issues/279 --- tsconfig.node.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.node.json b/tsconfig.node.json index 4d2f4bc..e1f2188 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -6,7 +6,7 @@ "moduleDetection": "force", "module": "ESNext", "moduleResolution": "bundler", - "types": ["node"], + "types": ["node", "vite-ssg"], "allowImportingTsExtensions": true, "strict": true, "noFallthroughCasesInSwitch": true, From d2827800ee74df20cc092ae0347367454b525a8c Mon Sep 17 00:00:00 2001 From: Riley Ho Date: Sat, 29 Nov 2025 21:21:14 +0800 Subject: [PATCH 2/3] feat: migrate to unplugin-vue-router for file-based routing --- package.json | 3 +- pnpm-lock.yaml | 288 ++++++++++++++++++++++++++-- src/main.ts | 2 +- src/pages/[lang]/about-us/index.vue | 13 ++ src/pages/[lang]/index.vue | 12 ++ src/pages/index.vue | 21 +- src/routes.ts | 23 --- tsconfig.app.json | 4 +- typed-router.d.ts | 90 +++++++++ vite.config.ts | 15 ++ 10 files changed, 424 insertions(+), 47 deletions(-) create mode 100644 src/pages/[lang]/about-us/index.vue create mode 100644 src/pages/[lang]/index.vue delete mode 100644 src/routes.ts create mode 100644 typed-router.d.ts diff --git a/package.json b/package.json index aac6958..a99c7f9 100644 --- a/package.json +++ b/package.json @@ -51,12 +51,13 @@ "unocss": "^66.5.0", "unocss-preset-theme": "^0.14.1", "unplugin-icons": "^22.2.0", + "unplugin-vue-router": "^0.17.1", "vite": "^6.0.0", "vite-plugin-dts": "~4.5.0", "vite-ssg": "^28.1.0", "vitest": "^3.0.0", "vue-i18n": "^11.1.12", - "vue-router": "^4.5.1", + "vue-router": "^4.6.3", "vue-tsc": "^2.2.8" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c41607f..4e9b60d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,7 +14,7 @@ importers: devDependencies: '@antfu/eslint-config': specifier: ^5.2.1 - version: 5.2.1(@vue/compiler-sfc@3.5.20)(eslint@9.34.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4) + version: 5.2.1(@vue/compiler-sfc@3.5.25)(eslint@9.34.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4) '@iconify-json/tabler': specifier: ^1.2.22 version: 1.2.22 @@ -113,7 +113,10 @@ importers: version: 0.14.1(@unocss/core@66.5.0) unplugin-icons: specifier: ^22.2.0 - version: 22.2.0(@vue/compiler-sfc@3.5.20) + version: 22.2.0(@vue/compiler-sfc@3.5.25) + unplugin-vue-router: + specifier: ^0.17.1 + version: 0.17.1(@vue/compiler-sfc@3.5.25)(typescript@5.8.3)(vue-router@4.6.3(vue@3.5.20(typescript@5.8.3)))(vue@3.5.20(typescript@5.8.3)) vite: specifier: ^6.0.0 version: 6.3.5(@types/node@24.3.0)(jiti@2.4.2)(terser@5.44.0)(yaml@2.8.1) @@ -122,7 +125,7 @@ importers: version: 4.5.4(@types/node@24.3.0)(rollup@4.49.0)(typescript@5.8.3)(vite@6.3.5(@types/node@24.3.0)(jiti@2.4.2)(terser@5.44.0)(yaml@2.8.1)) vite-ssg: specifier: ^28.1.0 - version: 28.1.0(unhead@2.0.14)(vite@6.3.5(@types/node@24.3.0)(jiti@2.4.2)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.20(typescript@5.8.3)))(vue@3.5.20(typescript@5.8.3)) + version: 28.1.0(unhead@2.0.14)(vite@6.3.5(@types/node@24.3.0)(jiti@2.4.2)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.6.3(vue@3.5.20(typescript@5.8.3)))(vue@3.5.20(typescript@5.8.3)) vitest: specifier: ^3.0.0 version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@22.1.0)(terser@5.44.0)(yaml@2.8.1) @@ -130,8 +133,8 @@ importers: specifier: ^11.1.12 version: 11.1.12(vue@3.5.20(typescript@5.8.3)) vue-router: - specifier: ^4.5.1 - version: 4.5.1(vue@3.5.20(typescript@5.8.3)) + specifier: ^4.6.3 + version: 4.6.3(vue@3.5.20(typescript@5.8.3)) vue-tsc: specifier: ^2.2.8 version: 2.2.12(typescript@5.8.3) @@ -213,6 +216,10 @@ packages: resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} engines: {node: '>=6.9.0'} + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -221,6 +228,10 @@ packages: resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.27.7': resolution: {integrity: sha512-qnzXzDXdr/po3bOTbTIQZ7+TxNKxpkN5IifVLXS+r7qwynkZfPyjZfE7hCXbo7IoO9TNcSyibgONsf2HauUd3Q==} engines: {node: '>=6.0.0'} @@ -231,6 +242,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} @@ -243,6 +259,10 @@ packages: resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} engines: {node: '>=6.9.0'} + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + '@clack/core@0.5.0': resolution: {integrity: sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==} @@ -1110,24 +1130,51 @@ packages: '@volar/language-core@2.4.15': resolution: {integrity: sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==} + '@volar/language-core@2.4.23': + resolution: {integrity: sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==} + '@volar/source-map@2.4.15': resolution: {integrity: sha512-CPbMWlUN6hVZJYGcU/GSoHu4EnCHiLaXI9n8c9la6RaI9W5JHX+NqG+GSQcB0JdC2FIBLdZJwGsfKyBB71VlTg==} + '@volar/source-map@2.4.23': + resolution: {integrity: sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q==} + '@volar/typescript@2.4.15': resolution: {integrity: sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==} + '@vue-macros/common@3.1.1': + resolution: {integrity: sha512-afW2DMjgCBVs33mWRlz7YsGHzoEEupnl0DK5ZTKsgziAlLh5syc5m+GM7eqeYrgiQpwMaVxa1fk73caCvPxyAw==} + engines: {node: '>=20.19.0'} + peerDependencies: + vue: ^2.7.0 || ^3.2.25 + peerDependenciesMeta: + vue: + optional: true + '@vue/compiler-core@3.5.20': resolution: {integrity: sha512-8TWXUyiqFd3GmP4JTX9hbiTFRwYHgVL/vr3cqhr4YQ258+9FADwvj7golk2sWNGHR67QgmCZ8gz80nQcMokhwg==} + '@vue/compiler-core@3.5.25': + resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==} + '@vue/compiler-dom@3.5.20': resolution: {integrity: sha512-whB44M59XKjqUEYOMPYU0ijUV0G+4fdrHVKDe32abNdX/kJe1NUEMqsi4cwzXa9kyM9w5S8WqFsrfo1ogtBZGQ==} + '@vue/compiler-dom@3.5.25': + resolution: {integrity: sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==} + '@vue/compiler-sfc@3.5.20': resolution: {integrity: sha512-SFcxapQc0/feWiSBfkGsa1v4DOrnMAQSYuvDMpEaxbpH5dKbnEM5KobSNSgU+1MbHCl+9ftm7oQWxvwDB6iBfw==} + '@vue/compiler-sfc@3.5.25': + resolution: {integrity: sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==} + '@vue/compiler-ssr@3.5.20': resolution: {integrity: sha512-RSl5XAMc5YFUXpDQi+UQDdVjH9FnEpLDHIALg5J0ITHxkEzJ8uQLlo7CIbjPYqmZtt6w0TsIPbo1izYXwDG7JA==} + '@vue/compiler-ssr@3.5.25': + resolution: {integrity: sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==} + '@vue/compiler-vue2@2.7.16': resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} @@ -1150,6 +1197,14 @@ packages: typescript: optional: true + '@vue/language-core@3.1.5': + resolution: {integrity: sha512-FMcqyzWN+sYBeqRMWPGT2QY0mUasZMVIuHvmb5NT3eeqPrbHBYtCP8JWEUCDCgM+Zr62uuWY/qoeBrPrzfa78w==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + '@vue/reactivity@3.5.20': resolution: {integrity: sha512-hS8l8x4cl1fmZpSQX/NXlqWKARqEsNmfkwOIYqtR2F616NGfsLUm0G6FQBK6uDKUCVyi1YOL8Xmt/RkZcd/jYQ==} @@ -1167,6 +1222,9 @@ packages: '@vue/shared@3.5.20': resolution: {integrity: sha512-SoRGP596KU/ig6TfgkCMbXkr4YJ91n/QSdMuqeP5r3hVIYA3CPHUBCc7Skak0EAKV+5lL4KyIh61VA/pK1CIAA==} + '@vue/shared@3.5.25': + resolution: {integrity: sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==} + '@vue/test-utils@2.4.6': resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==} @@ -1238,6 +1296,9 @@ packages: alien-signals@1.0.13: resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==} + alien-signals@3.1.1: + resolution: {integrity: sha512-ogkIWbVrLwKtHY6oOAXaYkAxP+cTH7V5FZ5+Tm4NZFd8VDZ6uNMDrfzqctTZ42eTMCSR3ne3otpcxmqSnFfPYA==} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -1276,6 +1337,14 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + ast-kit@2.2.0: + resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} + engines: {node: '>=20.19.0'} + + ast-walker-scope@0.8.3: + resolution: {integrity: sha512-cbdCP0PGOBq0ASG+sjnKIoYkWMKhhz+F/h9pRexUdX2Hd38+WOlBkRKlqkGOSm0YQpcFMQBJeK4WspUAkwsEdg==} + engines: {node: '>=20.19.0'} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -1354,6 +1423,10 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + ci-info@4.3.0: resolution: {integrity: sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==} engines: {node: '>=8'} @@ -2120,6 +2193,11 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + jsonc-eslint-parser@2.4.0: resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2170,9 +2248,16 @@ packages: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} + magic-string-ast@1.0.3: + resolution: {integrity: sha512-CvkkH1i81zl7mmb94DsRiFeG9V2fR2JeuK8yDgS8oiZSFa++wWLEgZ5ufEOyLHbvSbD1gTRKv9NdX69Rnvr9JA==} + engines: {node: '>=20.19.0'} + magic-string@0.30.18: resolution: {integrity: sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + markdown-it-abbr@2.0.0: resolution: {integrity: sha512-of7C8pXSjXjDojW4neNP+jD7inUYH/DO0Ca+K/4FUEccg0oHAEX/nfscw0jfz66PJbYWOAT9U8mjO21X5p6aAw==} @@ -2573,6 +2658,10 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + refa@0.12.1: resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} @@ -2641,6 +2730,9 @@ packages: resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} engines: {node: ^14.0.0 || >=16.0.0} + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + semver@7.5.4: resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} engines: {node: '>=10'} @@ -2774,6 +2866,10 @@ packages: resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + tinypool@1.1.1: resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} engines: {node: ^18.0.0 || >=20.0.0} @@ -2928,6 +3024,19 @@ packages: resolution: {integrity: sha512-JLoggz+PvLVMJo+jZt97hdIIIZ2yTzGgft9e9q8iMrC4ewufl62ekeW7mixBghonn2gVb/ICjyvlmOCUBnJLQg==} engines: {node: '>=20.19.0'} + unplugin-utils@0.3.1: + resolution: {integrity: sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==} + engines: {node: '>=20.19.0'} + + unplugin-vue-router@0.17.1: + resolution: {integrity: sha512-V5QXY9kGARKUkp/JKz1lWzb4Itc6A8oKS5IUq9MkCR3jUcxnXzjvXqctYaxqvCsrWpO4sYuT/HxPRHFn9u/VSA==} + peerDependencies: + '@vue/compiler-sfc': ^3.5.17 + vue-router: ^4.6.0 + peerDependenciesMeta: + vue-router: + optional: true + unplugin@2.3.10: resolution: {integrity: sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==} engines: {node: '>=18.12.0'} @@ -3068,10 +3177,10 @@ packages: peerDependencies: vue: ^3.0.0 - vue-router@4.5.1: - resolution: {integrity: sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==} + vue-router@4.6.3: + resolution: {integrity: sha512-ARBedLm9YlbvQomnmq91Os7ck6efydTSpRP3nuOKCvgJOHNrhRoJDSKtee8kcL1Vf7nz6U+PMBL+hTvR3bTVQg==} peerDependencies: - vue: ^3.2.0 + vue: ^3.5.0 vue-tsc@2.2.12: resolution: {integrity: sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==} @@ -3192,7 +3301,7 @@ packages: snapshots: - '@antfu/eslint-config@5.2.1(@vue/compiler-sfc@3.5.20)(eslint@9.34.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4)': + '@antfu/eslint-config@5.2.1(@vue/compiler-sfc@3.5.25)(eslint@9.34.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4)': dependencies: '@antfu/install-pkg': 1.1.0 '@clack/prompts': 0.11.0 @@ -3223,7 +3332,7 @@ snapshots: eslint-plugin-unused-imports: 4.2.0(@typescript-eslint/eslint-plugin@8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.34.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.34.0(jiti@2.4.2)) eslint-plugin-vue: 10.4.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.34.0(jiti@2.4.2))(vue-eslint-parser@10.2.0(eslint@9.34.0(jiti@2.4.2))) eslint-plugin-yml: 1.18.0(eslint@9.34.0(jiti@2.4.2)) - eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.20)(eslint@9.34.0(jiti@2.4.2)) + eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.25)(eslint@9.34.0(jiti@2.4.2)) globals: 16.3.0 jsonc-eslint-parser: 2.4.0 local-pkg: 1.1.2 @@ -3269,10 +3378,20 @@ snapshots: '@jridgewell/trace-mapping': 0.3.30 jsesc: 3.1.0 + '@babel/generator@7.28.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.30 + jsesc: 3.1.0 + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.27.1': {} + '@babel/helper-validator-identifier@7.28.5': {} + '@babel/parser@7.27.7': dependencies: '@babel/types': 7.28.2 @@ -3281,6 +3400,10 @@ snapshots: dependencies: '@babel/types': 7.28.2 + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 @@ -3304,6 +3427,11 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@clack/core@0.5.0': dependencies: picocolors: 1.1.1 @@ -4219,14 +4347,30 @@ snapshots: dependencies: '@volar/source-map': 2.4.15 + '@volar/language-core@2.4.23': + dependencies: + '@volar/source-map': 2.4.23 + '@volar/source-map@2.4.15': {} + '@volar/source-map@2.4.23': {} + '@volar/typescript@2.4.15': dependencies: '@volar/language-core': 2.4.15 path-browserify: 1.0.1 vscode-uri: 3.1.0 + '@vue-macros/common@3.1.1(vue@3.5.20(typescript@5.8.3))': + dependencies: + '@vue/compiler-sfc': 3.5.25 + ast-kit: 2.2.0 + local-pkg: 1.1.2 + magic-string-ast: 1.0.3 + unplugin-utils: 0.3.1 + optionalDependencies: + vue: 3.5.20(typescript@5.8.3) + '@vue/compiler-core@3.5.20': dependencies: '@babel/parser': 7.28.3 @@ -4235,11 +4379,24 @@ snapshots: estree-walker: 2.0.2 source-map-js: 1.2.1 + '@vue/compiler-core@3.5.25': + dependencies: + '@babel/parser': 7.28.5 + '@vue/shared': 3.5.25 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + '@vue/compiler-dom@3.5.20': dependencies: '@vue/compiler-core': 3.5.20 '@vue/shared': 3.5.20 + '@vue/compiler-dom@3.5.25': + dependencies: + '@vue/compiler-core': 3.5.25 + '@vue/shared': 3.5.25 + '@vue/compiler-sfc@3.5.20': dependencies: '@babel/parser': 7.28.3 @@ -4252,11 +4409,28 @@ snapshots: postcss: 8.5.6 source-map-js: 1.2.1 + '@vue/compiler-sfc@3.5.25': + dependencies: + '@babel/parser': 7.28.5 + '@vue/compiler-core': 3.5.25 + '@vue/compiler-dom': 3.5.25 + '@vue/compiler-ssr': 3.5.25 + '@vue/shared': 3.5.25 + estree-walker: 2.0.2 + magic-string: 0.30.21 + postcss: 8.5.6 + source-map-js: 1.2.1 + '@vue/compiler-ssr@3.5.20': dependencies: '@vue/compiler-dom': 3.5.20 '@vue/shared': 3.5.20 + '@vue/compiler-ssr@3.5.25': + dependencies: + '@vue/compiler-dom': 3.5.25 + '@vue/shared': 3.5.25 + '@vue/compiler-vue2@2.7.16': dependencies: de-indent: 1.0.2 @@ -4290,6 +4464,18 @@ snapshots: optionalDependencies: typescript: 5.8.3 + '@vue/language-core@3.1.5(typescript@5.8.3)': + dependencies: + '@volar/language-core': 2.4.23 + '@vue/compiler-dom': 3.5.20 + '@vue/shared': 3.5.20 + alien-signals: 3.1.1 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + picomatch: 4.0.3 + optionalDependencies: + typescript: 5.8.3 + '@vue/reactivity@3.5.20': dependencies: '@vue/shared': 3.5.20 @@ -4314,6 +4500,8 @@ snapshots: '@vue/shared@3.5.20': {} + '@vue/shared@3.5.25': {} + '@vue/test-utils@2.4.6': dependencies: js-beautify: 1.15.4 @@ -4375,6 +4563,8 @@ snapshots: alien-signals@1.0.13: {} + alien-signals@3.1.1: {} + ansi-regex@5.0.1: {} ansi-regex@6.2.0: {} @@ -4402,6 +4592,16 @@ snapshots: assertion-error@2.0.1: {} + ast-kit@2.2.0: + dependencies: + '@babel/parser': 7.28.5 + pathe: 2.0.3 + + ast-walker-scope@0.8.3: + dependencies: + '@babel/parser': 7.28.5 + ast-kit: 2.2.0 + asynckit@0.4.0: {} balanced-match@1.0.2: {} @@ -4483,6 +4683,10 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + ci-info@4.3.0: {} clean-css@5.3.3: @@ -4887,9 +5091,9 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.20)(eslint@9.34.0(jiti@2.4.2)): + eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.25)(eslint@9.34.0(jiti@2.4.2)): dependencies: - '@vue/compiler-sfc': 3.5.20 + '@vue/compiler-sfc': 3.5.25 eslint: 9.34.0(jiti@2.4.2) eslint-scope@8.4.0: @@ -5331,6 +5535,8 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} + json5@2.2.3: {} + jsonc-eslint-parser@2.4.0: dependencies: acorn: 8.15.0 @@ -5387,10 +5593,18 @@ snapshots: dependencies: yallist: 4.0.0 + magic-string-ast@1.0.3: + dependencies: + magic-string: 0.30.21 + magic-string@0.30.18: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + markdown-it-abbr@2.0.0: {} markdown-it-anchor@9.2.0(@types/markdown-it@14.1.2)(markdown-it@14.1.0): @@ -5946,6 +6160,8 @@ snapshots: dependencies: picomatch: 2.3.1 + readdirp@4.1.2: {} + refa@0.12.1: dependencies: '@eslint-community/regexpp': 4.12.1 @@ -6025,6 +6241,8 @@ snapshots: refa: 0.12.1 regexp-ast-analysis: 0.7.1 + scule@1.3.0: {} + semver@7.5.4: dependencies: lru-cache: 6.0.0 @@ -6141,6 +6359,11 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + tinypool@1.1.1: {} tinyrainbow@2.0.0: {} @@ -6273,7 +6496,7 @@ snapshots: - postcss - supports-color - unplugin-icons@22.2.0(@vue/compiler-sfc@3.5.20): + unplugin-icons@22.2.0(@vue/compiler-sfc@3.5.25): dependencies: '@antfu/install-pkg': 1.1.0 '@iconify/utils': 2.3.0 @@ -6281,7 +6504,7 @@ snapshots: local-pkg: 1.1.2 unplugin: 2.3.10 optionalDependencies: - '@vue/compiler-sfc': 3.5.20 + '@vue/compiler-sfc': 3.5.25 transitivePeerDependencies: - supports-color @@ -6290,6 +6513,37 @@ snapshots: pathe: 2.0.3 picomatch: 4.0.3 + unplugin-utils@0.3.1: + dependencies: + pathe: 2.0.3 + picomatch: 4.0.3 + + unplugin-vue-router@0.17.1(@vue/compiler-sfc@3.5.25)(typescript@5.8.3)(vue-router@4.6.3(vue@3.5.20(typescript@5.8.3)))(vue@3.5.20(typescript@5.8.3)): + dependencies: + '@babel/generator': 7.28.5 + '@vue-macros/common': 3.1.1(vue@3.5.20(typescript@5.8.3)) + '@vue/compiler-sfc': 3.5.25 + '@vue/language-core': 3.1.5(typescript@5.8.3) + ast-walker-scope: 0.8.3 + chokidar: 4.0.3 + json5: 2.2.3 + local-pkg: 1.1.2 + magic-string: 0.30.21 + mlly: 1.8.0 + muggle-string: 0.4.1 + pathe: 2.0.3 + picomatch: 4.0.3 + scule: 1.3.0 + tinyglobby: 0.2.15 + unplugin: 2.3.10 + unplugin-utils: 0.3.1 + yaml: 2.8.1 + optionalDependencies: + vue-router: 4.6.3(vue@3.5.20(typescript@5.8.3)) + transitivePeerDependencies: + - typescript + - vue + unplugin@2.3.10: dependencies: '@jridgewell/remapping': 2.3.5 @@ -6354,7 +6608,7 @@ snapshots: - rollup - supports-color - vite-ssg@28.1.0(unhead@2.0.14)(vite@6.3.5(@types/node@24.3.0)(jiti@2.4.2)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.20(typescript@5.8.3)))(vue@3.5.20(typescript@5.8.3)): + vite-ssg@28.1.0(unhead@2.0.14)(vite@6.3.5(@types/node@24.3.0)(jiti@2.4.2)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.6.3(vue@3.5.20(typescript@5.8.3)))(vue@3.5.20(typescript@5.8.3)): dependencies: '@unhead/dom': 2.0.14(unhead@2.0.14) '@unhead/vue': 2.0.14(vue@3.5.20(typescript@5.8.3)) @@ -6366,7 +6620,7 @@ snapshots: vite: 6.3.5(@types/node@24.3.0)(jiti@2.4.2)(terser@5.44.0)(yaml@2.8.1) vue: 3.5.20(typescript@5.8.3) optionalDependencies: - vue-router: 4.5.1(vue@3.5.20(typescript@5.8.3)) + vue-router: 4.6.3(vue@3.5.20(typescript@5.8.3)) transitivePeerDependencies: - bufferutil - canvas @@ -6458,7 +6712,7 @@ snapshots: '@vue/devtools-api': 6.6.4 vue: 3.5.20(typescript@5.8.3) - vue-router@4.5.1(vue@3.5.20(typescript@5.8.3)): + vue-router@4.6.3(vue@3.5.20(typescript@5.8.3)): dependencies: '@vue/devtools-api': 6.6.4 vue: 3.5.20(typescript@5.8.3) diff --git a/src/main.ts b/src/main.ts index 42e5210..aae5c99 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,7 +1,7 @@ import { ViteSSG } from 'vite-ssg' +import { routes } from 'vue-router/auto-routes' import App from '@/App.vue' import { setupModules } from '@/modules' -import { routes } from '@/routes' import 'virtual:uno.css' export const createApp = ViteSSG( diff --git a/src/pages/[lang]/about-us/index.vue b/src/pages/[lang]/about-us/index.vue new file mode 100644 index 0000000..e4add5a --- /dev/null +++ b/src/pages/[lang]/about-us/index.vue @@ -0,0 +1,13 @@ + + + + + diff --git a/src/pages/[lang]/index.vue b/src/pages/[lang]/index.vue new file mode 100644 index 0000000..52ef948 --- /dev/null +++ b/src/pages/[lang]/index.vue @@ -0,0 +1,12 @@ + + + diff --git a/src/pages/index.vue b/src/pages/index.vue index 7be610f..95607e1 100644 --- a/src/pages/index.vue +++ b/src/pages/index.vue @@ -1,5 +1,20 @@ + + diff --git a/src/routes.ts b/src/routes.ts deleted file mode 100644 index 1f04ede..0000000 --- a/src/routes.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { Component } from 'vue' - -const pages = Object.entries<{ default: Component }>(import.meta.glob('@/pages/**/*.vue', { eager: true })) - .map(([_path, component]) => { - const path = _path - .replace(/^\/src\/pages\//, '') - .replace(/\.vue$/, '') - .split('/') - .map((segment) => segment === 'index' ? '' : segment) - .join('/') - - return { - path: `${path}`, - component: component.default, - } - }) - -export const routes = [ - { - path: '/:lang', - children: pages, - }, -] diff --git a/tsconfig.app.json b/tsconfig.app.json index 350e8ff..384d1d6 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -3,7 +3,7 @@ "compilerOptions": { "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "paths": { "@/*": ["./src/*"] }, - "types": ["vite/client", "unplugin-icons/types/vue"], + "types": ["vite/client", "unplugin-icons/types/vue", "unplugin-vue-router/client"], /* Linting */ "strict": true, @@ -13,5 +13,5 @@ "erasableSyntaxOnly": true, "noUncheckedSideEffectImports": true }, - "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "src/typed-router.d.ts"] } diff --git a/typed-router.d.ts b/typed-router.d.ts new file mode 100644 index 0000000..ed86dd4 --- /dev/null +++ b/typed-router.d.ts @@ -0,0 +1,90 @@ +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// noinspection ES6UnusedImports +// Generated by unplugin-vue-router. ‼️ DO NOT MODIFY THIS FILE ‼️ +// It's recommended to commit this file. +// Make sure to add this file to your tsconfig.json file as an "includes" or "files" entry. + +declare module 'vue-router/auto-resolver' { + export type ParamParserCustom = never +} + +declare module 'vue-router/auto-routes' { + import type { + RouteRecordInfo, + ParamValue, + ParamValueOneOrMore, + ParamValueZeroOrMore, + ParamValueZeroOrOne, + } from 'vue-router' + + /** + * Route name map generated by unplugin-vue-router + */ + export interface RouteNamedMap { + '/': RouteRecordInfo< + '/', + '/', + Record, + Record, + | never + >, + '/[lang]/': RouteRecordInfo< + '/[lang]/', + '/:lang', + { lang: ParamValue }, + { lang: ParamValue }, + | never + >, + '/[lang]/about-us/': RouteRecordInfo< + '/[lang]/about-us/', + '/:lang/about-us', + { lang: ParamValue }, + { lang: ParamValue }, + | never + >, + } + + /** + * Route file to route info map by unplugin-vue-router. + * Used by the \`sfc-typed-router\` Volar plugin to automatically type \`useRoute()\`. + * + * Each key is a file path relative to the project root with 2 properties: + * - routes: union of route names of the possible routes when in this page (passed to useRoute<...>()) + * - views: names of nested views (can be passed to ) + * + * @internal + */ + export interface _RouteFileInfoMap { + 'src/pages/index.vue': { + routes: + | '/' + views: + | never + } + 'src/pages/[lang]/index.vue': { + routes: + | '/[lang]/' + views: + | never + } + 'src/pages/[lang]/about-us/index.vue': { + routes: + | '/[lang]/about-us/' + views: + | never + } + } + + /** + * Get a union of possible route names in a certain route component file. + * Used by the \`sfc-typed-router\` Volar plugin to automatically type \`useRoute()\`. + * + * @internal + */ + export type _RouteNamesForFilePath = + _RouteFileInfoMap extends Record + ? Info['routes'] + : keyof RouteNamedMap +} diff --git a/vite.config.ts b/vite.config.ts index 3d21264..c3985b8 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -3,6 +3,7 @@ import vue from '@vitejs/plugin-vue' import UnoCss from 'unocss/vite' import { FileSystemIconLoader } from 'unplugin-icons/loaders' import Icons from 'unplugin-icons/vite' +import VueRouter from 'unplugin-vue-router/vite' import { defineConfig } from 'vite' export default defineConfig(() => ({ @@ -15,6 +16,7 @@ export default defineConfig(() => ({ host: 'localhost', }, plugins: [ + VueRouter(), vue(), UnoCss(), Icons({ @@ -39,5 +41,18 @@ export default defineConfig(() => ({ ssgOptions: { dirStyle: 'nested' as const, formatting: 'minify' as const, + includedRoutes(paths) { + // Generate routes for each language + const languages = ['en', 'zh'] + + return paths.flatMap((path) => { + // For dynamic routes with :lang parameter, generate one version per language + if (path.includes(':lang')) { + return languages.map((lang) => path.replace(/:lang/g, lang)) + } + // For static routes, return as-is + return path + }) + }, }, })) From 22e65ef1b4df9ac477e13ddfd70b4956e51c008b Mon Sep 17 00:00:00 2001 From: Riley Ho Date: Sat, 29 Nov 2025 21:31:46 +0800 Subject: [PATCH 3/3] fix: correct typed-router.d.ts path in tsconfig --- tsconfig.app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.app.json b/tsconfig.app.json index 384d1d6..01105aa 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -13,5 +13,5 @@ "erasableSyntaxOnly": true, "noUncheckedSideEffectImports": true }, - "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "src/typed-router.d.ts"] + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "typed-router.d.ts"] }