diff --git a/package.json b/package.json
index 30089a2..34bcc4f 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,9 @@
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
- "files": ["dist"],
+ "files": [
+ "dist"
+ ],
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
@@ -40,12 +42,14 @@
"@biomejs/biome": "^1.8.3",
"@playwright/test": "^1.46.1",
"@rsbuild/core": "^1.0.1-rc.0",
+ "@rsbuild/plugin-vue": "1.0.1-rc.5",
"@types/node": "^20.16.2",
"nano-staged": "^0.8.0",
"playwright": "^1.46.1",
"simple-git-hooks": "^2.11.1",
"tsup": "^8.2.4",
- "typescript": "^5.5.4"
+ "typescript": "^5.5.4",
+ "vue": "^3.5.0"
},
"peerDependencies": {
"@rsbuild/core": "1.x || ^1.0.1-beta.0"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 5ed5fb4..f8b7bf8 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -27,6 +27,9 @@ importers:
'@rsbuild/core':
specifier: ^1.0.1-rc.0
version: 1.0.1-rc.0
+ '@rsbuild/plugin-vue':
+ specifier: 1.0.1-rc.5
+ version: 1.0.1-rc.5(@rsbuild/core@1.0.1-rc.0)(esbuild@0.23.0)(vue@3.5.3(typescript@5.5.4))
'@types/node':
specifier: ^20.16.2
version: 20.16.2
@@ -45,6 +48,9 @@ importers:
typescript:
specifier: ^5.5.4
version: 5.5.4
+ vue:
+ specifier: ^3.5.0
+ version: 3.5.3(typescript@5.5.4)
playground: {}
@@ -426,6 +432,9 @@ packages:
resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
engines: {node: '>=6.0.0'}
+ '@jridgewell/source-map@0.3.6':
+ resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==}
+
'@jridgewell/sourcemap-codec@1.4.15':
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
@@ -567,6 +576,11 @@ packages:
peerDependencies:
'@rsbuild/core': ^1.0.1-rc.4
+ '@rsbuild/plugin-vue@1.0.1-rc.5':
+ resolution: {integrity: sha512-pcdirXqxT1IjghfzVIn7UxnQU4mF6gf/jaCxOIToV6LkFOgcL1VNq1vYZrerj7lw+J5dtEO4x4hVhYvgm3zoMQ==}
+ peerDependencies:
+ '@rsbuild/core': ^1.0.1-rc.4
+
'@rspack/binding-darwin-arm64@1.0.0':
resolution: {integrity: sha512-ZHQk9YK+swlTG48kJTgzFUW9T26KjhLXRok5la7t2AMoiuHyhGHHgC5iQfPJLZ62XzcJ/rfqs2rwakl97151jQ==}
cpu: [arm64]
@@ -650,6 +664,9 @@ packages:
'@types/estree@1.0.5':
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
+ '@types/json-schema@7.0.15':
+ resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+
'@types/node@20.16.2':
resolution: {integrity: sha512-91s/n4qUPV/wg8eE9KHYW1kouTfDk2FPGjXbBMfRWP/2vg1rCXNQL1OCabwGs0XSdukuK+MwCDXE30QpSeMUhQ==}
@@ -681,9 +698,92 @@ packages:
'@vue/compiler-ssr@3.5.3':
resolution: {integrity: sha512-F/5f+r2WzL/2YAPl7UlKcJWHrvoZN8XwEBLnT7S4BXwncH25iDOabhO2M2DWioyTguJAGavDOawejkFXj8EM1w==}
+ '@vue/reactivity@3.5.3':
+ resolution: {integrity: sha512-2w61UnRWTP7+rj1H/j6FH706gRBHdFVpIqEkSDAyIpafBXYH8xt4gttstbbCWdU3OlcSWO8/3mbKl/93/HSMpw==}
+
+ '@vue/runtime-core@3.5.3':
+ resolution: {integrity: sha512-5b2AQw5OZlmCzSsSBWYoZOsy75N4UdMWenTfDdI5bAzXnuVR7iR8Q4AOzQm2OGoA41xjk53VQKrqQhOz2ktWaw==}
+
+ '@vue/runtime-dom@3.5.3':
+ resolution: {integrity: sha512-wPR1DEGc3XnQ7yHbmkTt3GoY0cEnVGQnARRdAkDzZ8MbUKEs26gogCQo6AOvvgahfjIcnvWJzkZArQ1fmWjcSg==}
+
+ '@vue/server-renderer@3.5.3':
+ resolution: {integrity: sha512-28volmaZVG2PGO3V3+gBPKoSHvLlE8FGfG/GKXKkjjfxLuj/50B/0OQGakM/g6ehQeqCrZYM4eHC4Ks48eig1Q==}
+ peerDependencies:
+ vue: 3.5.3
+
'@vue/shared@3.5.3':
resolution: {integrity: sha512-Jp2v8nylKBT+PlOUjun2Wp/f++TfJVFjshLzNtJDdmFJabJa7noGMncqXRM1vXGX+Yo2V7WykQFNxusSim8SCA==}
+ '@webassemblyjs/ast@1.12.1':
+ resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==}
+
+ '@webassemblyjs/floating-point-hex-parser@1.11.6':
+ resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==}
+
+ '@webassemblyjs/helper-api-error@1.11.6':
+ resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==}
+
+ '@webassemblyjs/helper-buffer@1.12.1':
+ resolution: {integrity: sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==}
+
+ '@webassemblyjs/helper-numbers@1.11.6':
+ resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==}
+
+ '@webassemblyjs/helper-wasm-bytecode@1.11.6':
+ resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==}
+
+ '@webassemblyjs/helper-wasm-section@1.12.1':
+ resolution: {integrity: sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==}
+
+ '@webassemblyjs/ieee754@1.11.6':
+ resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==}
+
+ '@webassemblyjs/leb128@1.11.6':
+ resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==}
+
+ '@webassemblyjs/utf8@1.11.6':
+ resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==}
+
+ '@webassemblyjs/wasm-edit@1.12.1':
+ resolution: {integrity: sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==}
+
+ '@webassemblyjs/wasm-gen@1.12.1':
+ resolution: {integrity: sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==}
+
+ '@webassemblyjs/wasm-opt@1.12.1':
+ resolution: {integrity: sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==}
+
+ '@webassemblyjs/wasm-parser@1.12.1':
+ resolution: {integrity: sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==}
+
+ '@webassemblyjs/wast-printer@1.12.1':
+ resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==}
+
+ '@xtuc/ieee754@1.2.0':
+ resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
+
+ '@xtuc/long@4.2.2':
+ resolution: {integrity: sha1-0pHGpOl5ibXGHZrPOWrk/hM6cY0=}
+
+ acorn-import-attributes@1.9.5:
+ resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==}
+ peerDependencies:
+ acorn: ^8
+
+ acorn@8.12.1:
+ resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ ajv-keywords@3.5.2:
+ resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==}
+ peerDependencies:
+ ajv: ^6.9.1
+
+ ajv@6.12.6:
+ resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
@@ -737,6 +837,9 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
+ buffer-from@1.1.2:
+ resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+
bundle-require@5.0.0:
resolution: {integrity: sha512-GuziW3fSSmopcx4KRymQEJVbZUfqlCqcq7dvs6TYwKRZiegK/2buMxQTPs6MGlNv50wms1699qYO54R8XfRX4w==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -758,10 +861,18 @@ packages:
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
engines: {node: '>=4'}
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+
chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
+ chrome-trace-event@1.0.4:
+ resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
+ engines: {node: '>=6.0'}
+
color-convert@1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
@@ -775,6 +886,9 @@ packages:
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+ commander@2.20.3:
+ resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
+
commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
@@ -793,6 +907,9 @@ packages:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
+ csstype@3.1.3:
+ resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+
debug@4.3.6:
resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==}
engines: {node: '>=6.0'}
@@ -822,10 +939,17 @@ packages:
emoji-regex@9.2.2:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+ enhanced-resolve@5.17.1:
+ resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==}
+ engines: {node: '>=10.13.0'}
+
entities@4.5.0:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'}
+ es-module-lexer@1.5.4:
+ resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==}
+
esbuild@0.23.0:
resolution: {integrity: sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==}
engines: {node: '>=18'}
@@ -839,17 +963,43 @@ packages:
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
engines: {node: '>=0.8.0'}
+ eslint-scope@5.1.1:
+ resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
+ engines: {node: '>=8.0.0'}
+
+ esrecurse@4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+
+ estraverse@4.3.0:
+ resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
+ engines: {node: '>=4.0'}
+
+ estraverse@5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+
estree-walker@2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+ events@3.3.0:
+ resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
+ engines: {node: '>=0.8.x'}
+
execa@5.1.1:
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
engines: {node: '>=10'}
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
fast-glob@3.3.2:
resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
engines: {node: '>=8.6.0'}
+ fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
fastq@1.17.1:
resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
@@ -883,6 +1033,9 @@ packages:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
+ glob-to-regexp@0.4.1:
+ resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
+
glob@10.3.12:
resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==}
engines: {node: '>=16 || 14 >=14.17'}
@@ -896,10 +1049,20 @@ packages:
resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
engines: {node: '>=10'}
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
has-flag@3.0.0:
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
engines: {node: '>=4'}
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ hash-sum@2.0.0:
+ resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==}
+
html-tags@3.3.1:
resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==}
engines: {node: '>=8'}
@@ -943,6 +1106,10 @@ packages:
resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
engines: {node: '>=14'}
+ jest-worker@27.5.1:
+ resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
+ engines: {node: '>= 10.13.0'}
+
joycon@3.1.1:
resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
engines: {node: '>=10'}
@@ -955,6 +1122,12 @@ packages:
engines: {node: '>=4'}
hasBin: true
+ json-parse-even-better-errors@2.3.1:
+ resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
+
+ json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+
json5@2.2.3:
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
engines: {node: '>=6'}
@@ -971,6 +1144,10 @@ packages:
resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ loader-runner@4.3.0:
+ resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==}
+ engines: {node: '>=6.11.5'}
+
lodash.sortby@4.7.0:
resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==}
@@ -995,6 +1172,14 @@ packages:
resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
engines: {node: '>=8.6'}
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
mimic-fn@2.1.0:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
@@ -1023,6 +1208,9 @@ packages:
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
+ neo-async@2.6.2:
+ resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
+
node-releases@2.0.18:
resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
@@ -1107,6 +1295,9 @@ packages:
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+ randombytes@2.1.0:
+ resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
+
readdirp@3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
@@ -1130,10 +1321,20 @@ packages:
run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+ safe-buffer@5.2.1:
+ resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+
+ schema-utils@3.3.0:
+ resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==}
+ engines: {node: '>= 10.13.0'}
+
semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
+ serialize-javascript@6.0.2:
+ resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
+
shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
@@ -1161,6 +1362,13 @@ packages:
resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
engines: {node: '>=0.10.0'}
+ source-map-support@0.5.21:
+ resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
+
+ source-map@0.6.1:
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+ engines: {node: '>=0.10.0'}
+
source-map@0.8.0-beta.0:
resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==}
engines: {node: '>= 8'}
@@ -1194,9 +1402,42 @@ packages:
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
engines: {node: '>=4'}
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ supports-color@8.1.1:
+ resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
+ engines: {node: '>=10'}
+
svg-tags@1.0.0:
resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
+ tapable@2.2.1:
+ resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
+ engines: {node: '>=6'}
+
+ terser-webpack-plugin@5.3.10:
+ resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==}
+ engines: {node: '>= 10.13.0'}
+ peerDependencies:
+ '@swc/core': '*'
+ esbuild: '*'
+ uglify-js: '*'
+ webpack: ^5.1.0
+ peerDependenciesMeta:
+ '@swc/core':
+ optional: true
+ esbuild:
+ optional: true
+ uglify-js:
+ optional: true
+
+ terser@5.31.6:
+ resolution: {integrity: sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==}
+ engines: {node: '>=10'}
+ hasBin: true
+
thenify-all@1.6.0:
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
engines: {node: '>=0.8'}
@@ -1262,9 +1503,50 @@ packages:
peerDependencies:
browserslist: '>= 4.21.0'
+ uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+
+ vue-loader@17.4.2:
+ resolution: {integrity: sha512-yTKOA4R/VN4jqjw4y5HrynFL8AK0Z3/Jt7eOJXEitsm0GMRHDBjCfCiuTiLP7OESvsZYo2pATCWhDqxC5ZrM6w==}
+ peerDependencies:
+ '@vue/compiler-sfc': '*'
+ vue: '*'
+ webpack: ^4.1.0 || ^5.0.0-0
+ peerDependenciesMeta:
+ '@vue/compiler-sfc':
+ optional: true
+ vue:
+ optional: true
+
+ vue@3.5.3:
+ resolution: {integrity: sha512-xvRbd0HpuLovYbOHXRHlSBsSvmUJbo0pzbkKTApWnQGf3/cu5Z39mQeA5cZdLRVIoNf3zI6MSoOgHUT5i2jO+Q==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ watchpack@2.4.2:
+ resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==}
+ engines: {node: '>=10.13.0'}
+
webidl-conversions@4.0.2:
resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
+ webpack-sources@3.2.3:
+ resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
+ engines: {node: '>=10.13.0'}
+
+ webpack@5.94.0:
+ resolution: {integrity: sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==}
+ engines: {node: '>=10.13.0'}
+ hasBin: true
+ peerDependencies:
+ webpack-cli: '*'
+ peerDependenciesMeta:
+ webpack-cli:
+ optional: true
+
whatwg-url@7.1.0:
resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
@@ -1642,6 +1924,11 @@ snapshots:
'@jridgewell/set-array@1.2.1': {}
+ '@jridgewell/source-map@0.3.6':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.5
+ '@jridgewell/trace-mapping': 0.3.25
+
'@jridgewell/sourcemap-codec@1.4.15': {}
'@jridgewell/sourcemap-codec@1.5.0': {}
@@ -1758,6 +2045,19 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@rsbuild/plugin-vue@1.0.1-rc.5(@rsbuild/core@1.0.1-rc.0)(esbuild@0.23.0)(vue@3.5.3(typescript@5.5.4))':
+ dependencies:
+ '@rsbuild/core': 1.0.1-rc.0
+ vue-loader: 17.4.2(vue@3.5.3(typescript@5.5.4))(webpack@5.94.0(esbuild@0.23.0))
+ webpack: 5.94.0(esbuild@0.23.0)
+ transitivePeerDependencies:
+ - '@swc/core'
+ - '@vue/compiler-sfc'
+ - esbuild
+ - uglify-js
+ - vue
+ - webpack-cli
+
'@rspack/binding-darwin-arm64@1.0.0':
optional: true
@@ -1835,6 +2135,8 @@ snapshots:
'@types/estree@1.0.5': {}
+ '@types/json-schema@7.0.15': {}
+
'@types/node@20.16.2':
dependencies:
undici-types: 6.19.8
@@ -1898,8 +2200,127 @@ snapshots:
'@vue/compiler-dom': 3.5.3
'@vue/shared': 3.5.3
+ '@vue/reactivity@3.5.3':
+ dependencies:
+ '@vue/shared': 3.5.3
+
+ '@vue/runtime-core@3.5.3':
+ dependencies:
+ '@vue/reactivity': 3.5.3
+ '@vue/shared': 3.5.3
+
+ '@vue/runtime-dom@3.5.3':
+ dependencies:
+ '@vue/reactivity': 3.5.3
+ '@vue/runtime-core': 3.5.3
+ '@vue/shared': 3.5.3
+ csstype: 3.1.3
+
+ '@vue/server-renderer@3.5.3(vue@3.5.3(typescript@5.5.4))':
+ dependencies:
+ '@vue/compiler-ssr': 3.5.3
+ '@vue/shared': 3.5.3
+ vue: 3.5.3(typescript@5.5.4)
+
'@vue/shared@3.5.3': {}
+ '@webassemblyjs/ast@1.12.1':
+ dependencies:
+ '@webassemblyjs/helper-numbers': 1.11.6
+ '@webassemblyjs/helper-wasm-bytecode': 1.11.6
+
+ '@webassemblyjs/floating-point-hex-parser@1.11.6': {}
+
+ '@webassemblyjs/helper-api-error@1.11.6': {}
+
+ '@webassemblyjs/helper-buffer@1.12.1': {}
+
+ '@webassemblyjs/helper-numbers@1.11.6':
+ dependencies:
+ '@webassemblyjs/floating-point-hex-parser': 1.11.6
+ '@webassemblyjs/helper-api-error': 1.11.6
+ '@xtuc/long': 4.2.2
+
+ '@webassemblyjs/helper-wasm-bytecode@1.11.6': {}
+
+ '@webassemblyjs/helper-wasm-section@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/helper-buffer': 1.12.1
+ '@webassemblyjs/helper-wasm-bytecode': 1.11.6
+ '@webassemblyjs/wasm-gen': 1.12.1
+
+ '@webassemblyjs/ieee754@1.11.6':
+ dependencies:
+ '@xtuc/ieee754': 1.2.0
+
+ '@webassemblyjs/leb128@1.11.6':
+ dependencies:
+ '@xtuc/long': 4.2.2
+
+ '@webassemblyjs/utf8@1.11.6': {}
+
+ '@webassemblyjs/wasm-edit@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/helper-buffer': 1.12.1
+ '@webassemblyjs/helper-wasm-bytecode': 1.11.6
+ '@webassemblyjs/helper-wasm-section': 1.12.1
+ '@webassemblyjs/wasm-gen': 1.12.1
+ '@webassemblyjs/wasm-opt': 1.12.1
+ '@webassemblyjs/wasm-parser': 1.12.1
+ '@webassemblyjs/wast-printer': 1.12.1
+
+ '@webassemblyjs/wasm-gen@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/helper-wasm-bytecode': 1.11.6
+ '@webassemblyjs/ieee754': 1.11.6
+ '@webassemblyjs/leb128': 1.11.6
+ '@webassemblyjs/utf8': 1.11.6
+
+ '@webassemblyjs/wasm-opt@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/helper-buffer': 1.12.1
+ '@webassemblyjs/wasm-gen': 1.12.1
+ '@webassemblyjs/wasm-parser': 1.12.1
+
+ '@webassemblyjs/wasm-parser@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/helper-api-error': 1.11.6
+ '@webassemblyjs/helper-wasm-bytecode': 1.11.6
+ '@webassemblyjs/ieee754': 1.11.6
+ '@webassemblyjs/leb128': 1.11.6
+ '@webassemblyjs/utf8': 1.11.6
+
+ '@webassemblyjs/wast-printer@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@xtuc/long': 4.2.2
+
+ '@xtuc/ieee754@1.2.0': {}
+
+ '@xtuc/long@4.2.2': {}
+
+ acorn-import-attributes@1.9.5(acorn@8.12.1):
+ dependencies:
+ acorn: 8.12.1
+
+ acorn@8.12.1: {}
+
+ ajv-keywords@3.5.2(ajv@6.12.6):
+ dependencies:
+ ajv: 6.12.6
+
+ ajv@6.12.6:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
+
ansi-regex@5.0.1: {}
ansi-regex@6.0.1: {}
@@ -1949,6 +2370,8 @@ snapshots:
node-releases: 2.0.18
update-browserslist-db: 1.1.0(browserslist@4.23.3)
+ buffer-from@1.1.2: {}
+
bundle-require@5.0.0(esbuild@0.23.0):
dependencies:
esbuild: 0.23.0
@@ -1966,6 +2389,11 @@ snapshots:
escape-string-regexp: 1.0.5
supports-color: 5.5.0
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
chokidar@3.6.0:
dependencies:
anymatch: 3.1.3
@@ -1978,6 +2406,8 @@ snapshots:
optionalDependencies:
fsevents: 2.3.3
+ chrome-trace-event@1.0.4: {}
+
color-convert@1.9.3:
dependencies:
color-name: 1.1.3
@@ -1990,6 +2420,8 @@ snapshots:
color-name@1.1.4: {}
+ commander@2.20.3: {}
+
commander@4.1.1: {}
consola@3.2.3: {}
@@ -2004,6 +2436,8 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
+ csstype@3.1.3: {}
+
debug@4.3.6:
dependencies:
ms: 2.1.2
@@ -2022,8 +2456,15 @@ snapshots:
emoji-regex@9.2.2: {}
+ enhanced-resolve@5.17.1:
+ dependencies:
+ graceful-fs: 4.2.11
+ tapable: 2.2.1
+
entities@4.5.0: {}
+ es-module-lexer@1.5.4: {}
+
esbuild@0.23.0:
optionalDependencies:
'@esbuild/aix-ppc64': 0.23.0
@@ -2055,8 +2496,23 @@ snapshots:
escape-string-regexp@1.0.5: {}
+ eslint-scope@5.1.1:
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 4.3.0
+
+ esrecurse@4.3.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ estraverse@4.3.0: {}
+
+ estraverse@5.3.0: {}
+
estree-walker@2.0.2: {}
+ events@3.3.0: {}
+
execa@5.1.1:
dependencies:
cross-spawn: 7.0.3
@@ -2069,6 +2525,8 @@ snapshots:
signal-exit: 3.0.7
strip-final-newline: 2.0.0
+ fast-deep-equal@3.1.3: {}
+
fast-glob@3.3.2:
dependencies:
'@nodelib/fs.stat': 2.0.5
@@ -2077,6 +2535,8 @@ snapshots:
merge2: 1.4.1
micromatch: 4.0.5
+ fast-json-stable-stringify@2.1.0: {}
+
fastq@1.17.1:
dependencies:
reusify: 1.0.4
@@ -2104,6 +2564,8 @@ snapshots:
dependencies:
is-glob: 4.0.3
+ glob-to-regexp@0.4.1: {}
+
glob@10.3.12:
dependencies:
foreground-child: 3.1.1
@@ -2123,8 +2585,14 @@ snapshots:
merge2: 1.4.1
slash: 3.0.0
+ graceful-fs@4.2.11: {}
+
has-flag@3.0.0: {}
+ has-flag@4.0.0: {}
+
+ hash-sum@2.0.0: {}
+
html-tags@3.3.1: {}
human-signals@2.1.0: {}
@@ -2155,12 +2623,22 @@ snapshots:
optionalDependencies:
'@pkgjs/parseargs': 0.11.0
+ jest-worker@27.5.1:
+ dependencies:
+ '@types/node': 20.16.2
+ merge-stream: 2.0.0
+ supports-color: 8.1.1
+
joycon@3.1.1: {}
js-tokens@4.0.0: {}
jsesc@2.5.2: {}
+ json-parse-even-better-errors@2.3.1: {}
+
+ json-schema-traverse@0.4.1: {}
+
json5@2.2.3: {}
lilconfig@3.1.1: {}
@@ -2169,6 +2647,8 @@ snapshots:
load-tsconfig@0.2.5: {}
+ loader-runner@4.3.0: {}
+
lodash.sortby@4.7.0: {}
lru-cache@10.2.0: {}
@@ -2190,6 +2670,12 @@ snapshots:
braces: 3.0.2
picomatch: 2.3.1
+ mime-db@1.52.0: {}
+
+ mime-types@2.1.35:
+ dependencies:
+ mime-db: 1.52.0
+
mimic-fn@2.1.0: {}
minimatch@9.0.4:
@@ -2212,6 +2698,8 @@ snapshots:
nanoid@3.3.7: {}
+ neo-async@2.6.2: {}
+
node-releases@2.0.18: {}
normalize-path@3.0.0: {}
@@ -2267,6 +2755,10 @@ snapshots:
queue-microtask@1.2.3: {}
+ randombytes@2.1.0:
+ dependencies:
+ safe-buffer: 5.2.1
+
readdirp@3.6.0:
dependencies:
picomatch: 2.3.1
@@ -2305,8 +2797,20 @@ snapshots:
dependencies:
queue-microtask: 1.2.3
+ safe-buffer@5.2.1: {}
+
+ schema-utils@3.3.0:
+ dependencies:
+ '@types/json-schema': 7.0.15
+ ajv: 6.12.6
+ ajv-keywords: 3.5.2(ajv@6.12.6)
+
semver@6.3.1: {}
+ serialize-javascript@6.0.2:
+ dependencies:
+ randombytes: 2.1.0
+
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
@@ -2323,6 +2827,13 @@ snapshots:
source-map-js@1.2.0: {}
+ source-map-support@0.5.21:
+ dependencies:
+ buffer-from: 1.1.2
+ source-map: 0.6.1
+
+ source-map@0.6.1: {}
+
source-map@0.8.0-beta.0:
dependencies:
whatwg-url: 7.1.0
@@ -2363,8 +2874,36 @@ snapshots:
dependencies:
has-flag: 3.0.0
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ supports-color@8.1.1:
+ dependencies:
+ has-flag: 4.0.0
+
svg-tags@1.0.0: {}
+ tapable@2.2.1: {}
+
+ terser-webpack-plugin@5.3.10(esbuild@0.23.0)(webpack@5.94.0(esbuild@0.23.0)):
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.25
+ jest-worker: 27.5.1
+ schema-utils: 3.3.0
+ serialize-javascript: 6.0.2
+ terser: 5.31.6
+ webpack: 5.94.0(esbuild@0.23.0)
+ optionalDependencies:
+ esbuild: 0.23.0
+
+ terser@5.31.6:
+ dependencies:
+ '@jridgewell/source-map': 0.3.6
+ acorn: 8.12.1
+ commander: 2.20.3
+ source-map-support: 0.5.21
+
thenify-all@1.6.0:
dependencies:
thenify: 3.3.1
@@ -2428,8 +2967,68 @@ snapshots:
escalade: 3.2.0
picocolors: 1.0.1
+ uri-js@4.4.1:
+ dependencies:
+ punycode: 2.3.1
+
+ vue-loader@17.4.2(vue@3.5.3(typescript@5.5.4))(webpack@5.94.0(esbuild@0.23.0)):
+ dependencies:
+ chalk: 4.1.2
+ hash-sum: 2.0.0
+ watchpack: 2.4.2
+ webpack: 5.94.0(esbuild@0.23.0)
+ optionalDependencies:
+ vue: 3.5.3(typescript@5.5.4)
+
+ vue@3.5.3(typescript@5.5.4):
+ dependencies:
+ '@vue/compiler-dom': 3.5.3
+ '@vue/compiler-sfc': 3.5.3
+ '@vue/runtime-dom': 3.5.3
+ '@vue/server-renderer': 3.5.3(vue@3.5.3(typescript@5.5.4))
+ '@vue/shared': 3.5.3
+ optionalDependencies:
+ typescript: 5.5.4
+
+ watchpack@2.4.2:
+ dependencies:
+ glob-to-regexp: 0.4.1
+ graceful-fs: 4.2.11
+
webidl-conversions@4.0.2: {}
+ webpack-sources@3.2.3: {}
+
+ webpack@5.94.0(esbuild@0.23.0):
+ dependencies:
+ '@types/estree': 1.0.5
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/wasm-edit': 1.12.1
+ '@webassemblyjs/wasm-parser': 1.12.1
+ acorn: 8.12.1
+ acorn-import-attributes: 1.9.5(acorn@8.12.1)
+ browserslist: 4.23.3
+ chrome-trace-event: 1.0.4
+ enhanced-resolve: 5.17.1
+ es-module-lexer: 1.5.4
+ eslint-scope: 5.1.1
+ events: 3.3.0
+ glob-to-regexp: 0.4.1
+ graceful-fs: 4.2.11
+ json-parse-even-better-errors: 2.3.1
+ loader-runner: 4.3.0
+ mime-types: 2.1.35
+ neo-async: 2.6.2
+ schema-utils: 3.3.0
+ tapable: 2.2.1
+ terser-webpack-plugin: 5.3.10(esbuild@0.23.0)(webpack@5.94.0(esbuild@0.23.0))
+ watchpack: 2.4.2
+ webpack-sources: 3.2.3
+ transitivePeerDependencies:
+ - '@swc/core'
+ - esbuild
+ - uglify-js
+
whatwg-url@7.1.0:
dependencies:
lodash.sortby: 4.7.0
diff --git a/test/jsx-basic/index.test.ts b/test/jsx-basic/index.test.ts
new file mode 100644
index 0000000..617df3d
--- /dev/null
+++ b/test/jsx-basic/index.test.ts
@@ -0,0 +1,23 @@
+import { dirname } from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { expect, test } from '@playwright/test';
+import { createRsbuild, loadConfig } from '@rsbuild/core';
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+
+test('should build basic Vue jsx correctly', async ({ page }) => {
+ const rsbuild = await createRsbuild({
+ cwd: __dirname,
+ rsbuildConfig: (await loadConfig({ cwd: __dirname })).content,
+ });
+
+ await rsbuild.build();
+ const { server, urls } = await rsbuild.preview();
+
+ await page.goto(urls[0]);
+
+ const button1 = page.locator('#button1');
+ await expect(button1).toHaveText('A: 0');
+
+ await server.close();
+});
diff --git a/test/jsx-basic/rsbuild.config.ts b/test/jsx-basic/rsbuild.config.ts
new file mode 100644
index 0000000..9319fa9
--- /dev/null
+++ b/test/jsx-basic/rsbuild.config.ts
@@ -0,0 +1,18 @@
+import { defineConfig } from '@rsbuild/core';
+import { pluginBabel } from '@rsbuild/plugin-babel';
+import { pluginVue } from '@rsbuild/plugin-vue';
+import { pluginVueJsx } from '@rsbuild/plugin-vue-jsx';
+import { getRandomPort } from '../helper';
+
+export default defineConfig({
+ plugins: [
+ pluginVue(),
+ pluginVueJsx(),
+ pluginBabel({
+ include: /\.(?:jsx|tsx)$/,
+ }),
+ ],
+ server: {
+ port: getRandomPort(),
+ },
+});
diff --git a/test/jsx-basic/src/A.jsx b/test/jsx-basic/src/A.jsx
new file mode 100644
index 0000000..22d6237
--- /dev/null
+++ b/test/jsx-basic/src/A.jsx
@@ -0,0 +1,14 @@
+import { defineComponent, ref } from 'vue';
+
+export default defineComponent({
+ name: 'Test',
+
+ setup() {
+ const count = ref(0);
+ return () => (
+
+ );
+ },
+});
diff --git a/test/jsx-basic/src/index.js b/test/jsx-basic/src/index.js
new file mode 100644
index 0000000..6d3006e
--- /dev/null
+++ b/test/jsx-basic/src/index.js
@@ -0,0 +1,6 @@
+import { createApp } from 'vue';
+import A from './A';
+
+console.log(A);
+
+createApp(A).mount('#root');
diff --git a/test/jsx-hmr/index.test.ts b/test/jsx-hmr/index.test.ts
new file mode 100644
index 0000000..62634e6
--- /dev/null
+++ b/test/jsx-hmr/index.test.ts
@@ -0,0 +1,263 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { type Page, expect, test } from '@playwright/test';
+import { createRsbuild, loadConfig } from '@rsbuild/core';
+import { pluginVueJsx } from '../../src';
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+
+test('should render', async ({ page }) => {
+ const rsbuild = await createRsbuild({
+ cwd: __dirname,
+ rsbuildConfig: (await loadConfig({ cwd: __dirname })).content,
+ });
+
+ const { server, urls } = await rsbuild.startDevServer();
+
+ await page.goto(urls[0]);
+
+ await expect(page.locator('.named')).toHaveText('named 0');
+ await expect(page.locator('.named-specifier')).toHaveText(
+ 'named specifier 1',
+ );
+ await expect(page.locator('.default')).toHaveText('default 2');
+ await expect(page.locator('.default-tsx')).toHaveText('default tsx 3');
+ await expect(page.locator('.script')).toHaveText('script 4');
+ await expect(page.locator('.ts-import')).toHaveText('success');
+
+ await server.close();
+});
+
+test('should update', async ({ page }) => {
+ const rsbuild = await createRsbuild({
+ cwd: __dirname,
+ rsbuildConfig: (await loadConfig({ cwd: __dirname })).content,
+ });
+
+ const { server, urls } = await rsbuild.startDevServer();
+
+ await page.goto(urls[0]);
+
+ await page.locator('.named').click();
+ await expect(page.locator('.named')).toHaveText('named 1');
+
+ await page.locator('.named-specifier').click();
+ await expect(page.locator('.named-specifier')).toHaveText(
+ 'named specifier 2',
+ );
+
+ await page.locator('.default').click();
+ await expect(page.locator('.default')).toHaveText('default 3');
+
+ await page.locator('.default-tsx').click();
+ await expect(page.locator('.default-tsx')).toHaveText('default tsx 4');
+
+ await page.locator('.script').click();
+ await expect(page.locator('.script')).toHaveText('script 5');
+
+ await server.close();
+});
+
+test.describe('vue jsx hmr', () => {
+ // HMR cases will fail in Windows
+ if (process.platform === 'win32') {
+ test.skip();
+ }
+
+ let server: {
+ close: () => Promise;
+ };
+ let page: Page;
+
+ test.beforeAll(async ({ browser }) => {
+ page = await browser.newPage();
+ const rsbuild = await createRsbuild({
+ cwd: __dirname,
+ rsbuildConfig: (await loadConfig({ cwd: __dirname })).content,
+ });
+
+ const result = await rsbuild.startDevServer();
+ server = result.server;
+
+ await page.goto(result.urls[0]);
+ });
+
+ test.afterAll(async () => {
+ // reset files
+ editFile('Comps.jsx', (code) =>
+ code.replace('named updated {count', 'named {count'),
+ );
+ editFile('Comps.jsx', (code) =>
+ code.replace('named specifier updated {count', 'named specifier {count'),
+ );
+ editFile('Comps.jsx', (code) =>
+ code.replace('default updated {count', 'default {count'),
+ );
+ editFile('Comp.tsx', (code) =>
+ code.replace('default tsx updated {count', 'default tsx {count'),
+ );
+ editFile('setup-syntax-jsx.vue', (code) =>
+ code.replace('let count = ref(1000)', 'let count = ref(100)'),
+ );
+
+ await server.close();
+ });
+
+ test('hmr: named export', async () => {
+ await page.locator('.named').click();
+ await expect(page.locator('.named')).toHaveText('named 1');
+ await page.locator('.named-specifier').click();
+ await expect(page.locator('.named-specifier')).toHaveText(
+ 'named specifier 2',
+ );
+ await page.locator('.default').click();
+ await expect(page.locator('.default')).toHaveText('default 3');
+ await page.locator('.default-tsx').click();
+ await expect(page.locator('.default-tsx')).toHaveText('default tsx 4');
+
+ editFile('Comps.jsx', (code) =>
+ code.replace('named {count', 'named updated {count'),
+ );
+ await untilUpdated(() => page.textContent('.named'), 'named updated 0');
+
+ // affect all components in same file
+ await expect(page.locator('.named-specifier')).toHaveText(
+ 'named specifier 1',
+ );
+ await expect(page.locator('.default')).toHaveText('default 2');
+ // should not affect other components from different file
+ await expect(page.locator('.default-tsx')).toHaveText('default tsx 4');
+ });
+
+ test('hmr: named export via specifier', async () => {
+ editFile('Comps.jsx', (code) =>
+ code.replace('named specifier {count', 'named specifier updated {count'),
+ );
+ await untilUpdated(
+ () => page.textContent('.named-specifier'),
+ 'named specifier updated 1',
+ );
+
+ // affect all components in same file
+ await expect(page.locator('.default')).toHaveText('default 2');
+ // should not affect other components on the page
+ await expect(page.locator('.default-tsx')).toHaveText('default tsx 4');
+ });
+
+ test('hmr: default export', async () => {
+ editFile('Comps.jsx', (code) =>
+ code.replace('default {count', 'default updated {count'),
+ );
+ await untilUpdated(() => page.textContent('.default'), 'default updated 2');
+
+ // should not affect other components on the page
+ await expect(page.locator('.default-tsx')).toHaveText('default tsx 4');
+ });
+
+ test('hmr: default Default export', async () => {
+ await page.locator('.named').click();
+ await expect(page.locator('.named')).toHaveText('named updated 1');
+
+ editFile('Comp.tsx', (code) =>
+ code.replace('default tsx {count', 'default tsx updated {count'),
+ );
+ await untilUpdated(
+ () => page.textContent('.default-tsx'),
+ 'default tsx updated 3',
+ );
+
+ // should not affect other components on the page
+ await expect(page.locator('.named')).toHaveText('named updated 1');
+ });
+
+ // not pass
+ test.skip('hmr: vue script lang=jsx', async () => {
+ await page.locator('.script').click();
+ await expect(page.locator('.script')).toHaveText('script 5');
+
+ editFile('Script.vue', (code) =>
+ code.replace('script {count', 'script updated {count'),
+ );
+
+ await untilUpdated(() => page.textContent('.script'), 'script updated 4');
+
+ // reset code
+ editFile('Script.vue', (code) =>
+ code.replace('script updated {count', 'script {count'),
+ );
+ });
+
+ // not pass
+ test.skip('hmr: script in .vue', async () => {
+ await page.locator('.src-import').click();
+ await expect(page.locator('.src-import')).toHaveText('src import 6');
+
+ editFile('Script.vue', (code) =>
+ code.replace('script {count', 'script updated {count'),
+ );
+ await untilUpdated(() => page.textContent('.script'), 'script updated 4');
+
+ await expect(page.locator('.src-import')).toHaveText('src import 6');
+
+ // reset code
+ editFile('Script.vue', (code) =>
+ code.replace('script updated {count', 'script {count'),
+ );
+ });
+
+ // not pass
+ test.skip('hmr: src import in .vue', async () => {
+ await page.locator('.script').click();
+ await expect(page.locator('.script')).toHaveText('script 5');
+
+ editFile('SrcImport.jsx', (code) =>
+ code.replace('src import {count', 'src import updated {count'),
+ );
+
+ await untilUpdated(
+ () => page.textContent('.src-import'),
+ 'src import updated 5',
+ );
+
+ await expect(page.locator('.script')).toHaveText('script 5');
+
+ // reset code
+ editFile('SrcImport.jsx', (code) =>
+ code.replace('src import updated {count', 'src import {count'),
+ );
+ });
+
+ test('hmr: setup jsx in .vue', async () => {
+ editFile('setup-syntax-jsx.vue', (code) =>
+ code.replace('let count = ref(100)', 'let count = ref(1000)'),
+ );
+
+ await untilUpdated(() => page.textContent('.setup-jsx'), '1000');
+ });
+});
+
+function editFile(filename: string, replacer: (str: string) => string): void {
+ const fileName = path.join(__dirname, 'src', filename);
+ const content = fs.readFileSync(fileName, 'utf-8');
+ const modified = replacer(content);
+ fs.writeFileSync(fileName, modified);
+}
+
+const timeout = (n: number) => new Promise((r) => setTimeout(r, n));
+
+async function untilUpdated(
+ poll: () => Promise,
+ expected: string,
+): Promise {
+ const maxTries = 50;
+ for (let tries = 0; tries < maxTries; tries++) {
+ const actual = (await poll()) ?? '';
+ if (actual.indexOf(expected) > -1 || tries === maxTries - 1) {
+ expect(actual).toMatch(expected);
+ break;
+ }
+
+ await timeout(50);
+ }
+}
diff --git a/test/jsx-hmr/rsbuild.config.ts b/test/jsx-hmr/rsbuild.config.ts
new file mode 100644
index 0000000..df51be7
--- /dev/null
+++ b/test/jsx-hmr/rsbuild.config.ts
@@ -0,0 +1,21 @@
+import { defineConfig } from '@rsbuild/core';
+import { pluginBabel } from '@rsbuild/plugin-babel';
+import { pluginVue } from '@rsbuild/plugin-vue';
+import { pluginVueJsx } from '@rsbuild/plugin-vue-jsx';
+import { getRandomPort } from '../helper';
+
+export default defineConfig({
+ plugins: [
+ pluginVue(),
+ pluginBabel({
+ include: /\.(?:jsx|tsx)(\.js)?$/,
+ }),
+ pluginVueJsx(),
+ ],
+ server: {
+ port: getRandomPort(),
+ },
+ performance: {
+ buildCache: false,
+ },
+});
diff --git a/test/jsx-hmr/src/Comp.tsx b/test/jsx-hmr/src/Comp.tsx
new file mode 100644
index 0000000..42e5eec
--- /dev/null
+++ b/test/jsx-hmr/src/Comp.tsx
@@ -0,0 +1,14 @@
+import { defineComponent, ref } from 'vue';
+
+const Default = defineComponent(() => {
+ const count = ref(3);
+ const inc = () => count.value++;
+
+ return () => (
+
+ );
+});
+
+export default Default;
diff --git a/test/jsx-hmr/src/Comps.jsx b/test/jsx-hmr/src/Comps.jsx
new file mode 100644
index 0000000..cb1c120
--- /dev/null
+++ b/test/jsx-hmr/src/Comps.jsx
@@ -0,0 +1,35 @@
+import { defineComponent, ref } from 'vue';
+
+export const Named = defineComponent(() => {
+ const count = ref(0);
+ const inc = () => count.value++;
+
+ return () => (
+
+ );
+});
+
+const NamedSpec = defineComponent(() => {
+ const count = ref(1);
+ const inc = () => count.value++;
+
+ return () => (
+
+ );
+});
+export { NamedSpec };
+
+export default defineComponent(() => {
+ const count = ref(2);
+ const inc = () => count.value++;
+
+ return () => (
+
+ );
+});
diff --git a/test/jsx-hmr/src/Script.vue b/test/jsx-hmr/src/Script.vue
new file mode 100644
index 0000000..b262597
--- /dev/null
+++ b/test/jsx-hmr/src/Script.vue
@@ -0,0 +1,14 @@
+
diff --git a/test/jsx-hmr/src/SrcImport.jsx b/test/jsx-hmr/src/SrcImport.jsx
new file mode 100644
index 0000000..3deef5d
--- /dev/null
+++ b/test/jsx-hmr/src/SrcImport.jsx
@@ -0,0 +1,12 @@
+import { defineComponent, ref } from 'vue';
+
+export default defineComponent(() => {
+ const count = ref(5);
+ const inc = () => count.value++;
+
+ return () => (
+
+ );
+});
diff --git a/test/jsx-hmr/src/SrcImport.vue b/test/jsx-hmr/src/SrcImport.vue
new file mode 100644
index 0000000..89f6fb3
--- /dev/null
+++ b/test/jsx-hmr/src/SrcImport.vue
@@ -0,0 +1 @@
+
diff --git a/test/jsx-hmr/src/TsImport.vue b/test/jsx-hmr/src/TsImport.vue
new file mode 100644
index 0000000..2871dc8
--- /dev/null
+++ b/test/jsx-hmr/src/TsImport.vue
@@ -0,0 +1,16 @@
+
+ Ts Import
+ {{ foo }}
+
+
+
+
+
diff --git a/test/jsx-hmr/src/TsImportFile.ts b/test/jsx-hmr/src/TsImportFile.ts
new file mode 100644
index 0000000..14d0f45
--- /dev/null
+++ b/test/jsx-hmr/src/TsImportFile.ts
@@ -0,0 +1 @@
+export const foo = 'success';
diff --git a/test/jsx-hmr/src/index.jsx b/test/jsx-hmr/src/index.jsx
new file mode 100644
index 0000000..7d74335
--- /dev/null
+++ b/test/jsx-hmr/src/index.jsx
@@ -0,0 +1,24 @@
+import { createApp } from 'vue';
+import { default as TsxDefault } from './Comp';
+import { default as Default, Named, NamedSpec } from './Comps';
+import JsxScript from './Script.vue';
+import JsxSrcImport from './SrcImport.vue';
+import TsImport from './TsImport.vue';
+import JsxSetupSyntax from './setup-syntax-jsx.vue';
+
+function App() {
+ return (
+ <>
+
+
+
+
+
+
+
+
+ >
+ );
+}
+
+createApp(App).mount('#root');
diff --git a/test/jsx-hmr/src/setup-syntax-jsx.vue b/test/jsx-hmr/src/setup-syntax-jsx.vue
new file mode 100644
index 0000000..ddde9fd
--- /dev/null
+++ b/test/jsx-hmr/src/setup-syntax-jsx.vue
@@ -0,0 +1,17 @@
+
+
+
+ {{ count }}
+
+
diff --git a/test/basic/index.test.ts b/test/old/index.test.ts
similarity index 100%
rename from test/basic/index.test.ts
rename to test/old/index.test.ts
diff --git a/test/basic/src/index.js b/test/old/src/index.js
similarity index 100%
rename from test/basic/src/index.js
rename to test/old/src/index.js
diff --git a/test/sfc-lang-jsx/index.test.ts b/test/sfc-lang-jsx/index.test.ts
new file mode 100644
index 0000000..d5fe71e
--- /dev/null
+++ b/test/sfc-lang-jsx/index.test.ts
@@ -0,0 +1,26 @@
+import { dirname } from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { expect, test } from '@playwright/test';
+import { createRsbuild, loadConfig } from '@rsbuild/core';
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+
+test('should build Vue sfc with lang="jsx" correctly', async ({ page }) => {
+ const rsbuild = await createRsbuild({
+ cwd: __dirname,
+ rsbuildConfig: (await loadConfig({ cwd: __dirname })).content,
+ });
+
+ await rsbuild.build();
+ const { server, urls } = await rsbuild.preview();
+
+ await page.goto(urls[0]);
+
+ const button = page.locator('#button');
+ await expect(button).toHaveText('0');
+
+ const foo = page.locator('#foo');
+ await expect(foo).toHaveText('Foo');
+
+ await server.close();
+});
diff --git a/test/sfc-lang-jsx/rsbuild.config.ts b/test/sfc-lang-jsx/rsbuild.config.ts
new file mode 100644
index 0000000..9319fa9
--- /dev/null
+++ b/test/sfc-lang-jsx/rsbuild.config.ts
@@ -0,0 +1,18 @@
+import { defineConfig } from '@rsbuild/core';
+import { pluginBabel } from '@rsbuild/plugin-babel';
+import { pluginVue } from '@rsbuild/plugin-vue';
+import { pluginVueJsx } from '@rsbuild/plugin-vue-jsx';
+import { getRandomPort } from '../helper';
+
+export default defineConfig({
+ plugins: [
+ pluginVue(),
+ pluginVueJsx(),
+ pluginBabel({
+ include: /\.(?:jsx|tsx)$/,
+ }),
+ ],
+ server: {
+ port: getRandomPort(),
+ },
+});
diff --git a/test/sfc-lang-jsx/src/App.vue b/test/sfc-lang-jsx/src/App.vue
new file mode 100644
index 0000000..cb70cc0
--- /dev/null
+++ b/test/sfc-lang-jsx/src/App.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
diff --git a/test/sfc-lang-jsx/src/index.js b/test/sfc-lang-jsx/src/index.js
new file mode 100644
index 0000000..84c0113
--- /dev/null
+++ b/test/sfc-lang-jsx/src/index.js
@@ -0,0 +1,4 @@
+import { createApp } from 'vue';
+import App from './App.vue';
+
+createApp(App).mount('#root');
diff --git a/test/sfc-lang-tsx/index.test.ts b/test/sfc-lang-tsx/index.test.ts
new file mode 100644
index 0000000..ce9b510
--- /dev/null
+++ b/test/sfc-lang-tsx/index.test.ts
@@ -0,0 +1,26 @@
+import { dirname } from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { expect, test } from '@playwright/test';
+import { createRsbuild, loadConfig } from '@rsbuild/core';
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+
+test('should build Vue sfc with lang="tsx" correctly', async ({ page }) => {
+ const rsbuild = await createRsbuild({
+ cwd: __dirname,
+ rsbuildConfig: (await loadConfig({ cwd: __dirname })).content,
+ });
+
+ await rsbuild.build();
+ const { server, urls } = await rsbuild.preview();
+
+ await page.goto(urls[0]);
+
+ const button = page.locator('#button');
+ await expect(button).toHaveText('0');
+
+ const foo = page.locator('#foo');
+ await expect(foo).toHaveText('Foo');
+
+ await server.close();
+});
diff --git a/test/sfc-lang-tsx/rsbuild.config.ts b/test/sfc-lang-tsx/rsbuild.config.ts
new file mode 100644
index 0000000..9319fa9
--- /dev/null
+++ b/test/sfc-lang-tsx/rsbuild.config.ts
@@ -0,0 +1,18 @@
+import { defineConfig } from '@rsbuild/core';
+import { pluginBabel } from '@rsbuild/plugin-babel';
+import { pluginVue } from '@rsbuild/plugin-vue';
+import { pluginVueJsx } from '@rsbuild/plugin-vue-jsx';
+import { getRandomPort } from '../helper';
+
+export default defineConfig({
+ plugins: [
+ pluginVue(),
+ pluginVueJsx(),
+ pluginBabel({
+ include: /\.(?:jsx|tsx)$/,
+ }),
+ ],
+ server: {
+ port: getRandomPort(),
+ },
+});
diff --git a/test/sfc-lang-tsx/src/App.vue b/test/sfc-lang-tsx/src/App.vue
new file mode 100644
index 0000000..b6e325a
--- /dev/null
+++ b/test/sfc-lang-tsx/src/App.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
diff --git a/test/sfc-lang-tsx/src/index.js b/test/sfc-lang-tsx/src/index.js
new file mode 100644
index 0000000..84c0113
--- /dev/null
+++ b/test/sfc-lang-tsx/src/index.js
@@ -0,0 +1,4 @@
+import { createApp } from 'vue';
+import App from './App.vue';
+
+createApp(App).mount('#root');