From 5202dd5accc0f0637d02a3c8d71cef1caa2409d9 Mon Sep 17 00:00:00 2001 From: Vanisper <273266469@qq.com> Date: Fri, 8 May 2026 03:33:03 +0800 Subject: [PATCH 1/2] =?UTF-8?q?refactor(uniapp):=20=E8=87=AA=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E9=85=8D=E7=BD=AE=E8=A7=A3=E6=9E=90=E5=B9=B6=E8=A1=A5?= =?UTF-8?q?=E5=85=85=E5=8D=95=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 2 +- examples/vue3+vite+ts/package.json | 1 - package.json | 6 +- pnpm-lock.yaml | 467 ++++++++++++++++--------- pnpm-workspace.yaml | 1 - src/plugin/subpackages-optimization.ts | 2 +- src/utils/uniapp/config.test.ts | 272 ++++++++++++++ src/utils/uniapp/config.ts | 392 +++++++++++++++++++++ src/utils/uniapp/index.ts | 1 + vitest.config.ts | 8 + 10 files changed, 990 insertions(+), 162 deletions(-) create mode 100644 src/utils/uniapp/config.test.ts create mode 100644 src/utils/uniapp/config.ts create mode 100644 vitest.config.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 206b25b..84edd30 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,5 @@ { - "typescript.tsdk": "node_modules/typescript/lib", + "js/ts.tsdk.path": "node_modules/typescript/lib", "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit", "source.organizeImports": "never" diff --git a/examples/vue3+vite+ts/package.json b/examples/vue3+vite+ts/package.json index 05d8e10..5ed9dec 100644 --- a/examples/vue3+vite+ts/package.json +++ b/examples/vue3+vite+ts/package.json @@ -22,7 +22,6 @@ "devDependencies": { "@dcloudio/types": "catalog:uniapp", "@dcloudio/uni-automator": "catalog:uniapp", - "@dcloudio/uni-cli-shared": "catalog:uniapp", "@dcloudio/vite-plugin-uni": "catalog:uniapp", "@https-enable/types": "^0.1.1", "@types/lodash": "catalog:", diff --git a/package.json b/package.json index 2b272f4..9e2d4dc 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,8 @@ "scripts": { "build": "tsdown", "dev": "tsdown --watch", + "test": "vitest run", + "test:watch": "vitest", "release": "npm run build && bumpp", "prepublishOnly": "npm run build", "prepare": "simple-git-hooks && npm run build", @@ -62,7 +64,6 @@ "vue": "^3.0.0" }, "dependencies": { - "@dcloudio/uni-cli-shared": "3.0.0-4020820240925001", "@vue/compiler-sfc": "catalog:", "ast-kit": "^2.2.0", "chalk": "4.1.2", @@ -84,7 +85,8 @@ "simple-git-hooks": "^2.11.1", "tsdown": "^0.18.1", "typescript": "^5.7.3", - "vite": "^4.0.0" + "vite": "^4.0.0", + "vitest": "0.34.6" }, "simple-git-hooks": { "pre-commit": "pnpm lint-staged", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9ec6e8d..770bba2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,9 +25,6 @@ catalogs: '@dcloudio/uni-automator': specifier: 3.0.0-4060620250520001 version: 3.0.0-4060620250520001 - '@dcloudio/uni-cli-shared': - specifier: 3.0.0-4060620250520001 - version: 3.0.0-4060620250520001 '@dcloudio/uni-components': specifier: 3.0.0-4060620250520001 version: 3.0.0-4060620250520001 @@ -48,9 +45,6 @@ importers: .: dependencies: - '@dcloudio/uni-cli-shared': - specifier: 3.0.0-4020820240925001 - version: 3.0.0-4020820240925001(postcss@8.5.6)(rollup@3.29.5)(vue@3.4.21(typescript@5.9.3)) '@vue/compiler-sfc': specifier: 'catalog:' version: 3.4.21 @@ -69,7 +63,7 @@ importers: devDependencies: '@antfu/eslint-config': specifier: ^4.3.0 - version: 4.19.0(@vue/compiler-sfc@3.4.21)(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + version: 4.19.0(@vue/compiler-sfc@3.4.21)(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)(vitest@0.34.6(jsdom@16.7.0)(terser@5.44.1)) '@babel/types': specifier: ^7.28.4 version: 7.28.5 @@ -115,6 +109,9 @@ importers: vite: specifier: ^4.0.0 version: 4.5.14(@types/node@22.19.3)(terser@5.44.1) + vitest: + specifier: 0.34.6 + version: 0.34.6(jsdom@16.7.0)(terser@5.44.1) examples/biz-components: dependencies: @@ -186,9 +183,6 @@ importers: '@dcloudio/uni-automator': specifier: catalog:uniapp version: 3.0.0-4060620250520001(jest-environment-node@27.5.1)(jest@27.0.4)(postcss@8.5.6)(rollup@3.29.5)(vue@3.4.21(typescript@5.9.3)) - '@dcloudio/uni-cli-shared': - specifier: catalog:uniapp - version: 3.0.0-4060620250520001(postcss@8.5.6)(rollup@3.29.5)(vue@3.4.21(typescript@5.9.3)) '@dcloudio/vite-plugin-uni': specifier: catalog:uniapp version: 3.0.0-4060620250520001(postcss@8.5.6)(rollup@3.29.5)(vite@4.5.14(@types/node@22.19.3)(terser@5.44.1))(vue@3.4.21(typescript@5.9.3)) @@ -967,10 +961,6 @@ packages: jest: 27.0.4 jest-environment-node: 27.5.1 - '@dcloudio/uni-cli-shared@3.0.0-4020820240925001': - resolution: {integrity: sha512-zWIMxjyc8OdpZU1/ivEfjQQa5jNk2sThIkBS6hM3rs7E68HE6cAxPZqZh9CY0LuM8XsAgILIoY77yTcCM3vMJQ==} - engines: {node: ^14.18.0 || >=16.0.0} - '@dcloudio/uni-cli-shared@3.0.0-4060620250520001': resolution: {integrity: sha512-6OhYL/3xDq2vqqfD6jka8yfNPEjTFcr6qZ1HQvN6YZbM1+AJrgPZkCyhh3w4ypC911lSMVWeWqunIigLLobXAw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -993,9 +983,6 @@ packages: '@dcloudio/uni-h5@3.0.0-4060620250520001': resolution: {integrity: sha512-lfjD85Pj0rLnsPJQKP6T+iy3H1gW/PWwcRU8b/K6lfE0CL74P9DdgZp9VsFRyaTvH1uvwg+PeUElj6iFsI9cSQ==} - '@dcloudio/uni-i18n@3.0.0-4020820240925001': - resolution: {integrity: sha512-+EfuUC79QIYIbKB8cdH0IoY69DYytG9jeybIATSlMwMZjVJznA8dGfvkfgy29mBjgLYThuXyZ1dSZ33DXr9MBw==} - '@dcloudio/uni-i18n@3.0.0-4060620250520001': resolution: {integrity: sha512-UqYcjERvmlb8FPhKqg9xAkDPxjMXG9BjezaVm0PTw33Jm5h2Sf9BnCJZYVg2RNS7+3kPSwUBIGdyC4rBNI4COg==} @@ -1014,9 +1001,6 @@ packages: '@dcloudio/uni-push@3.0.0-4060620250520001': resolution: {integrity: sha512-7ly9CIZQOPu/mkej/M/2OI88Qq2O89E71lbW2NM+isHMbeJWXDTIn84Xdlk9EONWcOw03HuUWLb2ZYqoeDYiTw==} - '@dcloudio/uni-shared@3.0.0-4020820240925001': - resolution: {integrity: sha512-CSzMyxotDk/O8Yc2h1B0Bfm/wiDumexLNRJ0EJxXBX2eCyHpLl9SMrYIDqC0Y7aSHNPYA2UKfoaAujTMGqFmtg==} - '@dcloudio/uni-shared@3.0.0-4060620250520001': resolution: {integrity: sha512-U3VhBYC2+kPDFm7Ap9oZeJTqmys774bcli6kJpNmDYFkgkqOoYUtT+0SueOliREL98ogaqoW42zV5T4XjPXj4w==} @@ -1474,6 +1458,10 @@ packages: node-notifier: optional: true + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/source-map@27.5.1': resolution: {integrity: sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -1738,24 +1726,28 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-arm64-musl@1.0.0-beta.55': resolution: {integrity: sha512-QbNncvqAXziya5wleI+OJvmceEE15vE4yn4qfbI/hwT/+8ZcqxyfRZOOh62KjisXxp4D0h3JZspycXYejxAU3w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [musl] '@rolldown/binding-linux-x64-gnu@1.0.0-beta.55': resolution: {integrity: sha512-YZCTZZM+rujxwVc6A+QZaNMJXVtmabmFYLG2VGQTKaBfYGvBKUgtbMEttnp/oZ88BMi2DzadBVhOmfQV8SuHhw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-musl@1.0.0-beta.55': resolution: {integrity: sha512-28q9OQ/DDpFh2keS4BVAlc3N65/wiqKbk5K1pgLdu/uWbKa8hgUJofhXxqO+a+Ya2HVTUuYHneWsI2u+eu3N5Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [musl] '@rolldown/binding-openharmony-arm64@1.0.0-beta.55': resolution: {integrity: sha512-LiCA4BjCnm49B+j1lFzUtlC+4ZphBv0d0g5VqrEJua/uyv9Ey1v9tiaMql1C8c0TVSNDUmrkfHQ71vuQC7YfpQ==} @@ -1792,6 +1784,9 @@ packages: rollup: optional: true + '@sinclair/typebox@0.27.10': + resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} + '@sinonjs/commons@1.8.6': resolution: {integrity: sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==} @@ -1823,6 +1818,14 @@ packages: '@types/babel__traverse@7.28.0': resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/chai-subset@1.3.6': + resolution: {integrity: sha512-m8lERkkQj+uek18hXOZuec3W/fCRTrU4hrnXjH3qhHy96ytuPaPiWGgu7sJb7tZxZonO75vYAjCvpe/e4VUwRw==} + peerDependencies: + '@types/chai': <5.2.0 + + '@types/chai@4.3.20': + resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} + '@types/conventional-commits-parser@5.0.2': resolution: {integrity: sha512-BgT2szDXnVypgpNxOK8aL5SGjUdaQbC++WZNjF1Qge3Og2+zhHj+RWhmehLhYyvQwqAmvezruVfOf8+3m74W+g==} @@ -1973,6 +1976,21 @@ packages: vitest: optional: true + '@vitest/expect@0.34.6': + resolution: {integrity: sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==} + + '@vitest/runner@0.34.6': + resolution: {integrity: sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==} + + '@vitest/snapshot@0.34.6': + resolution: {integrity: sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==} + + '@vitest/spy@0.34.6': + resolution: {integrity: sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==} + + '@vitest/utils@0.34.6': + resolution: {integrity: sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==} + '@vue/babel-helper-vue-transform-on@1.5.0': resolution: {integrity: sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==} @@ -2063,6 +2081,10 @@ packages: resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} engines: {node: '>=0.4.0'} + acorn-walk@8.3.5: + resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} + engines: {node: '>=0.4.0'} + acorn@7.4.1: resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} engines: {node: '>=0.4.0'} @@ -2153,6 +2175,9 @@ packages: asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + ast-kit@2.2.0: resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} engines: {node: '>=20.19.0'} @@ -2345,6 +2370,10 @@ packages: centra@2.7.0: resolution: {integrity: sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==} + chai@4.5.0: + resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} + engines: {node: '>=4'} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -2370,6 +2399,9 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -2626,6 +2658,10 @@ packages: dedent@0.7.0: resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + engines: {node: '>=6'} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -2681,6 +2717,10 @@ packages: resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dom-walk@0.1.2: resolution: {integrity: sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==} @@ -3213,6 +3253,9 @@ packages: resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} engines: {node: '>=18'} + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -3825,10 +3868,6 @@ packages: resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} engines: {node: '>=14'} - local-pkg@0.5.1: - resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} - engines: {node: '>=14'} - local-pkg@1.1.2: resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} engines: {node: '>=14'} @@ -3900,6 +3939,9 @@ packages: resolution: {integrity: sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==} engines: {node: '>=0.10.0'} + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -4372,9 +4414,15 @@ packages: path-to-regexp@0.1.12: resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + perfect-debounce@1.0.0: resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} @@ -4506,6 +4554,10 @@ packages: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} @@ -4562,6 +4614,9 @@ packages: react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + read-cache@1.0.0: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} @@ -4782,6 +4837,9 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -4843,10 +4901,16 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + statuses@2.0.2: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -4897,8 +4961,8 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-literal@2.1.1: - resolution: {integrity: sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==} + strip-literal@1.3.0: + resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} strip-literal@3.1.0: resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} @@ -4970,6 +5034,9 @@ packages: tiny-conventional-commits-parser@0.0.1: resolution: {integrity: sha512-N5+AZWdBeHNSgTIaxvx0+9mFrnW4H1BbjQ84H7i3TuWSkno8Hju886hLaHZhE/hYEKrfrfl/uHurqpZJHDuYGQ==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinycolor2@1.6.0: resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} @@ -4984,6 +5051,14 @@ packages: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinypool@0.7.0: + resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==} + engines: {node: '>=14.0.0'} + + tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + engines: {node: '>=14.0.0'} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -5062,6 +5137,10 @@ packages: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} @@ -5107,9 +5186,6 @@ packages: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} - unimport@3.14.6: - resolution: {integrity: sha512-CYvbDaTT04Rh8bmD8jz3WPmHYZRG/NnvYVzwD6V1YAlvvKROlAeNDUBhkBGzNav2RKaeuXvlWYaa1V4Lfi/O0g==} - unimport@4.1.1: resolution: {integrity: sha512-j9+fijH6aDd05yv1fXlyt7HSxtOWtGtrZeYTVBsSUg57Iuf+Ps2itIZjeyu7bEQ4k0WOgYhHrdW8m/pJgOpl5g==} engines: {node: '>=18.12.0'} @@ -5138,18 +5214,6 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - unplugin-auto-import@0.16.7: - resolution: {integrity: sha512-w7XmnRlchq6YUFJVFGSvG1T/6j8GrdYN6Em9Wf0Ye+HXgD/22kont+WnuCAA0UaUoxtuvRR1u/mXKy63g/hfqQ==} - engines: {node: '>=14'} - peerDependencies: - '@nuxt/kit': ^3.2.2 - '@vueuse/core': '*' - peerDependenciesMeta: - '@nuxt/kit': - optional: true - '@vueuse/core': - optional: true - unplugin-auto-import@19.1.0: resolution: {integrity: sha512-B+TGBEBHqY9aR+7YfShfLujETOHstzpV+yaqgy5PkfV0QG7Py+TYMX7vJ9W4SrysHR+UzR+gzcx/nuZjmPeclA==} engines: {node: '>=14'} @@ -5166,10 +5230,6 @@ packages: resolution: {integrity: sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==} engines: {node: '>=18.12.0'} - unplugin@1.16.1: - resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} - engines: {node: '>=14.0.0'} - unplugin@2.3.11: resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} engines: {node: '>=18.12.0'} @@ -5214,6 +5274,11 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + vite-node@0.34.6: + resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} + engines: {node: '>=v14.18.0'} + hasBin: true + vite@4.5.14: resolution: {integrity: sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==} engines: {node: ^14.18.0 || >=16.0.0} @@ -5242,6 +5307,37 @@ packages: terser: optional: true + vitest@0.34.6: + resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==} + engines: {node: '>=v14.18.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + playwright: '*' + safaridriver: '*' + webdriverio: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + vue-eslint-parser@10.2.0: resolution: {integrity: sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -5288,6 +5384,7 @@ packages: whatwg-encoding@1.0.5: resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation whatwg-mimetype@2.3.0: resolution: {integrity: sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==} @@ -5305,6 +5402,11 @@ packages: engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -5439,7 +5541,7 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@antfu/eslint-config@4.19.0(@vue/compiler-sfc@3.4.21)(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@antfu/eslint-config@4.19.0(@vue/compiler-sfc@3.4.21)(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)(vitest@0.34.6(jsdom@16.7.0)(terser@5.44.1))': dependencies: '@antfu/install-pkg': 1.1.0 '@clack/prompts': 0.11.0 @@ -5448,7 +5550,7 @@ snapshots: '@stylistic/eslint-plugin': 5.6.1(eslint@9.39.2(jiti@2.6.1)) '@typescript-eslint/eslint-plugin': 8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/parser': 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@vitest/eslint-plugin': 1.5.4(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@vitest/eslint-plugin': 1.5.4(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)(vitest@0.34.6(jsdom@16.7.0)(terser@5.44.1)) ansis: 4.2.0 cac: 6.7.14 eslint: 9.39.2(jiti@2.6.1) @@ -6451,64 +6553,6 @@ snapshots: - utf-8-validate - vue - '@dcloudio/uni-cli-shared@3.0.0-4020820240925001(postcss@8.5.6)(rollup@3.29.5)(vue@3.4.21(typescript@5.9.3))': - dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.27.1 - '@babel/core': 7.28.5 - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 - '@dcloudio/uni-i18n': 3.0.0-4020820240925001 - '@dcloudio/uni-shared': 3.0.0-4020820240925001 - '@intlify/core-base': 9.1.9 - '@intlify/shared': 9.1.9 - '@intlify/vue-devtools': 9.1.9 - '@rollup/pluginutils': 5.3.0(rollup@3.29.5) - '@vue/compiler-core': 3.4.21 - '@vue/compiler-dom': 3.4.21 - '@vue/compiler-sfc': 3.4.21 - '@vue/compiler-ssr': 3.4.21 - '@vue/server-renderer': 3.4.21(vue@3.4.21(typescript@5.9.3)) - '@vue/shared': 3.4.21 - adm-zip: 0.5.16 - autoprefixer: 10.4.23(postcss@8.5.6) - base64url: 3.0.1 - chokidar: 3.6.0 - compare-versions: 3.6.0 - debug: 4.4.3 - es-module-lexer: 1.7.0 - esbuild: 0.20.2 - estree-walker: 2.0.2 - fast-glob: 3.3.3 - fs-extra: 10.1.0 - hash-sum: 2.0.0 - isbinaryfile: 5.0.7 - jsonc-parser: 3.3.1 - lines-and-columns: 2.0.4 - magic-string: 0.30.21 - merge: 2.1.1 - mime: 3.0.0 - module-alias: 2.2.3 - os-locale-s-fix: 1.0.8-fix-1 - picocolors: 1.1.1 - postcss-import: 14.1.0(postcss@8.5.6) - postcss-load-config: 3.1.4(postcss@8.5.6) - postcss-modules: 4.3.1(postcss@8.5.6) - postcss-selector-parser: 6.1.2 - resolve: 1.22.11 - source-map-js: 1.2.1 - tapable: 2.3.0 - unplugin-auto-import: 0.16.7(rollup@3.29.5) - xregexp: 3.1.0 - transitivePeerDependencies: - - '@nuxt/kit' - - '@vueuse/core' - - postcss - - rollup - - supports-color - - ts-node - - vue - '@dcloudio/uni-cli-shared@3.0.0-4060620250520001(postcss@8.5.6)(rollup@3.29.5)(vue@3.4.21(typescript@5.9.3))': dependencies: '@ampproject/remapping': 2.3.0 @@ -6663,8 +6707,6 @@ snapshots: - ts-node - vue - '@dcloudio/uni-i18n@3.0.0-4020820240925001': {} - '@dcloudio/uni-i18n@3.0.0-4060620250520001': {} '@dcloudio/uni-mp-compiler@3.0.0-4060620250520001(postcss@8.5.6)(rollup@3.29.5)(vue@3.4.21(typescript@5.9.3))': @@ -6748,10 +6790,6 @@ snapshots: - ts-node - vue - '@dcloudio/uni-shared@3.0.0-4020820240925001': - dependencies: - '@vue/shared': 3.4.21 - '@dcloudio/uni-shared@3.0.0-4060620250520001': dependencies: '@vue/shared': 3.4.21 @@ -7213,6 +7251,10 @@ snapshots: transitivePeerDependencies: - supports-color + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.10 + '@jest/source-map@27.5.1': dependencies: callsites: 3.1.0 @@ -7644,6 +7686,8 @@ snapshots: optionalDependencies: rollup: 3.29.5 + '@sinclair/typebox@0.27.10': {} + '@sinonjs/commons@1.8.6': dependencies: type-detect: 4.0.8 @@ -7690,6 +7734,12 @@ snapshots: dependencies: '@babel/types': 7.28.5 + '@types/chai-subset@1.3.6(@types/chai@4.3.20)': + dependencies: + '@types/chai': 4.3.20 + + '@types/chai@4.3.20': {} + '@types/conventional-commits-parser@5.0.2': dependencies: '@types/node': 22.19.3 @@ -7878,16 +7928,45 @@ snapshots: vite: 4.5.14(@types/node@22.19.3)(terser@5.44.1) vue: 3.4.21(typescript@5.9.3) - '@vitest/eslint-plugin@1.5.4(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@vitest/eslint-plugin@1.5.4(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)(vitest@0.34.6(jsdom@16.7.0)(terser@5.44.1))': dependencies: '@typescript-eslint/scope-manager': 8.50.0 '@typescript-eslint/utils': 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) optionalDependencies: typescript: 5.9.3 + vitest: 0.34.6(jsdom@16.7.0)(terser@5.44.1) transitivePeerDependencies: - supports-color + '@vitest/expect@0.34.6': + dependencies: + '@vitest/spy': 0.34.6 + '@vitest/utils': 0.34.6 + chai: 4.5.0 + + '@vitest/runner@0.34.6': + dependencies: + '@vitest/utils': 0.34.6 + p-limit: 4.0.0 + pathe: 1.1.2 + + '@vitest/snapshot@0.34.6': + dependencies: + magic-string: 0.30.21 + pathe: 1.1.2 + pretty-format: 29.7.0 + + '@vitest/spy@0.34.6': + dependencies: + tinyspy: 2.2.1 + + '@vitest/utils@0.34.6': + dependencies: + diff-sequences: 29.6.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + '@vue/babel-helper-vue-transform-on@1.5.0': {} '@vue/babel-plugin-jsx@1.5.0(@babel/core@7.28.5)': @@ -8029,6 +8108,10 @@ snapshots: acorn-walk@7.2.0: {} + acorn-walk@8.3.5: + dependencies: + acorn: 8.15.0 + acorn@7.4.1: {} acorn@8.15.0: {} @@ -8104,6 +8187,8 @@ snapshots: asap@2.0.6: {} + assertion-error@1.1.0: {} + ast-kit@2.2.0: dependencies: '@babel/parser': 7.28.5 @@ -8349,6 +8434,16 @@ snapshots: transitivePeerDependencies: - debug + chai@4.5.0: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.4 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.1.0 + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -8370,6 +8465,10 @@ snapshots: chardet@0.7.0: {} + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -8613,6 +8712,10 @@ snapshots: dedent@0.7.0: {} + deep-eql@4.1.4: + dependencies: + type-detect: 4.1.0 + deep-is@0.1.4: {} deepmerge@4.3.1: {} @@ -8649,6 +8752,8 @@ snapshots: diff-sequences@27.5.1: {} + diff-sequences@29.6.3: {} + dom-walk@0.1.2: {} domexception@2.0.1: @@ -9306,6 +9411,8 @@ snapshots: get-east-asian-width@1.4.0: {} + get-func-name@2.0.2: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -10145,11 +10252,6 @@ snapshots: local-pkg@0.4.3: {} - local-pkg@0.5.1: - dependencies: - mlly: 1.8.0 - pkg-types: 1.3.1 - local-pkg@1.1.2: dependencies: mlly: 1.8.0 @@ -10211,6 +10313,10 @@ snapshots: longest@2.0.1: {} + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -10817,8 +10923,12 @@ snapshots: path-to-regexp@0.1.12: {} + pathe@1.1.2: {} + pathe@2.0.3: {} + pathval@1.1.1: {} + perfect-debounce@1.0.0: {} phin@2.9.3: {} @@ -10942,6 +11052,12 @@ snapshots: ansi-styles: 5.2.0 react-is: 17.0.2 + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + process@0.11.10: {} prompts@2.4.2: @@ -10992,6 +11108,8 @@ snapshots: react-is@17.0.2: {} + react-is@18.3.1: {} + read-cache@1.0.0: dependencies: pify: 2.3.0 @@ -11231,6 +11349,8 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} + signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -11279,8 +11399,12 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 + stackback@0.0.2: {} + statuses@2.0.2: {} + std-env@3.10.0: {} + string-argv@0.3.2: {} string-hash@1.1.3: {} @@ -11324,9 +11448,9 @@ snapshots: strip-json-comments@3.1.1: {} - strip-literal@2.1.1: + strip-literal@1.3.0: dependencies: - js-tokens: 9.0.1 + acorn: 8.15.0 strip-literal@3.1.0: dependencies: @@ -11398,6 +11522,8 @@ snapshots: tiny-conventional-commits-parser@0.0.1: {} + tinybench@2.9.0: {} + tinycolor2@1.6.0: {} tinyexec@0.3.2: {} @@ -11409,6 +11535,10 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinypool@0.7.0: {} + + tinyspy@2.2.1: {} + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -11482,6 +11612,8 @@ snapshots: type-detect@4.0.8: {} + type-detect@4.1.0: {} + type-fest@0.21.3: {} type-is@1.6.18: @@ -11517,25 +11649,6 @@ snapshots: unicorn-magic@0.1.0: {} - unimport@3.14.6(rollup@3.29.5): - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@3.29.5) - acorn: 8.15.0 - escape-string-regexp: 5.0.0 - estree-walker: 3.0.3 - fast-glob: 3.3.3 - local-pkg: 1.1.2 - magic-string: 0.30.21 - mlly: 1.8.0 - pathe: 2.0.3 - picomatch: 4.0.3 - pkg-types: 1.3.1 - scule: 1.3.0 - strip-literal: 2.1.1 - unplugin: 1.16.1 - transitivePeerDependencies: - - rollup - unimport@4.1.1: dependencies: acorn: 8.15.0 @@ -11578,19 +11691,6 @@ snapshots: unpipe@1.0.0: {} - unplugin-auto-import@0.16.7(rollup@3.29.5): - dependencies: - '@antfu/utils': 0.7.10 - '@rollup/pluginutils': 5.3.0(rollup@3.29.5) - fast-glob: 3.3.3 - local-pkg: 0.5.1 - magic-string: 0.30.21 - minimatch: 9.0.5 - unimport: 3.14.6(rollup@3.29.5) - unplugin: 1.16.1 - transitivePeerDependencies: - - rollup - unplugin-auto-import@19.1.0: dependencies: local-pkg: 1.1.2 @@ -11605,11 +11705,6 @@ snapshots: pathe: 2.0.3 picomatch: 4.0.3 - unplugin@1.16.1: - dependencies: - acorn: 8.15.0 - webpack-virtual-modules: 0.6.2 - unplugin@2.3.11: dependencies: '@jridgewell/remapping': 2.3.5 @@ -11654,6 +11749,24 @@ snapshots: vary@1.1.2: {} + vite-node@0.34.6(@types/node@22.19.3)(terser@5.44.1): + dependencies: + cac: 6.7.14 + debug: 4.4.3 + mlly: 1.8.0 + pathe: 1.1.2 + picocolors: 1.1.1 + vite: 4.5.14(@types/node@22.19.3)(terser@5.44.1) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + vite@4.5.14(@types/node@22.19.3)(terser@5.44.1): dependencies: esbuild: 0.18.20 @@ -11664,6 +11777,43 @@ snapshots: fsevents: 2.3.3 terser: 5.44.1 + vitest@0.34.6(jsdom@16.7.0)(terser@5.44.1): + dependencies: + '@types/chai': 4.3.20 + '@types/chai-subset': 1.3.6(@types/chai@4.3.20) + '@types/node': 22.19.3 + '@vitest/expect': 0.34.6 + '@vitest/runner': 0.34.6 + '@vitest/snapshot': 0.34.6 + '@vitest/spy': 0.34.6 + '@vitest/utils': 0.34.6 + acorn: 8.15.0 + acorn-walk: 8.3.5 + cac: 6.7.14 + chai: 4.5.0 + debug: 4.4.3 + local-pkg: 0.4.3 + magic-string: 0.30.21 + pathe: 1.1.2 + picocolors: 1.1.1 + std-env: 3.10.0 + strip-literal: 1.3.0 + tinybench: 2.9.0 + tinypool: 0.7.0 + vite: 4.5.14(@types/node@22.19.3)(terser@5.44.1) + vite-node: 0.34.6(@types/node@22.19.3)(terser@5.44.1) + why-is-node-running: 2.3.0 + optionalDependencies: + jsdom: 16.7.0 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + vue-eslint-parser@10.2.0(eslint@9.39.2(jiti@2.6.1)): dependencies: debug: 4.4.3 @@ -11733,6 +11883,11 @@ snapshots: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + word-wrap@1.2.5: {} wrap-ansi@7.0.0: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 565effd..a0b3360 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -11,7 +11,6 @@ catalogs: '@dcloudio/types': 3.4.14 '@dcloudio/uni-app': 3.0.0-4060620250520001 '@dcloudio/uni-automator': 3.0.0-4060620250520001 - '@dcloudio/uni-cli-shared': 3.0.0-4060620250520001 '@dcloudio/uni-components': 3.0.0-4060620250520001 '@dcloudio/uni-h5': 3.0.0-4060620250520001 '@dcloudio/uni-mp-weixin': 3.0.0-4060620250520001 diff --git a/src/plugin/subpackages-optimization.ts b/src/plugin/subpackages-optimization.ts index 5918e03..1eccf49 100644 --- a/src/plugin/subpackages-optimization.ts +++ b/src/plugin/subpackages-optimization.ts @@ -5,10 +5,10 @@ import type { Plugin } from 'vite' import type { ISubPkgsInfo, ManualChunkMeta, ManualChunksOption, ModuleInfo, OptimizationOptions } from '../type' import fs from 'node:fs' import path from 'node:path' -import { parseManifestJsonOnce, parseMiniProgramPagesJson } from '@dcloudio/uni-cli-shared' import { logger } from '../common/Logger' import { EXT_RE, EXTNAME_JS_RE, ROOT_DIR, UNI_INPUT_DIR } from '../constants' import { moduleIdProcessor as _moduleIdProcessor, normalizePath, parseQuerystring, parseVirtualPath } from '../utils' +import { parseManifestJsonOnce, parseMiniProgramPagesJson } from '../utils/uniapp' /** * ### uniapp 分包优化插件 diff --git a/src/utils/uniapp/config.test.ts b/src/utils/uniapp/config.test.ts new file mode 100644 index 0000000..05e9c5a --- /dev/null +++ b/src/utils/uniapp/config.test.ts @@ -0,0 +1,272 @@ +import fs from 'node:fs' +import os from 'node:os' +import path from 'node:path' +import process from 'node:process' +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import { + parseManifestJson, + parseManifestJsonOnce, + parseMiniProgramPagesJson, +} from './config' + +let inputDir = '' +let originalCompileTarget: string | undefined +let originalPlatform: string | undefined + +beforeEach(() => { + inputDir = fs.mkdtempSync(path.join(os.tmpdir(), 'bundle-optimizer-')) + originalCompileTarget = process.env.UNI_COMPILE_TARGET + originalPlatform = process.env.UNI_PLATFORM +}) + +afterEach(() => { + fs.rmSync(inputDir, { recursive: true, force: true }) + restoreEnv('UNI_COMPILE_TARGET', originalCompileTarget) + restoreEnv('UNI_PLATFORM', originalPlatform) +}) + +describe('parseManifestJson', () => { + it('parses JSONC without applying uni conditional blocks', () => { + writeFile('manifest.json', `{ + // comment + "name": "demo", + "mp-weixin": { + /* #ifdef MP-WEIXIN */ + "optimization": { + "subPackages": true, + }, + /* #endif */ + } + }`) + + expect(parseManifestJson(inputDir)).toEqual({ + 'name': 'demo', + 'mp-weixin': { + optimization: { + subPackages: true, + }, + }, + }) + }) + + it('keeps JSON duplicate key behavior when conditional comments wrap manifest keys', () => { + writeFile('manifest.json', `{ + // #ifdef MP-WEIXIN + "mp-weixin": { + "optimization": { + "subPackages": false + } + }, + // #endif + + // #ifndef MP-WEIXIN + "mp-weixin": { + "optimization": { + "subPackages": true + } + } + // #endif + }`) + + expect(parseManifestJson(inputDir)).toEqual({ + 'mp-weixin': { + optimization: { + subPackages: true, + }, + }, + }) + }) + + it('caches manifest parsing per input directory', () => { + writeFile('manifest.json', `{ + "name": "first" + }`) + + expect(parseManifestJsonOnce(inputDir).name).toBe('first') + + writeFile('manifest.json', `{ + "name": "second" + }`) + + expect(parseManifestJson(inputDir).name).toBe('second') + expect(parseManifestJsonOnce(inputDir).name).toBe('first') + }) + + it('returns empty config for missing manifest when compiling special targets', () => { + process.env.UNI_COMPILE_TARGET = 'ext-api' + + expect(parseManifestJson(inputDir)).toEqual({}) + }) +}) + +describe('parseMiniProgramPagesJson', () => { + it('keeps subpackage structure when subpackages option is enabled', () => { + const { appJson, nvuePages, pageJsons } = parseMiniProgramPagesJson(`{ + "pages": [ + // #ifdef MP-WEIXIN + { + "path": "pages/weixin", + }, + // #else + { + "path": "pages/other" + }, + // #endif + { + "path": "pages/common" + } + ], + "subpackages": [ + { + "root": "sub/", + "independent": true, + "pages": [ + { + "path": "index", + } + ], + } + ], + }`, 'mp-weixin', { subpackages: true }) + + expect(appJson).toEqual({ + pages: ['pages/weixin', 'pages/common'], + subPackages: [ + { + root: 'sub/', + pages: ['index'], + independent: true, + }, + ], + }) + expect(pageJsons).toEqual({}) + expect(nvuePages).toEqual([]) + }) + + it('flattens subpackages into pages by default', () => { + const { appJson } = parseMiniProgramPagesJson(`{ + "pages": [ + { + "path": "pages/index" + } + ], + "subPackages": [ + { + "root": "pkg/", + "pages": [ + { + "path": "index" + }, + { + "path": "nested/detail" + } + ] + } + ] + }`, 'mp-weixin') + + expect(appJson).toEqual({ + pages: ['pages/index', 'pkg/index', 'pkg/nested/detail'], + }) + }) + + it('supports compound conditions', () => { + const { appJson } = parseMiniProgramPagesJson(`{ + "pages": [ + // #if MP-WEIXIN && !APP + { + "path": "pages/mp" + }, + // #else + { + "path": "pages/fallback" + }, + // #endif + ] + }`, 'mp-weixin') + + expect(appJson.pages).toEqual(['pages/mp']) + }) + + it('supports multiple platforms separated by or operators', () => { + const { appJson } = parseMiniProgramPagesJson(`{ + "pages": [ + // #ifdef MP-WEIXIN || H5 + { + "path": "pages/shared" + }, + // #else + { + "path": "pages/fallback" + }, + // #endif + ] + }`, 'h5') + + expect(appJson.pages).toEqual(['pages/shared']) + }) + + it('normalizes condition keys with underscores like the official preprocessor', () => { + const { appJson } = parseMiniProgramPagesJson(`{ + "pages": [ + // #ifdef MP_WEIXIN + { + "path": "pages/weixin" + }, + // #else + { + "path": "pages/other" + }, + // #endif + ] + }`, 'mp-weixin') + + expect(appJson.pages).toEqual(['pages/weixin']) + }) + + it('treats elif as regular inactive content like the official preprocessor', () => { + const { appJson } = parseMiniProgramPagesJson(`{ + "pages": [ + // #if H5 + { + "path": "pages/h5" + }, + // #elif MP-WEIXIN + { + "path": "pages/weixin" + }, + // #else + { + "path": "pages/fallback" + }, + // #endif + ] + }`, 'mp-weixin') + + expect(appJson.pages).toEqual(['pages/fallback']) + }) + + it('throws when pages are duplicated', () => { + expect(() => parseMiniProgramPagesJson(`{ + "pages": [ + { + "path": "pages/index" + }, + { + "path": "pages/index" + } + ] + }`, 'mp-weixin')).toThrow('pages.json->pages/index duplication') + }) +}) + +function writeFile(filename: string, content: string) { + fs.writeFileSync(path.join(inputDir, filename), content) +} + +function restoreEnv(name: 'UNI_COMPILE_TARGET' | 'UNI_PLATFORM', value: string | undefined) { + if (value === undefined) + delete process.env[name] + else + process.env[name] = value +} diff --git a/src/utils/uniapp/config.ts b/src/utils/uniapp/config.ts new file mode 100644 index 0000000..f10cc66 --- /dev/null +++ b/src/utils/uniapp/config.ts @@ -0,0 +1,392 @@ +import fs from 'node:fs' +import path from 'node:path' +import process from 'node:process' + +type JsonObject = Record + +interface UniPage { + path: string + style?: JsonObject + [key: string]: any +} + +interface UniSubPackage { + root: string + pages?: UniPage[] + independent?: boolean + [key: string]: any +} + +interface UniPagesJson { + pages?: UniPage[] + subPackages?: UniSubPackage[] + subpackages?: UniSubPackage[] + [key: string]: any +} + +interface ParseMiniProgramPagesJsonOptions { + subpackages?: boolean +} + +interface MiniProgramAppJson { + pages: string[] + subPackages?: Array & { pages: string[] }> +} + +const manifestJsonCache = new Map() + +export function parseManifestJson(inputDir: string): JsonObject { + const filename = path.join(inputDir, 'manifest.json') + + if (!fs.existsSync(filename)) { + // 特殊编译目标可能没有完整项目配置,缺失 manifest 时按空配置处理 + if (process.env.UNI_COMPILE_TARGET) + return {} + + throw new Error(`[bundle-optimizer] manifest.json not found: ${filename}`) + } + + // manifest.json 仅按 JSONC 解析,条件注释在这里不参与平台裁剪 + return parseJsonLike(fs.readFileSync(filename, 'utf8'), filename) +} + +export function parseManifestJsonOnce(inputDir: string): JsonObject { + const cached = manifestJsonCache.get(inputDir) + if (cached) + return cached + + const manifestJson = parseManifestJson(inputDir) + manifestJsonCache.set(inputDir, manifestJson) + return manifestJson +} + +export function parseMiniProgramPagesJson( + jsonStr: string, + platform: string, + options: ParseMiniProgramPagesJsonOptions = {}, +): { appJson: MiniProgramAppJson, pageJsons: Record, nvuePages: string[] } { + // pages.json 支持条件编译,解析前需要先按平台裁剪 + const pagesJson = parseJsonLike(jsonStr, 'pages.json', { + platform, + preprocess: true, + }) + validatePagesJson(pagesJson) + + const appJson: MiniProgramAppJson = { + pages: pagesJson.pages!.map(page => page.path), + } + + const subPackages = pagesJson.subPackages || pagesJson.subpackages + if (Array.isArray(subPackages)) { + if (options.subpackages) { + appJson.subPackages = subPackages.map(({ root, pages = [], ...rest }) => { + return { + root, + pages: pages.map(page => page.path), + ...rest, + } + }) + } + else { + subPackages.forEach(({ root, pages = [] }) => { + pages.forEach((page) => { + appJson.pages.push(normalizePath(path.join(root, page.path))) + }) + }) + } + } + + return { + appJson, + pageJsons: {}, + nvuePages: [], + } +} + +function validatePagesJson(pagesJson: UniPagesJson) { + if (!Array.isArray(pagesJson.pages)) + throw new Error('[bundle-optimizer] pages.json->pages parse failed.') + + if (!pagesJson.pages.length) + throw new Error('[bundle-optimizer] pages.json->pages must contain at least 1 page.') + + const pages = new Set() + for (const page of pagesJson.pages) { + if (!page?.path) + throw new Error('[bundle-optimizer] pages.json->pages item must contain path.') + + if (pages.has(page.path)) + throw new Error(`[bundle-optimizer] pages.json->${page.path} duplication.`) + + pages.add(page.path) + } +} + +function parseJsonLike( + jsonStr: string, + filename: string, + { platform = process.env.UNI_PLATFORM, preprocess = false }: { platform?: string, preprocess?: boolean } = {}, +): T { + const content = stripTrailingCommas(stripJsonComments(preprocess ? preprocessConditionalJson(jsonStr, platform) : jsonStr)) + + try { + return JSON.parse(content) as T + } + catch (error) { + throw new Error(`[bundle-optimizer] ${filename} parse failed: ${(error as Error).message}`) + } +} + +function preprocessConditionalJson(jsonStr: string, platform = process.env.UNI_PLATFORM) { + const context = createConditionalContext(platform) + const stack: Array<{ parentActive: boolean, matched: boolean, active: boolean }> = [] + const lines = jsonStr.split(/\r?\n/) + + return lines.map((line) => { + const directive = parseDirective(line) + if (!directive) + return isActive(stack) ? line : '' + + const parentActive = stack.length ? stack[stack.length - 1].active : true + const { name, expression } = directive + + if (name === 'ifdef' || name === 'if') { + const matched = evaluateCondition(expression, context) + stack.push({ parentActive, matched, active: parentActive && matched }) + } + else if (name === 'ifndef') { + const matched = !evaluateCondition(expression, context) + stack.push({ parentActive, matched, active: parentActive && matched }) + } + else if (name === 'else') { + const current = stack[stack.length - 1] + if (current) { + current.active = current.parentActive && !current.matched + current.matched = true + } + } + else if (name === 'endif') { + stack.pop() + } + + return '' + }).join('\n') +} + +function parseDirective(line: string) { + const trimmed = line.trim() + const content = trimmed.startsWith('//') + ? trimmed.slice(2).trim() + : trimmed.startsWith('/*') && trimmed.endsWith('*/') + ? trimmed.slice(2, -2).trim() + : '' + + if (!content.startsWith('#')) + return + + const directiveContent = content.slice(1).trim() + const spaceIndex = directiveContent.search(/\s/) + const name = spaceIndex === -1 ? directiveContent : directiveContent.slice(0, spaceIndex) + const expression = spaceIndex === -1 ? '' : directiveContent.slice(spaceIndex).trim() + + // uni 条件编译不识别 #elif,这里保留为普通内容处理 + if (!['ifdef', 'ifndef', 'if', 'else', 'endif'].includes(name)) + return + + return { + name, + expression, + } +} + +function isActive(stack: Array<{ active: boolean }>) { + return stack.every(item => item.active) +} + +function createConditionalContext(platform = '') { + const normalizedPlatform = normalizeConditionKey(platform) + const context = new Set(['VUE3']) + + if (normalizedPlatform) + context.add(normalizedPlatform) + + if (normalizedPlatform.startsWith('MP_')) + context.add('MP') + + if (normalizedPlatform === 'APP' || normalizedPlatform === 'APP_PLUS') { + context.add('APP') + context.add('APP_PLUS') + } + + if (normalizedPlatform === 'APP_HARMONY') { + context.add('APP') + context.add('APP_HARMONY') + } + + if (normalizedPlatform === 'H5' || normalizedPlatform === 'WEB') { + context.add('H5') + context.add('WEB') + } + + if (normalizedPlatform.startsWith('QUICKAPP')) + context.add('QUICKAPP') + + return context +} + +function evaluateCondition(expression: string, context: Set) { + const tokens = expression.match(/[()!]|\|\||&&|[\w-]+/g) || [] + let index = 0 + + function peek() { + return tokens[index] + } + + function consume() { + return tokens[index++] + } + + function parseOr(): boolean { + let value = parseAnd() + while (peek() === '||') { + consume() + value = parseAnd() || value + } + return value + } + + function parseAnd(): boolean { + let value = parseUnary() + while (peek() === '&&') { + consume() + value = parseUnary() && value + } + return value + } + + function parseUnary(): boolean { + if (peek() === '!') { + consume() + return !parseUnary() + } + + if (peek() === '(') { + consume() + const value = parseOr() + if (peek() === ')') + consume() + return value + } + + const token = consume() + return token ? context.has(normalizeConditionKey(token)) : false + } + + return parseOr() +} + +function normalizeConditionKey(name: string) { + // 条件表达式里的平台名使用下划线形式进行匹配 + return name.replace(/-/g, '_').toUpperCase() +} + +function stripJsonComments(source: string) { + let result = '' + let inString = false + let escaped = false + + for (let i = 0; i < source.length; i++) { + const char = source[i] + const next = source[i + 1] + + if (inString) { + result += char + if (escaped) { + escaped = false + continue + } + if (char === '\\') { + escaped = true + continue + } + if (char === '"') + inString = false + continue + } + + if (char === '"') { + inString = true + result += char + continue + } + + if (char === '/' && next === '/') { + while (i < source.length && source[i] !== '\n') + i++ + result += '\n' + continue + } + + if (char === '/' && next === '*') { + i += 2 + while (i < source.length && !(source[i] === '*' && source[i + 1] === '/')) { + result += source[i] === '\n' ? '\n' : ' ' + i++ + } + i++ + continue + } + + result += char + } + + return result +} + +function stripTrailingCommas(source: string) { + let result = '' + let inString = false + let escaped = false + + for (let i = 0; i < source.length; i++) { + const char = source[i] + + if (inString) { + result += char + if (escaped) { + escaped = false + continue + } + if (char === '\\') { + escaped = true + continue + } + if (char === '"') + inString = false + continue + } + + if (char === '"') { + inString = true + result += char + continue + } + + if (char === ',') { + let nextIndex = i + 1 + while (/\s/.test(source[nextIndex] || '')) + nextIndex++ + + if (source[nextIndex] === '}' || source[nextIndex] === ']') + continue + } + + result += char + } + + return result +} + +function normalizePath(filePath: string) { + return filePath.replace(/\\/g, '/') +} diff --git a/src/utils/uniapp/index.ts b/src/utils/uniapp/index.ts index a4bc5a1..ca456bc 100644 --- a/src/utils/uniapp/index.ts +++ b/src/utils/uniapp/index.ts @@ -1,4 +1,5 @@ export * from './common' +export * from './config' export * from './is' export * from './type' export * from './virtual' diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..ceafc24 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + environment: 'node', + include: ['src/**/*.test.ts'], + }, +}) From 7a1a7a5dba8d3f00bb8a693b216ca2f33a9365f5 Mon Sep 17 00:00:00 2001 From: Vanisper <273266469@qq.com> Date: Fri, 8 May 2026 17:51:58 +0800 Subject: [PATCH 2/2] =?UTF-8?q?chore(uniapp):=20=E8=A1=A5=E5=85=85?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/uniapp/config.ts | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/utils/uniapp/config.ts b/src/utils/uniapp/config.ts index f10cc66..0539b78 100644 --- a/src/utils/uniapp/config.ts +++ b/src/utils/uniapp/config.ts @@ -35,12 +35,20 @@ interface MiniProgramAppJson { const manifestJsonCache = new Map() +/** + * 是否为普通编译目标 + * - 目前有特殊编译目标 uni_modules 和 ext-api + */ +function isNormalCompileTarget() { + return !process.env.UNI_COMPILE_TARGET +} + export function parseManifestJson(inputDir: string): JsonObject { const filename = path.join(inputDir, 'manifest.json') if (!fs.existsSync(filename)) { // 特殊编译目标可能没有完整项目配置,缺失 manifest 时按空配置处理 - if (process.env.UNI_COMPILE_TARGET) + if (!isNormalCompileTarget()) return {} throw new Error(`[bundle-optimizer] manifest.json not found: ${filename}`) @@ -127,6 +135,7 @@ function parseJsonLike( filename: string, { platform = process.env.UNI_PLATFORM, preprocess = false }: { platform?: string, preprocess?: boolean } = {}, ): T { + // 先去除注释,再去除尾随逗号,最后进行 JSON.parse const content = stripTrailingCommas(stripJsonComments(preprocess ? preprocessConditionalJson(jsonStr, platform) : jsonStr)) try { @@ -137,6 +146,14 @@ function parseJsonLike( } } +/** + * json 文本平台条件编译预处理 + * - 支持条件编译指令 #if、#ifdef、#ifndef、#else、#endif + * @param jsonStr + * @param platform 平台标识,默认为环境变量 UNI_PLATFORM + * @returns 预处理后的 json 文本 + * @see https://uniapp.dcloud.net.cn/tutorial/platform.html + */ function preprocessConditionalJson(jsonStr: string, platform = process.env.UNI_PLATFORM) { const context = createConditionalContext(platform) const stack: Array<{ parentActive: boolean, matched: boolean, active: boolean }> = [] @@ -203,6 +220,10 @@ function isActive(stack: Array<{ active: boolean }>) { return stack.every(item => item.active) } +/** + * 根据平台标识创建条件编译上下文 + * @param platform + */ function createConditionalContext(platform = '') { const normalizedPlatform = normalizeConditionKey(platform) const context = new Set(['VUE3']) @@ -234,6 +255,12 @@ function createConditionalContext(platform = '') { return context } +/** + * 评估条件表达式 + * - 支持逻辑与 &&、逻辑或 ||、逻辑非 !、括号 (),以及平台标识符 + * @param expression 条件表达式字符串 + * @param context 条件编译上下文,包含当前平台和相关标识符 + */ function evaluateCondition(expression: string, context: Set) { const tokens = expression.match(/[()!]|\|\||&&|[\w-]+/g) || [] let index = 0 @@ -290,6 +317,9 @@ function normalizeConditionKey(name: string) { return name.replace(/-/g, '_').toUpperCase() } +/** + * 去除 JSON 字符串中的注释 + */ function stripJsonComments(source: string) { let result = '' let inString = false @@ -343,6 +373,10 @@ function stripJsonComments(source: string) { return result } +/** + * 去除 JSON 字符串中的尾随逗号 + * @description jsonc 允许对象和数组中存在尾随逗号,但 JSON.parse 不支持,因此需要预处理去除 + */ function stripTrailingCommas(source: string) { let result = '' let inString = false