├── .gitignore ├── .prettierrc ├── README.md ├── package-lock.json ├── package.json ├── playground ├── .cache │ ├── manifest.json │ └── server-build.js ├── app │ ├── root.tsx │ └── routes │ │ └── _index.tsx ├── build.mjs ├── components │ └── Button.jsx ├── package-lock.json ├── package.json ├── remix.config.mjs ├── rsbuild.config.mjs ├── server.mjs ├── src │ └── index.js ├── utils │ ├── HoistContainerReferencesPlugin.js │ ├── RemixAssetsManifestPlugin.js │ ├── get-exports.js │ ├── get-routes.js │ ├── manifest.js │ └── server-build-entry.js ├── webpack.browser.js └── webpack.server.js ├── src ├── RemixAssetsManifestPlugin.mjs ├── get-exports.mjs ├── get-routes.mjs ├── index.mjs └── manifest.mjs └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | playground/public/build 4 | .idea 5 | /playground/build/ 6 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rsbuild Plugin 2 | 3 | Visit https://rsbuild.dev/plugins/dev/ to learn how to write an Rsbuild plugin. 4 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "remix", 3 | "lockfileVersion": 2, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "dependencies": { 8 | "esbuild": "^0.19.5", 9 | "webpack-node-externals": "^3.0.0" 10 | }, 11 | "devDependencies": { 12 | "@rsbuild/core": "^0.1.9", 13 | "@rsbuild/shared": "^0.1.9" 14 | } 15 | }, 16 | "node_modules/@esbuild/android-arm": { 17 | "version": "0.19.5", 18 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.5.tgz", 19 | "integrity": "sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==", 20 | "cpu": [ 21 | "arm" 22 | ], 23 | "optional": true, 24 | "os": [ 25 | "android" 26 | ], 27 | "engines": { 28 | "node": ">=12" 29 | } 30 | }, 31 | "node_modules/@esbuild/android-arm64": { 32 | "version": "0.19.5", 33 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.5.tgz", 34 | "integrity": "sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==", 35 | "cpu": [ 36 | "arm64" 37 | ], 38 | "optional": true, 39 | "os": [ 40 | "android" 41 | ], 42 | "engines": { 43 | "node": ">=12" 44 | } 45 | }, 46 | "node_modules/@esbuild/android-x64": { 47 | "version": "0.19.5", 48 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.5.tgz", 49 | "integrity": "sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==", 50 | "cpu": [ 51 | "x64" 52 | ], 53 | "optional": true, 54 | "os": [ 55 | "android" 56 | ], 57 | "engines": { 58 | "node": ">=12" 59 | } 60 | }, 61 | "node_modules/@esbuild/darwin-arm64": { 62 | "version": "0.19.5", 63 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.5.tgz", 64 | "integrity": "sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==", 65 | "cpu": [ 66 | "arm64" 67 | ], 68 | "optional": true, 69 | "os": [ 70 | "darwin" 71 | ], 72 | "engines": { 73 | "node": ">=12" 74 | } 75 | }, 76 | "node_modules/@esbuild/darwin-x64": { 77 | "version": "0.19.5", 78 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.5.tgz", 79 | "integrity": "sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==", 80 | "cpu": [ 81 | "x64" 82 | ], 83 | "optional": true, 84 | "os": [ 85 | "darwin" 86 | ], 87 | "engines": { 88 | "node": ">=12" 89 | } 90 | }, 91 | "node_modules/@esbuild/freebsd-arm64": { 92 | "version": "0.19.5", 93 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.5.tgz", 94 | "integrity": "sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==", 95 | "cpu": [ 96 | "arm64" 97 | ], 98 | "optional": true, 99 | "os": [ 100 | "freebsd" 101 | ], 102 | "engines": { 103 | "node": ">=12" 104 | } 105 | }, 106 | "node_modules/@esbuild/freebsd-x64": { 107 | "version": "0.19.5", 108 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.5.tgz", 109 | "integrity": "sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==", 110 | "cpu": [ 111 | "x64" 112 | ], 113 | "optional": true, 114 | "os": [ 115 | "freebsd" 116 | ], 117 | "engines": { 118 | "node": ">=12" 119 | } 120 | }, 121 | "node_modules/@esbuild/linux-arm": { 122 | "version": "0.19.5", 123 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.5.tgz", 124 | "integrity": "sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==", 125 | "cpu": [ 126 | "arm" 127 | ], 128 | "optional": true, 129 | "os": [ 130 | "linux" 131 | ], 132 | "engines": { 133 | "node": ">=12" 134 | } 135 | }, 136 | "node_modules/@esbuild/linux-arm64": { 137 | "version": "0.19.5", 138 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.5.tgz", 139 | "integrity": "sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==", 140 | "cpu": [ 141 | "arm64" 142 | ], 143 | "optional": true, 144 | "os": [ 145 | "linux" 146 | ], 147 | "engines": { 148 | "node": ">=12" 149 | } 150 | }, 151 | "node_modules/@esbuild/linux-ia32": { 152 | "version": "0.19.5", 153 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.5.tgz", 154 | "integrity": "sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==", 155 | "cpu": [ 156 | "ia32" 157 | ], 158 | "optional": true, 159 | "os": [ 160 | "linux" 161 | ], 162 | "engines": { 163 | "node": ">=12" 164 | } 165 | }, 166 | "node_modules/@esbuild/linux-loong64": { 167 | "version": "0.19.5", 168 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.5.tgz", 169 | "integrity": "sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==", 170 | "cpu": [ 171 | "loong64" 172 | ], 173 | "optional": true, 174 | "os": [ 175 | "linux" 176 | ], 177 | "engines": { 178 | "node": ">=12" 179 | } 180 | }, 181 | "node_modules/@esbuild/linux-mips64el": { 182 | "version": "0.19.5", 183 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.5.tgz", 184 | "integrity": "sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==", 185 | "cpu": [ 186 | "mips64el" 187 | ], 188 | "optional": true, 189 | "os": [ 190 | "linux" 191 | ], 192 | "engines": { 193 | "node": ">=12" 194 | } 195 | }, 196 | "node_modules/@esbuild/linux-ppc64": { 197 | "version": "0.19.5", 198 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.5.tgz", 199 | "integrity": "sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==", 200 | "cpu": [ 201 | "ppc64" 202 | ], 203 | "optional": true, 204 | "os": [ 205 | "linux" 206 | ], 207 | "engines": { 208 | "node": ">=12" 209 | } 210 | }, 211 | "node_modules/@esbuild/linux-riscv64": { 212 | "version": "0.19.5", 213 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.5.tgz", 214 | "integrity": "sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==", 215 | "cpu": [ 216 | "riscv64" 217 | ], 218 | "optional": true, 219 | "os": [ 220 | "linux" 221 | ], 222 | "engines": { 223 | "node": ">=12" 224 | } 225 | }, 226 | "node_modules/@esbuild/linux-s390x": { 227 | "version": "0.19.5", 228 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.5.tgz", 229 | "integrity": "sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==", 230 | "cpu": [ 231 | "s390x" 232 | ], 233 | "optional": true, 234 | "os": [ 235 | "linux" 236 | ], 237 | "engines": { 238 | "node": ">=12" 239 | } 240 | }, 241 | "node_modules/@esbuild/linux-x64": { 242 | "version": "0.19.5", 243 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.5.tgz", 244 | "integrity": "sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==", 245 | "cpu": [ 246 | "x64" 247 | ], 248 | "optional": true, 249 | "os": [ 250 | "linux" 251 | ], 252 | "engines": { 253 | "node": ">=12" 254 | } 255 | }, 256 | "node_modules/@esbuild/netbsd-x64": { 257 | "version": "0.19.5", 258 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.5.tgz", 259 | "integrity": "sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==", 260 | "cpu": [ 261 | "x64" 262 | ], 263 | "optional": true, 264 | "os": [ 265 | "netbsd" 266 | ], 267 | "engines": { 268 | "node": ">=12" 269 | } 270 | }, 271 | "node_modules/@esbuild/openbsd-x64": { 272 | "version": "0.19.5", 273 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.5.tgz", 274 | "integrity": "sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==", 275 | "cpu": [ 276 | "x64" 277 | ], 278 | "optional": true, 279 | "os": [ 280 | "openbsd" 281 | ], 282 | "engines": { 283 | "node": ">=12" 284 | } 285 | }, 286 | "node_modules/@esbuild/sunos-x64": { 287 | "version": "0.19.5", 288 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.5.tgz", 289 | "integrity": "sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==", 290 | "cpu": [ 291 | "x64" 292 | ], 293 | "optional": true, 294 | "os": [ 295 | "sunos" 296 | ], 297 | "engines": { 298 | "node": ">=12" 299 | } 300 | }, 301 | "node_modules/@esbuild/win32-arm64": { 302 | "version": "0.19.5", 303 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.5.tgz", 304 | "integrity": "sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==", 305 | "cpu": [ 306 | "arm64" 307 | ], 308 | "optional": true, 309 | "os": [ 310 | "win32" 311 | ], 312 | "engines": { 313 | "node": ">=12" 314 | } 315 | }, 316 | "node_modules/@esbuild/win32-ia32": { 317 | "version": "0.19.5", 318 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.5.tgz", 319 | "integrity": "sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==", 320 | "cpu": [ 321 | "ia32" 322 | ], 323 | "optional": true, 324 | "os": [ 325 | "win32" 326 | ], 327 | "engines": { 328 | "node": ">=12" 329 | } 330 | }, 331 | "node_modules/@esbuild/win32-x64": { 332 | "version": "0.19.5", 333 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.5.tgz", 334 | "integrity": "sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==", 335 | "cpu": [ 336 | "x64" 337 | ], 338 | "optional": true, 339 | "os": [ 340 | "win32" 341 | ], 342 | "engines": { 343 | "node": ">=12" 344 | } 345 | }, 346 | "node_modules/@rsbuild/core": { 347 | "version": "0.1.9", 348 | "resolved": "https://registry.npmjs.org/@rsbuild/core/-/core-0.1.9.tgz", 349 | "integrity": "sha512-UsMUeBQqIOulHyLCaVQew0WtHSL+/S5zSMU9+Iby/t5szEsWytRDjwekcZDxKhhut21Kyktr5d1RofTvY19ttg==", 350 | "dev": true, 351 | "dependencies": { 352 | "@rsbuild/shared": "0.1.9", 353 | "@rspack/core": "0.4.1", 354 | "core-js": "~3.32.2", 355 | "html-webpack-plugin": "npm:html-rspack-plugin@5.5.7", 356 | "postcss": "8.4.31" 357 | }, 358 | "bin": { 359 | "rsbuild": "bin/rsbuild.js" 360 | }, 361 | "engines": { 362 | "node": ">=14.0.0" 363 | } 364 | }, 365 | "node_modules/@rsbuild/shared": { 366 | "version": "0.1.9", 367 | "resolved": "https://registry.npmjs.org/@rsbuild/shared/-/shared-0.1.9.tgz", 368 | "integrity": "sha512-u2RAfuNRMIt+7KnCgikjIzl64nS3Ce3HI1EB3ALPkPdtV8ZvORID8RqdYzIJSfv4/cHD8rGeR6oXIFsAOc84OA==", 369 | "dev": true, 370 | "dependencies": { 371 | "@rspack/core": "0.4.1", 372 | "caniuse-lite": "^1.0.30001559", 373 | "line-diff": "2.1.1", 374 | "lodash": "^4.17.21", 375 | "postcss": "8.4.31" 376 | } 377 | }, 378 | "node_modules/@rspack/binding": { 379 | "version": "0.4.1", 380 | "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-0.4.1.tgz", 381 | "integrity": "sha512-tPETZWbP9VYzmdCIKmaxWWx0z2c//acd5eV2kgKOSWt29MH2wo+EFySfvWKWVCTwjBkuVrqaULUxcIJB3vUCTg==", 382 | "dev": true, 383 | "optionalDependencies": { 384 | "@rspack/binding-darwin-arm64": "0.4.1", 385 | "@rspack/binding-darwin-x64": "0.4.1", 386 | "@rspack/binding-linux-arm64-gnu": "0.4.1", 387 | "@rspack/binding-linux-arm64-musl": "0.4.1", 388 | "@rspack/binding-linux-x64-gnu": "0.4.1", 389 | "@rspack/binding-linux-x64-musl": "0.4.1", 390 | "@rspack/binding-win32-arm64-msvc": "0.4.1", 391 | "@rspack/binding-win32-ia32-msvc": "0.4.1", 392 | "@rspack/binding-win32-x64-msvc": "0.4.1" 393 | } 394 | }, 395 | "node_modules/@rspack/binding-darwin-arm64": { 396 | "version": "0.4.1", 397 | "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-0.4.1.tgz", 398 | "integrity": "sha512-oGosukPLEycihtFq+sfx4NOCYJW6+LBbdwlj9hNW8s7mqSshkKBTEkzGgEA+tsyQODOD13Qvg9R4dhUkXnMFJg==", 399 | "cpu": [ 400 | "arm64" 401 | ], 402 | "dev": true, 403 | "optional": true, 404 | "os": [ 405 | "darwin" 406 | ] 407 | }, 408 | "node_modules/@rspack/binding-darwin-x64": { 409 | "version": "0.4.1", 410 | "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-0.4.1.tgz", 411 | "integrity": "sha512-k7PbuNXxeqTL+5JONH+5PWk0iwiztT3zXej12qgy2joddWXpxkZJPjTxy8sNFV2tMQ7T0UqbWZaB3ZUFvPu5IA==", 412 | "cpu": [ 413 | "x64" 414 | ], 415 | "dev": true, 416 | "optional": true, 417 | "os": [ 418 | "darwin" 419 | ] 420 | }, 421 | "node_modules/@rspack/binding-linux-arm64-gnu": { 422 | "version": "0.4.1", 423 | "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.4.1.tgz", 424 | "integrity": "sha512-dunS6sTH14cbDIbt4gs7Bd/tHLS/D87dhgEu9GUH+oVR8niSzXKyhJayOOefxr7L1/tSUtEVGJAbYFXgz5LvNg==", 425 | "cpu": [ 426 | "arm64" 427 | ], 428 | "dev": true, 429 | "optional": true, 430 | "os": [ 431 | "linux" 432 | ] 433 | }, 434 | "node_modules/@rspack/binding-linux-arm64-musl": { 435 | "version": "0.4.1", 436 | "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.4.1.tgz", 437 | "integrity": "sha512-d/iUGx/uLy6eJ5OpFWH+ALcdgMiTgktq0UNbPN69lKkDctvfGCyi5tPHwbIh1g6WrpbROq7EPldNAxYAIAH8aw==", 438 | "cpu": [ 439 | "arm64" 440 | ], 441 | "dev": true, 442 | "optional": true, 443 | "os": [ 444 | "linux" 445 | ] 446 | }, 447 | "node_modules/@rspack/binding-linux-x64-gnu": { 448 | "version": "0.4.1", 449 | "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.4.1.tgz", 450 | "integrity": "sha512-bDLwt2D5dSQlJPfbzdtANvaZfaQrRAU/g6wmFF12RX2rZjPTipihMi5gywdGaDzAfCryRy8JE2CLqECI5sxKNw==", 451 | "cpu": [ 452 | "x64" 453 | ], 454 | "dev": true, 455 | "optional": true, 456 | "os": [ 457 | "linux" 458 | ] 459 | }, 460 | "node_modules/@rspack/binding-linux-x64-musl": { 461 | "version": "0.4.1", 462 | "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-0.4.1.tgz", 463 | "integrity": "sha512-lROn0GNzSjVBjILfeaoy5fLhVvjaY6bHGXit6EecDsd3BsruvlOVMaru+gU5otZO/o4ndTqFcA6xwCmXNn6Atg==", 464 | "cpu": [ 465 | "x64" 466 | ], 467 | "dev": true, 468 | "optional": true, 469 | "os": [ 470 | "linux" 471 | ] 472 | }, 473 | "node_modules/@rspack/binding-win32-arm64-msvc": { 474 | "version": "0.4.1", 475 | "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.4.1.tgz", 476 | "integrity": "sha512-PKIQDu4vRADPqQtnkiJwqDmgT5kuRj8oJgx6tb6D8kR+SFq2Y26zadNPu/LulfUTgQmxJSyQEvz4su3Gp1tAsQ==", 477 | "cpu": [ 478 | "arm64" 479 | ], 480 | "dev": true, 481 | "optional": true, 482 | "os": [ 483 | "win32" 484 | ] 485 | }, 486 | "node_modules/@rspack/binding-win32-ia32-msvc": { 487 | "version": "0.4.1", 488 | "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.4.1.tgz", 489 | "integrity": "sha512-RqcW+kedZoNlWXUdZiyuxHEQKerDx6zGjoCg5GSMZpCxFZsNMwq65Ok5WCH8WI+hzFXzphq06FgjpB5Y8K3zsQ==", 490 | "cpu": [ 491 | "ia32" 492 | ], 493 | "dev": true, 494 | "optional": true, 495 | "os": [ 496 | "win32" 497 | ] 498 | }, 499 | "node_modules/@rspack/binding-win32-x64-msvc": { 500 | "version": "0.4.1", 501 | "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.4.1.tgz", 502 | "integrity": "sha512-eNvamV92pt0lP9o43HdtpiD7Oo7lHeQqwNnaKAetN4BHVSPLtOjkHFS/aM1SKMtxCayEdzXYU7UZGPQvmdcXqQ==", 503 | "cpu": [ 504 | "x64" 505 | ], 506 | "dev": true, 507 | "optional": true, 508 | "os": [ 509 | "win32" 510 | ] 511 | }, 512 | "node_modules/@rspack/core": { 513 | "version": "0.4.1", 514 | "resolved": "https://registry.npmjs.org/@rspack/core/-/core-0.4.1.tgz", 515 | "integrity": "sha512-g502i0fHMj0lCr1Y/Bh5iwsEGB1BTiN+H06Oc39qEgs4bwQqnkGg/iQSBoR7q1886lAK8yIIDQeyCxF/6qI7EA==", 516 | "dev": true, 517 | "dependencies": { 518 | "@rspack/binding": "0.4.1", 519 | "@swc/helpers": "0.5.1", 520 | "browserslist": "^4.21.3", 521 | "compare-versions": "6.0.0-rc.1", 522 | "enhanced-resolve": "5.12.0", 523 | "fast-querystring": "1.1.2", 524 | "graceful-fs": "4.2.10", 525 | "json-parse-even-better-errors": "^3.0.0", 526 | "neo-async": "2.6.2", 527 | "react-refresh": "0.14.0", 528 | "tapable": "2.2.1", 529 | "terminal-link": "^2.1.1", 530 | "watchpack": "^2.4.0", 531 | "webpack-sources": "3.2.3", 532 | "zod": "^3.21.4", 533 | "zod-validation-error": "1.3.1" 534 | }, 535 | "engines": { 536 | "node": ">=16.0.0" 537 | } 538 | }, 539 | "node_modules/@swc/helpers": { 540 | "version": "0.5.1", 541 | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz", 542 | "integrity": "sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg==", 543 | "dev": true, 544 | "dependencies": { 545 | "tslib": "^2.4.0" 546 | } 547 | }, 548 | "node_modules/ansi-escapes": { 549 | "version": "4.3.2", 550 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", 551 | "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", 552 | "dev": true, 553 | "dependencies": { 554 | "type-fest": "^0.21.3" 555 | }, 556 | "engines": { 557 | "node": ">=8" 558 | }, 559 | "funding": { 560 | "url": "https://github.com/sponsors/sindresorhus" 561 | } 562 | }, 563 | "node_modules/browserslist": { 564 | "version": "4.22.2", 565 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", 566 | "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", 567 | "dev": true, 568 | "funding": [ 569 | { 570 | "type": "opencollective", 571 | "url": "https://opencollective.com/browserslist" 572 | }, 573 | { 574 | "type": "tidelift", 575 | "url": "https://tidelift.com/funding/github/npm/browserslist" 576 | }, 577 | { 578 | "type": "github", 579 | "url": "https://github.com/sponsors/ai" 580 | } 581 | ], 582 | "dependencies": { 583 | "caniuse-lite": "^1.0.30001565", 584 | "electron-to-chromium": "^1.4.601", 585 | "node-releases": "^2.0.14", 586 | "update-browserslist-db": "^1.0.13" 587 | }, 588 | "bin": { 589 | "browserslist": "cli.js" 590 | }, 591 | "engines": { 592 | "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" 593 | } 594 | }, 595 | "node_modules/caniuse-lite": { 596 | "version": "1.0.30001566", 597 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", 598 | "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", 599 | "dev": true, 600 | "funding": [ 601 | { 602 | "type": "opencollective", 603 | "url": "https://opencollective.com/browserslist" 604 | }, 605 | { 606 | "type": "tidelift", 607 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite" 608 | }, 609 | { 610 | "type": "github", 611 | "url": "https://github.com/sponsors/ai" 612 | } 613 | ] 614 | }, 615 | "node_modules/compare-versions": { 616 | "version": "6.0.0-rc.1", 617 | "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.0.0-rc.1.tgz", 618 | "integrity": "sha512-cFhkjbGY1jLFWIV7KegECbfuyYPxSGvgGkdkfM+ibboQDoPwg2FRHm5BSNTOApiauRBzJIQH7qvOJs2sW5ueKQ==", 619 | "dev": true 620 | }, 621 | "node_modules/core-js": { 622 | "version": "3.32.2", 623 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.2.tgz", 624 | "integrity": "sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==", 625 | "dev": true, 626 | "hasInstallScript": true, 627 | "funding": { 628 | "type": "opencollective", 629 | "url": "https://opencollective.com/core-js" 630 | } 631 | }, 632 | "node_modules/electron-to-chromium": { 633 | "version": "1.4.603", 634 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.603.tgz", 635 | "integrity": "sha512-Dvo5OGjnl7AZTU632dFJtWj0uJK835eeOVQIuRcmBmsFsTNn3cL05FqOyHAfGQDIoHfLhyJ1Tya3PJ0ceMz54g==", 636 | "dev": true 637 | }, 638 | "node_modules/enhanced-resolve": { 639 | "version": "5.12.0", 640 | "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", 641 | "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", 642 | "dev": true, 643 | "dependencies": { 644 | "graceful-fs": "^4.2.4", 645 | "tapable": "^2.2.0" 646 | }, 647 | "engines": { 648 | "node": ">=10.13.0" 649 | } 650 | }, 651 | "node_modules/esbuild": { 652 | "version": "0.19.5", 653 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz", 654 | "integrity": "sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==", 655 | "hasInstallScript": true, 656 | "bin": { 657 | "esbuild": "bin/esbuild" 658 | }, 659 | "engines": { 660 | "node": ">=12" 661 | }, 662 | "optionalDependencies": { 663 | "@esbuild/android-arm": "0.19.5", 664 | "@esbuild/android-arm64": "0.19.5", 665 | "@esbuild/android-x64": "0.19.5", 666 | "@esbuild/darwin-arm64": "0.19.5", 667 | "@esbuild/darwin-x64": "0.19.5", 668 | "@esbuild/freebsd-arm64": "0.19.5", 669 | "@esbuild/freebsd-x64": "0.19.5", 670 | "@esbuild/linux-arm": "0.19.5", 671 | "@esbuild/linux-arm64": "0.19.5", 672 | "@esbuild/linux-ia32": "0.19.5", 673 | "@esbuild/linux-loong64": "0.19.5", 674 | "@esbuild/linux-mips64el": "0.19.5", 675 | "@esbuild/linux-ppc64": "0.19.5", 676 | "@esbuild/linux-riscv64": "0.19.5", 677 | "@esbuild/linux-s390x": "0.19.5", 678 | "@esbuild/linux-x64": "0.19.5", 679 | "@esbuild/netbsd-x64": "0.19.5", 680 | "@esbuild/openbsd-x64": "0.19.5", 681 | "@esbuild/sunos-x64": "0.19.5", 682 | "@esbuild/win32-arm64": "0.19.5", 683 | "@esbuild/win32-ia32": "0.19.5", 684 | "@esbuild/win32-x64": "0.19.5" 685 | } 686 | }, 687 | "node_modules/escalade": { 688 | "version": "3.1.1", 689 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 690 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 691 | "dev": true, 692 | "engines": { 693 | "node": ">=6" 694 | } 695 | }, 696 | "node_modules/fast-decode-uri-component": { 697 | "version": "1.0.1", 698 | "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", 699 | "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", 700 | "dev": true 701 | }, 702 | "node_modules/fast-querystring": { 703 | "version": "1.1.2", 704 | "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", 705 | "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", 706 | "dev": true, 707 | "dependencies": { 708 | "fast-decode-uri-component": "^1.0.1" 709 | } 710 | }, 711 | "node_modules/glob-to-regexp": { 712 | "version": "0.4.1", 713 | "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", 714 | "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", 715 | "dev": true 716 | }, 717 | "node_modules/graceful-fs": { 718 | "version": "4.2.10", 719 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", 720 | "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", 721 | "dev": true 722 | }, 723 | "node_modules/has-flag": { 724 | "version": "4.0.0", 725 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 726 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 727 | "dev": true, 728 | "engines": { 729 | "node": ">=8" 730 | } 731 | }, 732 | "node_modules/html-webpack-plugin": { 733 | "name": "html-rspack-plugin", 734 | "version": "5.5.7", 735 | "resolved": "https://registry.npmjs.org/html-rspack-plugin/-/html-rspack-plugin-5.5.7.tgz", 736 | "integrity": "sha512-7dNAURj9XBHWoYg59F8VU6hT7J7w+od4Lr5hc/rrgN6sy6QfqVpoPqW9Qw4IGFOgit8Pul7iQp1yysBSIhOlsg==", 737 | "dev": true, 738 | "dependencies": { 739 | "lodash": "^4.17.21", 740 | "tapable": "^2.0.0" 741 | }, 742 | "engines": { 743 | "node": ">=10.13.0" 744 | }, 745 | "funding": { 746 | "type": "opencollective", 747 | "url": "https://opencollective.com/html-webpack-plugin" 748 | } 749 | }, 750 | "node_modules/json-parse-even-better-errors": { 751 | "version": "3.0.1", 752 | "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", 753 | "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==", 754 | "dev": true, 755 | "engines": { 756 | "node": "^14.17.0 || ^16.13.0 || >=18.0.0" 757 | } 758 | }, 759 | "node_modules/levdist": { 760 | "version": "1.0.0", 761 | "resolved": "https://registry.npmjs.org/levdist/-/levdist-1.0.0.tgz", 762 | "integrity": "sha512-YguwC2spb0pqpJM3a5OsBhih/GG2ZHoaSHnmBqhEI7997a36buhqcRTegEjozHxyxByIwLpZHZTVYMThq+Zd3g==", 763 | "dev": true 764 | }, 765 | "node_modules/line-diff": { 766 | "version": "2.1.1", 767 | "resolved": "https://registry.npmjs.org/line-diff/-/line-diff-2.1.1.tgz", 768 | "integrity": "sha512-vswdynAI5AMPJacOo2o+JJ4caDJbnY2NEqms4MhMW0NJbjh3skP/brpVTAgBxrg55NRZ2Vtw88ef18hnagIpYQ==", 769 | "dev": true, 770 | "dependencies": { 771 | "levdist": "^1.0.0" 772 | } 773 | }, 774 | "node_modules/lodash": { 775 | "version": "4.17.21", 776 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 777 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 778 | "dev": true 779 | }, 780 | "node_modules/nanoid": { 781 | "version": "3.3.7", 782 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", 783 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", 784 | "dev": true, 785 | "funding": [ 786 | { 787 | "type": "github", 788 | "url": "https://github.com/sponsors/ai" 789 | } 790 | ], 791 | "bin": { 792 | "nanoid": "bin/nanoid.cjs" 793 | }, 794 | "engines": { 795 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 796 | } 797 | }, 798 | "node_modules/neo-async": { 799 | "version": "2.6.2", 800 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", 801 | "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", 802 | "dev": true 803 | }, 804 | "node_modules/node-releases": { 805 | "version": "2.0.14", 806 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", 807 | "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", 808 | "dev": true 809 | }, 810 | "node_modules/picocolors": { 811 | "version": "1.0.0", 812 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 813 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 814 | "dev": true 815 | }, 816 | "node_modules/postcss": { 817 | "version": "8.4.31", 818 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", 819 | "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", 820 | "dev": true, 821 | "funding": [ 822 | { 823 | "type": "opencollective", 824 | "url": "https://opencollective.com/postcss/" 825 | }, 826 | { 827 | "type": "tidelift", 828 | "url": "https://tidelift.com/funding/github/npm/postcss" 829 | }, 830 | { 831 | "type": "github", 832 | "url": "https://github.com/sponsors/ai" 833 | } 834 | ], 835 | "dependencies": { 836 | "nanoid": "^3.3.6", 837 | "picocolors": "^1.0.0", 838 | "source-map-js": "^1.0.2" 839 | }, 840 | "engines": { 841 | "node": "^10 || ^12 || >=14" 842 | } 843 | }, 844 | "node_modules/react-refresh": { 845 | "version": "0.14.0", 846 | "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", 847 | "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", 848 | "dev": true, 849 | "engines": { 850 | "node": ">=0.10.0" 851 | } 852 | }, 853 | "node_modules/source-map-js": { 854 | "version": "1.0.2", 855 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 856 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 857 | "dev": true, 858 | "engines": { 859 | "node": ">=0.10.0" 860 | } 861 | }, 862 | "node_modules/supports-color": { 863 | "version": "7.2.0", 864 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 865 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 866 | "dev": true, 867 | "dependencies": { 868 | "has-flag": "^4.0.0" 869 | }, 870 | "engines": { 871 | "node": ">=8" 872 | } 873 | }, 874 | "node_modules/supports-hyperlinks": { 875 | "version": "2.3.0", 876 | "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", 877 | "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", 878 | "dev": true, 879 | "dependencies": { 880 | "has-flag": "^4.0.0", 881 | "supports-color": "^7.0.0" 882 | }, 883 | "engines": { 884 | "node": ">=8" 885 | } 886 | }, 887 | "node_modules/tapable": { 888 | "version": "2.2.1", 889 | "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", 890 | "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", 891 | "dev": true, 892 | "engines": { 893 | "node": ">=6" 894 | } 895 | }, 896 | "node_modules/terminal-link": { 897 | "version": "2.1.1", 898 | "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", 899 | "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", 900 | "dev": true, 901 | "dependencies": { 902 | "ansi-escapes": "^4.2.1", 903 | "supports-hyperlinks": "^2.0.0" 904 | }, 905 | "engines": { 906 | "node": ">=8" 907 | }, 908 | "funding": { 909 | "url": "https://github.com/sponsors/sindresorhus" 910 | } 911 | }, 912 | "node_modules/tslib": { 913 | "version": "2.6.2", 914 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", 915 | "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", 916 | "dev": true 917 | }, 918 | "node_modules/type-fest": { 919 | "version": "0.21.3", 920 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", 921 | "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", 922 | "dev": true, 923 | "engines": { 924 | "node": ">=10" 925 | }, 926 | "funding": { 927 | "url": "https://github.com/sponsors/sindresorhus" 928 | } 929 | }, 930 | "node_modules/update-browserslist-db": { 931 | "version": "1.0.13", 932 | "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", 933 | "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", 934 | "dev": true, 935 | "funding": [ 936 | { 937 | "type": "opencollective", 938 | "url": "https://opencollective.com/browserslist" 939 | }, 940 | { 941 | "type": "tidelift", 942 | "url": "https://tidelift.com/funding/github/npm/browserslist" 943 | }, 944 | { 945 | "type": "github", 946 | "url": "https://github.com/sponsors/ai" 947 | } 948 | ], 949 | "dependencies": { 950 | "escalade": "^3.1.1", 951 | "picocolors": "^1.0.0" 952 | }, 953 | "bin": { 954 | "update-browserslist-db": "cli.js" 955 | }, 956 | "peerDependencies": { 957 | "browserslist": ">= 4.21.0" 958 | } 959 | }, 960 | "node_modules/watchpack": { 961 | "version": "2.4.0", 962 | "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", 963 | "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", 964 | "dev": true, 965 | "dependencies": { 966 | "glob-to-regexp": "^0.4.1", 967 | "graceful-fs": "^4.1.2" 968 | }, 969 | "engines": { 970 | "node": ">=10.13.0" 971 | } 972 | }, 973 | "node_modules/webpack-node-externals": { 974 | "version": "3.0.0", 975 | "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz", 976 | "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==", 977 | "engines": { 978 | "node": ">=6" 979 | } 980 | }, 981 | "node_modules/webpack-sources": { 982 | "version": "3.2.3", 983 | "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", 984 | "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", 985 | "dev": true, 986 | "engines": { 987 | "node": ">=10.13.0" 988 | } 989 | }, 990 | "node_modules/zod": { 991 | "version": "3.22.4", 992 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", 993 | "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", 994 | "dev": true, 995 | "funding": { 996 | "url": "https://github.com/sponsors/colinhacks" 997 | } 998 | }, 999 | "node_modules/zod-validation-error": { 1000 | "version": "1.3.1", 1001 | "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-1.3.1.tgz", 1002 | "integrity": "sha512-cNEXpla+tREtNdAnNKY4xKY1SGOn2yzyuZMu4O0RQylX9apRpUjNcPkEc3uHIAr5Ct7LenjZt6RzjEH6+JsqVQ==", 1003 | "dev": true, 1004 | "engines": { 1005 | "node": ">=16.0.0" 1006 | }, 1007 | "peerDependencies": { 1008 | "zod": "^3.18.0" 1009 | } 1010 | } 1011 | }, 1012 | "dependencies": { 1013 | "@esbuild/android-arm": { 1014 | "version": "0.19.5", 1015 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.5.tgz", 1016 | "integrity": "sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==", 1017 | "optional": true 1018 | }, 1019 | "@esbuild/android-arm64": { 1020 | "version": "0.19.5", 1021 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.5.tgz", 1022 | "integrity": "sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==", 1023 | "optional": true 1024 | }, 1025 | "@esbuild/android-x64": { 1026 | "version": "0.19.5", 1027 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.5.tgz", 1028 | "integrity": "sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==", 1029 | "optional": true 1030 | }, 1031 | "@esbuild/darwin-arm64": { 1032 | "version": "0.19.5", 1033 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.5.tgz", 1034 | "integrity": "sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==", 1035 | "optional": true 1036 | }, 1037 | "@esbuild/darwin-x64": { 1038 | "version": "0.19.5", 1039 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.5.tgz", 1040 | "integrity": "sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==", 1041 | "optional": true 1042 | }, 1043 | "@esbuild/freebsd-arm64": { 1044 | "version": "0.19.5", 1045 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.5.tgz", 1046 | "integrity": "sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==", 1047 | "optional": true 1048 | }, 1049 | "@esbuild/freebsd-x64": { 1050 | "version": "0.19.5", 1051 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.5.tgz", 1052 | "integrity": "sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==", 1053 | "optional": true 1054 | }, 1055 | "@esbuild/linux-arm": { 1056 | "version": "0.19.5", 1057 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.5.tgz", 1058 | "integrity": "sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==", 1059 | "optional": true 1060 | }, 1061 | "@esbuild/linux-arm64": { 1062 | "version": "0.19.5", 1063 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.5.tgz", 1064 | "integrity": "sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==", 1065 | "optional": true 1066 | }, 1067 | "@esbuild/linux-ia32": { 1068 | "version": "0.19.5", 1069 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.5.tgz", 1070 | "integrity": "sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==", 1071 | "optional": true 1072 | }, 1073 | "@esbuild/linux-loong64": { 1074 | "version": "0.19.5", 1075 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.5.tgz", 1076 | "integrity": "sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==", 1077 | "optional": true 1078 | }, 1079 | "@esbuild/linux-mips64el": { 1080 | "version": "0.19.5", 1081 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.5.tgz", 1082 | "integrity": "sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==", 1083 | "optional": true 1084 | }, 1085 | "@esbuild/linux-ppc64": { 1086 | "version": "0.19.5", 1087 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.5.tgz", 1088 | "integrity": "sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==", 1089 | "optional": true 1090 | }, 1091 | "@esbuild/linux-riscv64": { 1092 | "version": "0.19.5", 1093 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.5.tgz", 1094 | "integrity": "sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==", 1095 | "optional": true 1096 | }, 1097 | "@esbuild/linux-s390x": { 1098 | "version": "0.19.5", 1099 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.5.tgz", 1100 | "integrity": "sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==", 1101 | "optional": true 1102 | }, 1103 | "@esbuild/linux-x64": { 1104 | "version": "0.19.5", 1105 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.5.tgz", 1106 | "integrity": "sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==", 1107 | "optional": true 1108 | }, 1109 | "@esbuild/netbsd-x64": { 1110 | "version": "0.19.5", 1111 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.5.tgz", 1112 | "integrity": "sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==", 1113 | "optional": true 1114 | }, 1115 | "@esbuild/openbsd-x64": { 1116 | "version": "0.19.5", 1117 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.5.tgz", 1118 | "integrity": "sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==", 1119 | "optional": true 1120 | }, 1121 | "@esbuild/sunos-x64": { 1122 | "version": "0.19.5", 1123 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.5.tgz", 1124 | "integrity": "sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==", 1125 | "optional": true 1126 | }, 1127 | "@esbuild/win32-arm64": { 1128 | "version": "0.19.5", 1129 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.5.tgz", 1130 | "integrity": "sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==", 1131 | "optional": true 1132 | }, 1133 | "@esbuild/win32-ia32": { 1134 | "version": "0.19.5", 1135 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.5.tgz", 1136 | "integrity": "sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==", 1137 | "optional": true 1138 | }, 1139 | "@esbuild/win32-x64": { 1140 | "version": "0.19.5", 1141 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.5.tgz", 1142 | "integrity": "sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==", 1143 | "optional": true 1144 | }, 1145 | "@rsbuild/core": { 1146 | "version": "0.1.9", 1147 | "resolved": "https://registry.npmjs.org/@rsbuild/core/-/core-0.1.9.tgz", 1148 | "integrity": "sha512-UsMUeBQqIOulHyLCaVQew0WtHSL+/S5zSMU9+Iby/t5szEsWytRDjwekcZDxKhhut21Kyktr5d1RofTvY19ttg==", 1149 | "dev": true, 1150 | "requires": { 1151 | "@rsbuild/shared": "0.1.9", 1152 | "@rspack/core": "0.4.1", 1153 | "core-js": "~3.32.2", 1154 | "html-webpack-plugin": "npm:html-rspack-plugin@5.5.7", 1155 | "postcss": "8.4.31" 1156 | } 1157 | }, 1158 | "@rsbuild/shared": { 1159 | "version": "0.1.9", 1160 | "resolved": "https://registry.npmjs.org/@rsbuild/shared/-/shared-0.1.9.tgz", 1161 | "integrity": "sha512-u2RAfuNRMIt+7KnCgikjIzl64nS3Ce3HI1EB3ALPkPdtV8ZvORID8RqdYzIJSfv4/cHD8rGeR6oXIFsAOc84OA==", 1162 | "dev": true, 1163 | "requires": { 1164 | "@rspack/core": "0.4.1", 1165 | "caniuse-lite": "^1.0.30001559", 1166 | "line-diff": "2.1.1", 1167 | "lodash": "^4.17.21", 1168 | "postcss": "8.4.31" 1169 | } 1170 | }, 1171 | "@rspack/binding": { 1172 | "version": "0.4.1", 1173 | "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-0.4.1.tgz", 1174 | "integrity": "sha512-tPETZWbP9VYzmdCIKmaxWWx0z2c//acd5eV2kgKOSWt29MH2wo+EFySfvWKWVCTwjBkuVrqaULUxcIJB3vUCTg==", 1175 | "dev": true, 1176 | "requires": { 1177 | "@rspack/binding-darwin-arm64": "0.4.1", 1178 | "@rspack/binding-darwin-x64": "0.4.1", 1179 | "@rspack/binding-linux-arm64-gnu": "0.4.1", 1180 | "@rspack/binding-linux-arm64-musl": "0.4.1", 1181 | "@rspack/binding-linux-x64-gnu": "0.4.1", 1182 | "@rspack/binding-linux-x64-musl": "0.4.1", 1183 | "@rspack/binding-win32-arm64-msvc": "0.4.1", 1184 | "@rspack/binding-win32-ia32-msvc": "0.4.1", 1185 | "@rspack/binding-win32-x64-msvc": "0.4.1" 1186 | } 1187 | }, 1188 | "@rspack/binding-darwin-arm64": { 1189 | "version": "0.4.1", 1190 | "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-0.4.1.tgz", 1191 | "integrity": "sha512-oGosukPLEycihtFq+sfx4NOCYJW6+LBbdwlj9hNW8s7mqSshkKBTEkzGgEA+tsyQODOD13Qvg9R4dhUkXnMFJg==", 1192 | "dev": true, 1193 | "optional": true 1194 | }, 1195 | "@rspack/binding-darwin-x64": { 1196 | "version": "0.4.1", 1197 | "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-0.4.1.tgz", 1198 | "integrity": "sha512-k7PbuNXxeqTL+5JONH+5PWk0iwiztT3zXej12qgy2joddWXpxkZJPjTxy8sNFV2tMQ7T0UqbWZaB3ZUFvPu5IA==", 1199 | "dev": true, 1200 | "optional": true 1201 | }, 1202 | "@rspack/binding-linux-arm64-gnu": { 1203 | "version": "0.4.1", 1204 | "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.4.1.tgz", 1205 | "integrity": "sha512-dunS6sTH14cbDIbt4gs7Bd/tHLS/D87dhgEu9GUH+oVR8niSzXKyhJayOOefxr7L1/tSUtEVGJAbYFXgz5LvNg==", 1206 | "dev": true, 1207 | "optional": true 1208 | }, 1209 | "@rspack/binding-linux-arm64-musl": { 1210 | "version": "0.4.1", 1211 | "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.4.1.tgz", 1212 | "integrity": "sha512-d/iUGx/uLy6eJ5OpFWH+ALcdgMiTgktq0UNbPN69lKkDctvfGCyi5tPHwbIh1g6WrpbROq7EPldNAxYAIAH8aw==", 1213 | "dev": true, 1214 | "optional": true 1215 | }, 1216 | "@rspack/binding-linux-x64-gnu": { 1217 | "version": "0.4.1", 1218 | "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.4.1.tgz", 1219 | "integrity": "sha512-bDLwt2D5dSQlJPfbzdtANvaZfaQrRAU/g6wmFF12RX2rZjPTipihMi5gywdGaDzAfCryRy8JE2CLqECI5sxKNw==", 1220 | "dev": true, 1221 | "optional": true 1222 | }, 1223 | "@rspack/binding-linux-x64-musl": { 1224 | "version": "0.4.1", 1225 | "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-0.4.1.tgz", 1226 | "integrity": "sha512-lROn0GNzSjVBjILfeaoy5fLhVvjaY6bHGXit6EecDsd3BsruvlOVMaru+gU5otZO/o4ndTqFcA6xwCmXNn6Atg==", 1227 | "dev": true, 1228 | "optional": true 1229 | }, 1230 | "@rspack/binding-win32-arm64-msvc": { 1231 | "version": "0.4.1", 1232 | "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.4.1.tgz", 1233 | "integrity": "sha512-PKIQDu4vRADPqQtnkiJwqDmgT5kuRj8oJgx6tb6D8kR+SFq2Y26zadNPu/LulfUTgQmxJSyQEvz4su3Gp1tAsQ==", 1234 | "dev": true, 1235 | "optional": true 1236 | }, 1237 | "@rspack/binding-win32-ia32-msvc": { 1238 | "version": "0.4.1", 1239 | "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.4.1.tgz", 1240 | "integrity": "sha512-RqcW+kedZoNlWXUdZiyuxHEQKerDx6zGjoCg5GSMZpCxFZsNMwq65Ok5WCH8WI+hzFXzphq06FgjpB5Y8K3zsQ==", 1241 | "dev": true, 1242 | "optional": true 1243 | }, 1244 | "@rspack/binding-win32-x64-msvc": { 1245 | "version": "0.4.1", 1246 | "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.4.1.tgz", 1247 | "integrity": "sha512-eNvamV92pt0lP9o43HdtpiD7Oo7lHeQqwNnaKAetN4BHVSPLtOjkHFS/aM1SKMtxCayEdzXYU7UZGPQvmdcXqQ==", 1248 | "dev": true, 1249 | "optional": true 1250 | }, 1251 | "@rspack/core": { 1252 | "version": "0.4.1", 1253 | "resolved": "https://registry.npmjs.org/@rspack/core/-/core-0.4.1.tgz", 1254 | "integrity": "sha512-g502i0fHMj0lCr1Y/Bh5iwsEGB1BTiN+H06Oc39qEgs4bwQqnkGg/iQSBoR7q1886lAK8yIIDQeyCxF/6qI7EA==", 1255 | "dev": true, 1256 | "requires": { 1257 | "@rspack/binding": "0.4.1", 1258 | "@swc/helpers": "0.5.1", 1259 | "browserslist": "^4.21.3", 1260 | "compare-versions": "6.0.0-rc.1", 1261 | "enhanced-resolve": "5.12.0", 1262 | "fast-querystring": "1.1.2", 1263 | "graceful-fs": "4.2.10", 1264 | "json-parse-even-better-errors": "^3.0.0", 1265 | "neo-async": "2.6.2", 1266 | "react-refresh": "0.14.0", 1267 | "tapable": "2.2.1", 1268 | "terminal-link": "^2.1.1", 1269 | "watchpack": "^2.4.0", 1270 | "webpack-sources": "3.2.3", 1271 | "zod": "^3.21.4", 1272 | "zod-validation-error": "1.3.1" 1273 | } 1274 | }, 1275 | "@swc/helpers": { 1276 | "version": "0.5.1", 1277 | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz", 1278 | "integrity": "sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg==", 1279 | "dev": true, 1280 | "requires": { 1281 | "tslib": "^2.4.0" 1282 | } 1283 | }, 1284 | "ansi-escapes": { 1285 | "version": "4.3.2", 1286 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", 1287 | "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", 1288 | "dev": true, 1289 | "requires": { 1290 | "type-fest": "^0.21.3" 1291 | } 1292 | }, 1293 | "browserslist": { 1294 | "version": "4.22.2", 1295 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", 1296 | "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", 1297 | "dev": true, 1298 | "requires": { 1299 | "caniuse-lite": "^1.0.30001565", 1300 | "electron-to-chromium": "^1.4.601", 1301 | "node-releases": "^2.0.14", 1302 | "update-browserslist-db": "^1.0.13" 1303 | } 1304 | }, 1305 | "caniuse-lite": { 1306 | "version": "1.0.30001566", 1307 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", 1308 | "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", 1309 | "dev": true 1310 | }, 1311 | "compare-versions": { 1312 | "version": "6.0.0-rc.1", 1313 | "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.0.0-rc.1.tgz", 1314 | "integrity": "sha512-cFhkjbGY1jLFWIV7KegECbfuyYPxSGvgGkdkfM+ibboQDoPwg2FRHm5BSNTOApiauRBzJIQH7qvOJs2sW5ueKQ==", 1315 | "dev": true 1316 | }, 1317 | "core-js": { 1318 | "version": "3.32.2", 1319 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.2.tgz", 1320 | "integrity": "sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==", 1321 | "dev": true 1322 | }, 1323 | "electron-to-chromium": { 1324 | "version": "1.4.603", 1325 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.603.tgz", 1326 | "integrity": "sha512-Dvo5OGjnl7AZTU632dFJtWj0uJK835eeOVQIuRcmBmsFsTNn3cL05FqOyHAfGQDIoHfLhyJ1Tya3PJ0ceMz54g==", 1327 | "dev": true 1328 | }, 1329 | "enhanced-resolve": { 1330 | "version": "5.12.0", 1331 | "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", 1332 | "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", 1333 | "dev": true, 1334 | "requires": { 1335 | "graceful-fs": "^4.2.4", 1336 | "tapable": "^2.2.0" 1337 | } 1338 | }, 1339 | "esbuild": { 1340 | "version": "0.19.5", 1341 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz", 1342 | "integrity": "sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==", 1343 | "requires": { 1344 | "@esbuild/android-arm": "0.19.5", 1345 | "@esbuild/android-arm64": "0.19.5", 1346 | "@esbuild/android-x64": "0.19.5", 1347 | "@esbuild/darwin-arm64": "0.19.5", 1348 | "@esbuild/darwin-x64": "0.19.5", 1349 | "@esbuild/freebsd-arm64": "0.19.5", 1350 | "@esbuild/freebsd-x64": "0.19.5", 1351 | "@esbuild/linux-arm": "0.19.5", 1352 | "@esbuild/linux-arm64": "0.19.5", 1353 | "@esbuild/linux-ia32": "0.19.5", 1354 | "@esbuild/linux-loong64": "0.19.5", 1355 | "@esbuild/linux-mips64el": "0.19.5", 1356 | "@esbuild/linux-ppc64": "0.19.5", 1357 | "@esbuild/linux-riscv64": "0.19.5", 1358 | "@esbuild/linux-s390x": "0.19.5", 1359 | "@esbuild/linux-x64": "0.19.5", 1360 | "@esbuild/netbsd-x64": "0.19.5", 1361 | "@esbuild/openbsd-x64": "0.19.5", 1362 | "@esbuild/sunos-x64": "0.19.5", 1363 | "@esbuild/win32-arm64": "0.19.5", 1364 | "@esbuild/win32-ia32": "0.19.5", 1365 | "@esbuild/win32-x64": "0.19.5" 1366 | } 1367 | }, 1368 | "escalade": { 1369 | "version": "3.1.1", 1370 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 1371 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 1372 | "dev": true 1373 | }, 1374 | "fast-decode-uri-component": { 1375 | "version": "1.0.1", 1376 | "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", 1377 | "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", 1378 | "dev": true 1379 | }, 1380 | "fast-querystring": { 1381 | "version": "1.1.2", 1382 | "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", 1383 | "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", 1384 | "dev": true, 1385 | "requires": { 1386 | "fast-decode-uri-component": "^1.0.1" 1387 | } 1388 | }, 1389 | "glob-to-regexp": { 1390 | "version": "0.4.1", 1391 | "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", 1392 | "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", 1393 | "dev": true 1394 | }, 1395 | "graceful-fs": { 1396 | "version": "4.2.10", 1397 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", 1398 | "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", 1399 | "dev": true 1400 | }, 1401 | "has-flag": { 1402 | "version": "4.0.0", 1403 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1404 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1405 | "dev": true 1406 | }, 1407 | "html-webpack-plugin": { 1408 | "version": "npm:html-rspack-plugin@5.5.7", 1409 | "resolved": "https://registry.npmjs.org/html-rspack-plugin/-/html-rspack-plugin-5.5.7.tgz", 1410 | "integrity": "sha512-7dNAURj9XBHWoYg59F8VU6hT7J7w+od4Lr5hc/rrgN6sy6QfqVpoPqW9Qw4IGFOgit8Pul7iQp1yysBSIhOlsg==", 1411 | "dev": true, 1412 | "requires": { 1413 | "lodash": "^4.17.21", 1414 | "tapable": "^2.0.0" 1415 | } 1416 | }, 1417 | "json-parse-even-better-errors": { 1418 | "version": "3.0.1", 1419 | "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", 1420 | "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==", 1421 | "dev": true 1422 | }, 1423 | "levdist": { 1424 | "version": "1.0.0", 1425 | "resolved": "https://registry.npmjs.org/levdist/-/levdist-1.0.0.tgz", 1426 | "integrity": "sha512-YguwC2spb0pqpJM3a5OsBhih/GG2ZHoaSHnmBqhEI7997a36buhqcRTegEjozHxyxByIwLpZHZTVYMThq+Zd3g==", 1427 | "dev": true 1428 | }, 1429 | "line-diff": { 1430 | "version": "2.1.1", 1431 | "resolved": "https://registry.npmjs.org/line-diff/-/line-diff-2.1.1.tgz", 1432 | "integrity": "sha512-vswdynAI5AMPJacOo2o+JJ4caDJbnY2NEqms4MhMW0NJbjh3skP/brpVTAgBxrg55NRZ2Vtw88ef18hnagIpYQ==", 1433 | "dev": true, 1434 | "requires": { 1435 | "levdist": "^1.0.0" 1436 | } 1437 | }, 1438 | "lodash": { 1439 | "version": "4.17.21", 1440 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1441 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 1442 | "dev": true 1443 | }, 1444 | "nanoid": { 1445 | "version": "3.3.7", 1446 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", 1447 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", 1448 | "dev": true 1449 | }, 1450 | "neo-async": { 1451 | "version": "2.6.2", 1452 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", 1453 | "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", 1454 | "dev": true 1455 | }, 1456 | "node-releases": { 1457 | "version": "2.0.14", 1458 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", 1459 | "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", 1460 | "dev": true 1461 | }, 1462 | "picocolors": { 1463 | "version": "1.0.0", 1464 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 1465 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 1466 | "dev": true 1467 | }, 1468 | "postcss": { 1469 | "version": "8.4.31", 1470 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", 1471 | "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", 1472 | "dev": true, 1473 | "requires": { 1474 | "nanoid": "^3.3.6", 1475 | "picocolors": "^1.0.0", 1476 | "source-map-js": "^1.0.2" 1477 | } 1478 | }, 1479 | "react-refresh": { 1480 | "version": "0.14.0", 1481 | "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", 1482 | "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", 1483 | "dev": true 1484 | }, 1485 | "source-map-js": { 1486 | "version": "1.0.2", 1487 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 1488 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 1489 | "dev": true 1490 | }, 1491 | "supports-color": { 1492 | "version": "7.2.0", 1493 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1494 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1495 | "dev": true, 1496 | "requires": { 1497 | "has-flag": "^4.0.0" 1498 | } 1499 | }, 1500 | "supports-hyperlinks": { 1501 | "version": "2.3.0", 1502 | "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", 1503 | "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", 1504 | "dev": true, 1505 | "requires": { 1506 | "has-flag": "^4.0.0", 1507 | "supports-color": "^7.0.0" 1508 | } 1509 | }, 1510 | "tapable": { 1511 | "version": "2.2.1", 1512 | "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", 1513 | "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", 1514 | "dev": true 1515 | }, 1516 | "terminal-link": { 1517 | "version": "2.1.1", 1518 | "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", 1519 | "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", 1520 | "dev": true, 1521 | "requires": { 1522 | "ansi-escapes": "^4.2.1", 1523 | "supports-hyperlinks": "^2.0.0" 1524 | } 1525 | }, 1526 | "tslib": { 1527 | "version": "2.6.2", 1528 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", 1529 | "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", 1530 | "dev": true 1531 | }, 1532 | "type-fest": { 1533 | "version": "0.21.3", 1534 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", 1535 | "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", 1536 | "dev": true 1537 | }, 1538 | "update-browserslist-db": { 1539 | "version": "1.0.13", 1540 | "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", 1541 | "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", 1542 | "dev": true, 1543 | "requires": { 1544 | "escalade": "^3.1.1", 1545 | "picocolors": "^1.0.0" 1546 | } 1547 | }, 1548 | "watchpack": { 1549 | "version": "2.4.0", 1550 | "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", 1551 | "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", 1552 | "dev": true, 1553 | "requires": { 1554 | "glob-to-regexp": "^0.4.1", 1555 | "graceful-fs": "^4.1.2" 1556 | } 1557 | }, 1558 | "webpack-node-externals": { 1559 | "version": "3.0.0", 1560 | "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz", 1561 | "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==" 1562 | }, 1563 | "webpack-sources": { 1564 | "version": "3.2.3", 1565 | "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", 1566 | "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", 1567 | "dev": true 1568 | }, 1569 | "zod": { 1570 | "version": "3.22.4", 1571 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", 1572 | "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", 1573 | "dev": true 1574 | }, 1575 | "zod-validation-error": { 1576 | "version": "1.3.1", 1577 | "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-1.3.1.tgz", 1578 | "integrity": "sha512-cNEXpla+tREtNdAnNKY4xKY1SGOn2yzyuZMu4O0RQylX9apRpUjNcPkEc3uHIAr5Ct7LenjZt6RzjEH6+JsqVQ==", 1579 | "dev": true, 1580 | "requires": {} 1581 | } 1582 | } 1583 | } 1584 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type:": "module", 3 | "devDependencies": { 4 | "@rsbuild/core": "^0.1.9", 5 | "@rsbuild/shared": "^0.1.9" 6 | }, 7 | "dependencies": { 8 | "esbuild": "^0.19.5", 9 | "webpack-node-externals": "^3.0.0" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /playground/.cache/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1867bed47903c501", 3 | "url": "/build/manifest-1867BED47903C501.js", 4 | "entry": { 5 | "imports": [ 6 | "/build/lib-react-66188ff2c5a06a0f.js", 7 | "/build/lib-router-a524a71461d2b1ff.js", 8 | "/build/709-a3f569f183f91c6f.js", 9 | "/build/entry.client-662028472eb2ddeb.js", 10 | "/build/lib-polyfill-58f882e5ef7ff609.js", 11 | "/build/root-90d7f3c69f9b5c77.js" 12 | ], 13 | "module": "/build/entry.client-662028472eb2ddeb.js" 14 | }, 15 | "routes": { 16 | "root": { 17 | "id": "root", 18 | "path": "", 19 | "module": "/build/root-90d7f3c69f9b5c77.js", 20 | "imports": [ 21 | "/build/lib-react-66188ff2c5a06a0f.js", 22 | "/build/lib-router-a524a71461d2b1ff.js", 23 | "/build/lib-polyfill-58f882e5ef7ff609.js", 24 | "/build/709-a3f569f183f91c6f.js" 25 | ], 26 | "hasAction": false, 27 | "hasLoader": true, 28 | "hasCatchBoundary": false, 29 | "hasErrorBoundary": false 30 | }, 31 | "routes/_index": { 32 | "id": "routes/_index", 33 | "parentId": "root", 34 | "index": true, 35 | "module": "/build/routes/_index-3aebc4e561c22e4a.js", 36 | "imports": [ 37 | "/build/lib-react-66188ff2c5a06a0f.js", 38 | "/build/lib-router-a524a71461d2b1ff.js", 39 | "/build/709-a3f569f183f91c6f.js" 40 | ], 41 | "hasAction": false, 42 | "hasLoader": true, 43 | "hasCatchBoundary": false, 44 | "hasErrorBoundary": false 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /playground/.cache/server-build.js: -------------------------------------------------------------------------------- 1 | 2 | import * as entryServer from "/Users/bytedance/dev/remix/playground/node_modules/@remix-run/dev/dist/config/defaults/entry.server.node.tsx"; 3 | import * as route0 from "../app/root.tsx"; 4 | import * as route1 from "../app/routes/_index.tsx"; 5 | export const entry = { module: entryServer }; 6 | export const routes = { 7 | "root": { 8 | id: "root", 9 | parentId: undefined, 10 | path: "", 11 | index: undefined, 12 | caseSensitive: undefined, 13 | module: route0 14 | }, 15 | "routes/_index": { 16 | id: "routes/_index", 17 | parentId: "root", 18 | path: undefined, 19 | index: true, 20 | caseSensitive: undefined, 21 | module: route1 22 | } 23 | }; 24 | export const assets = {"version":"1867bed47903c501","url":"/build/manifest-1867BED47903C501.js","entry":{"imports":["/build/lib-react-66188ff2c5a06a0f.js","/build/lib-router-a524a71461d2b1ff.js","/build/709-a3f569f183f91c6f.js","/build/entry.client-662028472eb2ddeb.js","/build/lib-polyfill-58f882e5ef7ff609.js","/build/root-90d7f3c69f9b5c77.js"],"module":"/build/entry.client-662028472eb2ddeb.js"},"routes":{"root":{"id":"root","path":"","module":"/build/root-90d7f3c69f9b5c77.js","imports":["/build/lib-react-66188ff2c5a06a0f.js","/build/lib-router-a524a71461d2b1ff.js","/build/lib-polyfill-58f882e5ef7ff609.js","/build/709-a3f569f183f91c6f.js"],"hasAction":false,"hasLoader":true,"hasCatchBoundary":false,"hasErrorBoundary":false},"routes/_index":{"id":"routes/_index","parentId":"root","index":true,"module":"/build/routes/_index-3aebc4e561c22e4a.js","imports":["/build/lib-react-66188ff2c5a06a0f.js","/build/lib-router-a524a71461d2b1ff.js","/build/709-a3f569f183f91c6f.js"],"hasAction":false,"hasLoader":true,"hasCatchBoundary":false,"hasErrorBoundary":false}}}; 25 | export const future = {"v3_fetcherPersist":false}; 26 | export const publicPath = "/build/"; 27 | -------------------------------------------------------------------------------- /playground/app/root.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Links, 3 | Meta, 4 | Outlet, 5 | Scripts, 6 | ScrollRestoration, 7 | } from "@remix-run/react"; 8 | 9 | export function loader() { 10 | return "Hello, World!"; 11 | } 12 | //dynamic import data uri, force chunk handlers to be registered in webpack (since theres no import(), in this example) 13 | import("data:text/javascript,console.log('hello from app1')"); 14 | 15 | export default function App() { 16 | return ( 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /playground/app/routes/_index.tsx: -------------------------------------------------------------------------------- 1 | import { useLoaderData } from "@remix-run/react"; 2 | export function loader() { 3 | return { message: "Hello, World!" }; 4 | } 5 | // const Button = lazy(() => import('app2/button')); 6 | export default function Home() { 7 | const { message } = useLoaderData(); 8 | return ( 9 |
10 |

Home

11 |

{message}

12 |
13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /playground/build.mjs: -------------------------------------------------------------------------------- 1 | import { createRsbuild } from '@rsbuild/core'; 2 | import config from './rsbuild.config.mjs'; 3 | import * as fs from 'fs'; 4 | import * as path from 'path'; 5 | import packageJSon from './package.json' assert { type: 'json' }; 6 | import { readConfig } from '@remix-run/dev/dist/config.js'; 7 | 8 | 9 | const start = async () => { 10 | const remixConfig = await readConfig(); 11 | const client = await createRsbuild({ 12 | target: ['web'], 13 | rsbuildConfig: { 14 | ...config, 15 | dev: { 16 | setupMiddlewares: [ 17 | (middlewares, server) => { 18 | // console.log({ middlewares, server }); 19 | // middlewares.unshift(createRequestHandler({ build })) 20 | console.log('before'); 21 | console.log('after'); 22 | middlewares.unshift(async (req, res, next) => { 23 | const express = (await import('./build/index.js')).default; 24 | express.default.handle(req, res, next); 25 | }); 26 | } 27 | ] 28 | } 29 | } 30 | }); 31 | const server = await createRsbuild({ 32 | target: ['node'], 33 | rsbuildConfig: { ...config} 34 | }); 35 | const { serverMode, browserNodeBuiltinsPolyfill } = remixConfig; // Set the mode to the remix config mode 36 | if (process.env.NODE_ENV === 'production') { 37 | await client.build(); 38 | await server.build(); 39 | if (remixConfig.serverModuleFormat === 'esm') { 40 | const sr = await import('./build/index.mjs'); 41 | } else { 42 | const { serve } = (await import('./build/index.js')).default; 43 | serve() 44 | } 45 | } else { 46 | console.log('starting dev client'); 47 | await client.startDevServer({ 48 | printURLs: false 49 | }); 50 | console.log('starting dev server'); 51 | await server.startDevServer({ 52 | printURLs: false 53 | }); 54 | const isModule = packageJSon.type === 'module'; 55 | if (isModule) { 56 | if (!fs.existsSync('./build')) { 57 | fs.mkdirSync('./build'); 58 | } 59 | 60 | console.log('writing package.json'); 61 | fs.writeFileSync('./build/package.json', JSON.stringify({ type: 'commonjs' })); 62 | } 63 | } 64 | }; 65 | 66 | start(); 67 | -------------------------------------------------------------------------------- /playground/components/Button.jsx: -------------------------------------------------------------------------------- 1 | export default () => { 2 | return 3 | } 4 | -------------------------------------------------------------------------------- /playground/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "playground", 3 | "private": true, 4 | "type": "module", 5 | "version": "0.7.0", 6 | "scripts": { 7 | "dev1": "npx rsbuild dev", 8 | "webapck": "rspack --mode=development --config webpack.browser.js & rspack --mode=development --config webpack.server.js", 9 | "build": "NODE_ENV=production node ./build.mjs", 10 | "dev": "NODE_ENV=development node ./build.mjs" 11 | }, 12 | "devDependencies": { 13 | "@rsbuild/core": "^0.1.9", 14 | "@rsbuild/plugin-react": "^0.1.9", 15 | "@types/node": "^20.9.1" 16 | }, 17 | "dependencies": { 18 | "@remix-run/dev": "^2.3.0", 19 | "@remix-run/express": "^2.3.0", 20 | "@remix-run/node": "^2.3.0", 21 | "@remix-run/react": "^2.3.0", 22 | "@rsbuild/shared": "^0.0.24", 23 | "@rspack/cli": "^0.3.13", 24 | "@rspack/core": "^0.3.13", 25 | "cors": "^2.8.5", 26 | "isbot": "3.7.1", 27 | "webpack-node-externals": "^3.0.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /playground/remix.config.mjs: -------------------------------------------------------------------------------- 1 | 2 | const config = { 3 | server: "./server.mjs", 4 | serverModuleFormat: 'cjs', 5 | }; 6 | 7 | export default config; 8 | -------------------------------------------------------------------------------- /playground/rsbuild.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@rsbuild/core'; 2 | import { pluginFoo } from '../src/index.mjs'; 3 | import { pluginReact } from '@rsbuild/plugin-react'; 4 | import { readConfig } from '@remix-run/dev/dist/config.js'; 5 | const remixConfig = readConfig(); 6 | 7 | export default defineConfig({ 8 | public: { 9 | publicDir: false 10 | }, 11 | server:{ 12 | publicDir: false, 13 | port: 3000, 14 | }, 15 | plugins: [pluginFoo(remixConfig), pluginReact()], 16 | }); 17 | 18 | -------------------------------------------------------------------------------- /playground/server.mjs: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { createRequestHandler } from "@remix-run/express"; 3 | import cors from 'cors'; 4 | 5 | import * as build from "@remix-run/dev/server-build.js"; 6 | 7 | const app = express(); 8 | app.use(cors()); 9 | app.use(express.static("public")); 10 | app.use('/server', express.static("build")); 11 | app.all("*", createRequestHandler({ build })); 12 | 13 | 14 | export const serve = ()=>{ 15 | app.listen(3000, () => { 16 | console.log(`Server started at http://localhost:3000`); 17 | }); 18 | } 19 | export default app; 20 | -------------------------------------------------------------------------------- /playground/src/index.js: -------------------------------------------------------------------------------- 1 | console.log('test') -------------------------------------------------------------------------------- /playground/utils/HoistContainerReferencesPlugin.js: -------------------------------------------------------------------------------- 1 | class HoistContainerReferences { 2 | apply(compiler) { 3 | compiler.hooks.thisCompilation.tap('stuff', compilation => { 4 | compilation.hooks.afterOptimizeChunks.tap('EmbeddedContainerPlugin', chunks => { 5 | const chunkSet = new Map(); 6 | const externalRequests = new Set(); 7 | for (const chunk of chunks) { 8 | chunkSet.set(chunk.id || chunk.name, chunk); 9 | } 10 | // console.log(chunkSet) 11 | for (const chunk of chunks) { 12 | const remoteModules = compilation.chunkGraph.getChunkModulesIterableBySourceType( 13 | chunk, 14 | 'remote', 15 | ); 16 | if (!remoteModules) continue; 17 | for (const remoteModule of remoteModules) { 18 | remoteModule.dependencies.forEach(dep => { 19 | const mod = compilation.moduleGraph.getModule(dep); 20 | externalRequests.add(mod); 21 | const runtimeChunk = chunkSet.get(chunk.runtime); 22 | compilation.chunkGraph.connectChunkAndModule(runtimeChunk, mod); 23 | }); 24 | } 25 | } 26 | console.log(externalRequests); 27 | }); 28 | }); 29 | } 30 | } 31 | 32 | export {HoistContainerReferences} 33 | -------------------------------------------------------------------------------- /playground/utils/RemixAssetsManifestPlugin.js: -------------------------------------------------------------------------------- 1 | import {toManifest, writeManifest} from "./manifest.js"; 2 | 3 | class RemixAssetsManifestPlugin { 4 | constructor(remixConfig) { 5 | this.remixConfig = remixConfig; 6 | } 7 | /** 8 | * @param {import("webpack").Compiler} compiler 9 | */ 10 | apply(compiler) { 11 | compiler.hooks.emit.tapPromise( 12 | "RemixAssetsManifest", 13 | async (compilation) => { 14 | const stats = compilation.getStats(); 15 | const manifest = await toManifest(this.remixConfig, stats); 16 | writeManifest(this.remixConfig, manifest); 17 | } 18 | ); 19 | } 20 | } 21 | 22 | export {RemixAssetsManifestPlugin} 23 | -------------------------------------------------------------------------------- /playground/utils/get-exports.js: -------------------------------------------------------------------------------- 1 | import os from "os"; 2 | import esbuild from "esbuild"; 3 | 4 | export function getExports(routePath, remixConfig) { 5 | const { metafile, errors } = esbuild.buildSync({ 6 | sourceRoot: remixConfig.appDirectory, 7 | entryPoints: [routePath], 8 | target: "esnext", 9 | bundle: false, 10 | metafile: true, 11 | write: false, 12 | outdir: os.tmpdir(), 13 | }); 14 | if ((errors === null || errors === void 0 ? void 0 : errors.length) > 0) { 15 | throw new Error( 16 | esbuild.formatMessagesSync(errors, { kind: "error" }).join("\n") 17 | ); 18 | } 19 | const outputs = Object.values(metafile.outputs); 20 | if (outputs.length !== 1) { 21 | throw Error(); 22 | } 23 | const output = outputs[0]; 24 | return output.exports; 25 | } 26 | -------------------------------------------------------------------------------- /playground/utils/get-routes.js: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | 3 | export const routeSet = new Set(); 4 | export const getRoutes= (remixConfig)=> Object.fromEntries( 5 | Object.entries(remixConfig.routes).map(([key, route]) => { 6 | const fullPath = path.resolve(remixConfig.appDirectory, route.file); 7 | routeSet.add(fullPath); 8 | return [key, fullPath]; 9 | }) 10 | ); 11 | -------------------------------------------------------------------------------- /playground/utils/manifest.js: -------------------------------------------------------------------------------- 1 | import * as fs from "node:fs"; 2 | import * as path from "node:path"; 3 | 4 | import { getExports } from "./get-exports.js"; 5 | 6 | function createUrl(publicPath, file) { 7 | return ( 8 | publicPath.split(path.win32.sep).join("/") + 9 | (file || "").split(path.win32.sep).join("/") 10 | ); 11 | } 12 | 13 | /** 14 | * 15 | * @param {import("webpack").StatsCompilation} stats 16 | * @param {string} publicPath 17 | * @returns {(group: string) => string[]} 18 | */ 19 | function createNamedChunkGroupFactory(stats, publicPath) { 20 | const chunksById = new Map(stats.chunks?.map((chunk) => [chunk.id, chunk])); 21 | return (group) => { 22 | /** @type {Set} */ 23 | const files = new Set(); 24 | stats.namedChunkGroups?.[group].chunks?.forEach((chunkId) => { 25 | const chunk = chunksById.get(chunkId); 26 | chunk?.files?.forEach((file) => files.add(createUrl(publicPath, file))); 27 | }); 28 | return [...files]; 29 | }; 30 | } 31 | 32 | /** 33 | * @param {webpack.StatsCompilation} param0 34 | * @param {string} entrypointId 35 | */ 36 | const getAssets = ({ entrypoints }, entrypointId) => { 37 | if (entrypoints === undefined) throw Error("todo"); 38 | const { assets } = entrypoints[entrypointId]; 39 | if (assets === undefined) throw Error("todo"); 40 | return assets; 41 | }; 42 | 43 | /** 44 | * @param {import("@remix-run/dev").ResolvedRemixConfig} remixConfig 45 | * @param {import("webpack").Stats} stats 46 | * @returns {import("@remix-run/dev").AssetsManifest} 47 | */ 48 | export async function toManifest(remixConfig, stats) { 49 | const compilationStats = stats.toJson({ 50 | modules: true, 51 | entrypoints: true, 52 | assets: true, 53 | groupAssetsByChunk: true, 54 | hash: true, 55 | }); 56 | const getByNamedChunkGroup = createNamedChunkGroupFactory( 57 | compilationStats, 58 | remixConfig.publicPath 59 | ); 60 | 61 | const entryImports = getByNamedChunkGroup("entry.client"); 62 | const entryModule = createUrl( 63 | remixConfig.publicPath, 64 | getAssets(compilationStats, "entry.client").slice(-1)[0].name 65 | ); 66 | const rootImports = getByNamedChunkGroup("root"); 67 | 68 | // TODO: what are runtime imports? dynamic imports? 69 | // let runtimeImports = compilationStats.assetsByChunkName["runtime"].map( 70 | // (asset) => createUrl(remixConfig.publicPath, asset) 71 | // ); 72 | 73 | const routes = Object.fromEntries( 74 | Object.entries(remixConfig.routes).map(([routeId, route]) => { 75 | const assets = getAssets(compilationStats, routeId); 76 | const routeImports = assets 77 | .slice(0, -1) 78 | .map((asset) => createUrl(remixConfig.publicPath, asset.name)); 79 | const routeModule = createUrl( 80 | remixConfig.publicPath, 81 | assets.slice(-1)[0].name 82 | ); 83 | const routePath = path.resolve(remixConfig.appDirectory, route.file); 84 | const routeExports = getExports(routePath, remixConfig); 85 | return [ 86 | routeId, 87 | { 88 | id: route.id, 89 | parentId: route.parentId, 90 | path: route.path, 91 | index: route.index, 92 | caseSensitive: route.caseSensitive, 93 | module: routeModule, 94 | imports: routeImports, 95 | hasAction: routeExports.includes("action"), 96 | hasLoader: routeExports.includes("loader"), 97 | hasCatchBoundary: routeExports.includes("CatchBoundary"), 98 | hasErrorBoundary: routeExports.includes("ErrorBoundary"), 99 | }, 100 | ]; 101 | }) 102 | ); 103 | 104 | const version = compilationStats.hash; 105 | if (version === undefined) throw Error("todo"); 106 | return { 107 | version, 108 | url: createUrl( 109 | remixConfig.publicPath, 110 | `manifest-${version.toUpperCase()}.js` 111 | ), 112 | entry: { 113 | imports: [ 114 | ...new Set([/* ...runtimeImports, */ ...entryImports, ...rootImports]), 115 | ], 116 | module: entryModule, 117 | }, 118 | routes, 119 | }; 120 | } 121 | 122 | export function writeManifest(config, manifest) { 123 | fs.mkdirSync("./.cache", { recursive: true }); 124 | fs.writeFileSync( 125 | "./.cache/manifest.json", 126 | JSON.stringify(manifest, null, 2), 127 | "utf8" 128 | ); 129 | 130 | fs.mkdirSync(config.assetsBuildDirectory, { recursive: true }); 131 | fs.writeFileSync( 132 | path.resolve(config.assetsBuildDirectory, path.basename(manifest.url)), 133 | `window.__remixManifest=${JSON.stringify(manifest)};` 134 | ); 135 | } 136 | 137 | /** 138 | * @returns {import("@remix-run/dev").AssetsManifest} 139 | */ 140 | export function getManifest() { 141 | return JSON.parse(fs.readFileSync("./.cache/manifest.json", "utf8")); 142 | } 143 | -------------------------------------------------------------------------------- /playground/utils/server-build-entry.js: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | /** 3 | * 4 | * @param {import("@remix-run/dev").ResolvedRemixConfig} config 5 | * @param {import("@remix-run/dev").AssetsManifest} manifest 6 | * @returns 7 | */ 8 | export function createServerBuildEntry(config, manifest) { 9 | const routeImports = Object.values(config.routes).map((route, index) => { 10 | return `import * as route${index} from "${path 11 | .relative( 12 | path.resolve("./.cache"), 13 | path.resolve(config.appDirectory, route.file) 14 | ) 15 | .replace(/\\/g, "/")}";`; 16 | }); 17 | const routes = Object.entries(config.routes).map( 18 | ([routeId, route], index) => { 19 | return `${JSON.stringify(routeId)}: { 20 | id: ${JSON.stringify(route.id)}, 21 | parentId: ${JSON.stringify(route.parentId)}, 22 | path: ${JSON.stringify(route.path)}, 23 | index: ${JSON.stringify(route.index)}, 24 | caseSensitive: ${JSON.stringify(route.caseSensitive)}, 25 | module: route${index} 26 | }`; 27 | } 28 | ); 29 | 30 | return ` 31 | import * as entryServer from "${config.entryServerFilePath.replace( 32 | /\\/g, 33 | "/" 34 | )}"; 35 | ${routeImports.join("\n")} 36 | export const entry = { module: entryServer }; 37 | export const routes = { 38 | ${routes.join(",\n ")} 39 | }; 40 | export const assets = ${JSON.stringify(manifest)}; 41 | export const future = ${JSON.stringify(config.future)}; 42 | export const publicPath = ${JSON.stringify(config.publicPath)}; 43 | `; 44 | } 45 | `` -------------------------------------------------------------------------------- /playground/webpack.browser.js: -------------------------------------------------------------------------------- 1 | import * as path from "node:path"; 2 | 3 | import {readConfig} from "@remix-run/dev/dist/config.js"; 4 | import {toManifest, writeManifest} from "./utils/manifest.js"; 5 | import {getRoutes,routeSet} from './utils/get-routes.js' 6 | const mode = 7 | process.env.NODE_ENV === "production" ? "production" : "development"; 8 | const remixConfig = await readConfig(); 9 | 10 | 11 | /** 12 | * @type {import('webpack').Configuration} 13 | */ 14 | const config = { 15 | name: "browser", 16 | mode, 17 | devtool: mode === "development" ? "inline-cheap-source-map" : undefined, 18 | entry: { 19 | "entry.client": remixConfig.entryClientFilePath, 20 | ...getRoutes(remixConfig), 21 | }, 22 | externalsType: "module", 23 | experiments: { 24 | outputModule: true, 25 | topLevelAwait: true 26 | }, 27 | output: { 28 | // environment: { 29 | // module: true 30 | // }, 31 | path: remixConfig.assetsBuildDirectory, 32 | publicPath: 'auto', 33 | module: true, 34 | library: {type: "module"}, 35 | chunkFormat: "module", 36 | chunkLoading: "import", 37 | assetModuleFilename: "_assets/[name]-[contenthash][ext]", 38 | cssChunkFilename: "_assets/[name]-[contenthash][ext]", 39 | filename: "[name]-[contenthash].js", 40 | chunkFilename: "[name]-[contenthash].js", 41 | }, 42 | module: { 43 | rules: [ 44 | ], 45 | }, 46 | cache: false, 47 | optimization: { 48 | moduleIds: "named", 49 | runtimeChunk: "single", 50 | chunkIds: 'named', 51 | // treeshake unused code in development 52 | // needed so that browser build does not pull in server code 53 | usedExports: true, 54 | innerGraph: true, 55 | splitChunks: { 56 | chunks: "async", 57 | }, 58 | minimize: mode === "production", 59 | }, 60 | plugins: [ 61 | { 62 | /** 63 | * @param {import("webpack").Compiler} compiler 64 | */ 65 | apply(compiler) { 66 | compiler.hooks.emit.tapPromise( 67 | "RemixAssetsManifest", 68 | async (compilation) => { 69 | const stats = compilation.getStats(); 70 | const manifest = await toManifest(remixConfig, stats); 71 | writeManifest(remixConfig, manifest); 72 | } 73 | ); 74 | }, 75 | }, 76 | ], 77 | }; 78 | 79 | export default config; 80 | -------------------------------------------------------------------------------- /playground/webpack.server.js: -------------------------------------------------------------------------------- 1 | import * as fs from 'node:fs'; 2 | import * as path from 'node:path'; 3 | 4 | import { readConfig } from '@remix-run/dev/dist/config.js'; 5 | import nodeExternals from 'webpack-node-externals'; 6 | import { getManifest } from './utils/manifest.js'; 7 | import { createServerBuildEntry } from './utils/server-build-entry.js'; 8 | 9 | const mode = 10 | process.env.NODE_ENV === 'production' ? 'production' : 'development'; 11 | const remixConfig = await readConfig(); 12 | const isModule = remixConfig.serverModuleFormat === 'esm'; 13 | 14 | //TODO: add 15 | if (!isModule) { 16 | if (!fs.existsSync('./build')) { 17 | fs.mkdirSync('./build'); 18 | } 19 | fs.writeFileSync('./build/package.json', JSON.stringify({ type: 'commonjs' })); 20 | } 21 | 22 | const manifest = getManifest(); 23 | const serverBuildModule = './.cache/server-build.js'; 24 | const serverBuildEntry = createServerBuildEntry(remixConfig, manifest); 25 | fs.writeFileSync(serverBuildModule, serverBuildEntry, 'utf8'); 26 | 27 | 28 | /** 29 | * @type {import('webpack').Configuration} 30 | */ 31 | const config = { 32 | name: 'server', 33 | mode, 34 | devtool: mode === 'development' ? false : undefined, 35 | target: 'async-node', 36 | entry: remixConfig.serverEntryPoint 37 | ? path.resolve(remixConfig.rootDirectory, remixConfig.serverEntryPoint) 38 | : serverBuildModule, 39 | experiments: isModule ? { outputModule: true } : undefined, 40 | externalsType: isModule ? 'module' : undefined, 41 | externalsPresets: { node: true }, 42 | externals: [ 43 | nodeExternals({ 44 | allowlist: [/^@remix-run\/dev/], 45 | importType: isModule ? 'module' : 'commonjs' 46 | }) 47 | ], 48 | output: { 49 | filename: path.basename(remixConfig.serverBuildPath), 50 | library: { type: isModule ? 'module' : 'commonjs' }, 51 | chunkFormat: isModule ? 'module' : 'commonjs', 52 | chunkLoading: isModule ? 'import' : undefined, 53 | module: isModule, 54 | path: path.dirname(remixConfig.serverBuildPath), 55 | publicPath: remixConfig.publicPath, 56 | assetModuleFilename: '_assets/[name]-[contenthash][ext]', 57 | cssChunkFilename: '_assets/[name]-[contenthash][ext]', 58 | chunkFilename: '[name]-[chunkhash].js' 59 | }, 60 | optimization: { 61 | moduleIds: 'named' 62 | }, 63 | resolve: { 64 | alias: { 65 | '@remix-run/dev/server-build.js': serverBuildModule 66 | } 67 | }, 68 | module: { 69 | rules: [] 70 | }, 71 | plugins: [] 72 | }; 73 | 74 | export default config; 75 | -------------------------------------------------------------------------------- /src/RemixAssetsManifestPlugin.mjs: -------------------------------------------------------------------------------- 1 | import {toManifest, writeManifest} from "./manifest.mjs"; 2 | 3 | 4 | class RemixAssetsManifestPlugin { 5 | constructor(remixConfig) { 6 | this.remixConfig = remixConfig; 7 | } 8 | 9 | apply(compiler) { 10 | compiler.hooks.emit.tapPromise( 11 | "RemixAssetsManifest", 12 | async (compilation) => { 13 | const stats = compilation.getStats(); 14 | const manifest = await toManifest(this.remixConfig, stats); 15 | writeManifest(this.remixConfig, manifest); 16 | } 17 | ); 18 | } 19 | } 20 | 21 | export {RemixAssetsManifestPlugin} 22 | -------------------------------------------------------------------------------- /src/get-exports.mjs: -------------------------------------------------------------------------------- 1 | import os from "os"; 2 | import esbuild from "esbuild"; 3 | 4 | export function getExports(routePath, remixConfig) { 5 | const { metafile, errors } = esbuild.buildSync({ 6 | sourceRoot: remixConfig.appDirectory, 7 | entryPoints: [routePath], 8 | target: "esnext", 9 | bundle: false, 10 | metafile: true, 11 | write: false, 12 | outdir: os.tmpdir(), 13 | }); 14 | if ((errors === null || errors === void 0 ? void 0 : errors.length) > 0) { 15 | throw new Error( 16 | esbuild.formatMessagesSync(errors, { kind: "error" }).join("\n") 17 | ); 18 | } 19 | const outputs = Object.values(metafile.outputs); 20 | if (outputs.length !== 1) { 21 | throw Error(); 22 | } 23 | const output = outputs[0]; 24 | return output.exports; 25 | } 26 | -------------------------------------------------------------------------------- /src/get-routes.mjs: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | 3 | export const routeSet = new Set(); 4 | export function getRoutes(remixConfig) { 5 | return Object.fromEntries( 6 | Object.entries(remixConfig.routes).map(([key, route]) => { 7 | const fullPath = path.resolve(remixConfig.appDirectory, route.file); 8 | routeSet.add(fullPath); 9 | return [key, fullPath]; 10 | }) 11 | ); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /src/index.mjs: -------------------------------------------------------------------------------- 1 | // Import necessary modules 2 | import { setConfig } from '@rsbuild/shared'; // Import setConfig function from shared module 3 | import * as path from 'path'; // Node.js path module for handling and transforming file paths 4 | import * as fs from 'fs'; // Node.js file system module for interacting with the file system 5 | import { getRoutes } from './get-routes.mjs'; // Import getRoutes function from local module 6 | import { getManifest } from './manifest.mjs'; // Import getManifest function from local module 7 | import { RemixAssetsManifestPlugin } from './RemixAssetsManifestPlugin.mjs'; // Import RemixAssetsManifestPlugin from local module 8 | import { createServerBuildEntry } from '../playground/utils/server-build-entry.js'; // Import createServerBuildEntry function from utils 9 | import nodeExternals from 'webpack-node-externals'; // Import nodeExternals function from webpack-node-externals module 10 | 11 | // Define server build module 12 | const serverBuildModule = './.cache/server-build.js'; // Define the path for the server build module 13 | 14 | // Export pluginFoo 15 | export const pluginFoo = (remixOptions = {}) => ({ // Export a function that returns an object 16 | name: 'plugin-foo', // Name of the plugin 17 | 18 | setup(api, options) { // Setup function for the plugin 19 | api.onAfterBuild(async (config,options) => { // Event listener for after build event 20 | const remixConfig = await remixOptions; // Await the remixOptions promise 21 | const isModule = remixConfig.serverModuleFormat === 'esm'; // Check if the server module format is 'esm' 22 | 23 | // Check if the target includes 'node' or 'async-node' 24 | if (api.context.target.includes('node') || api.context.target.includes('async-node')) { 25 | 26 | // If the server module format is not 'esm' 27 | if (!isModule) { 28 | const dirname = path.dirname(remixConfig.serverBuildPath) // Get the directory name of the server build path 29 | // If the directory does not exist, create it 30 | if (!fs.existsSync(dirname)) { 31 | fs.mkdirSync(dirname); 32 | } 33 | // Write a package.json file in the directory with type set to 'commonjs' 34 | fs.writeFileSync(path.join(dirname,'package.json'), JSON.stringify({ type: 'commonjs' })); 35 | } 36 | } 37 | }); 38 | 39 | api.modifyRsbuildConfig(async (config, options) => { // Modify the Rsbuild config 40 | const remixConfig = await remixOptions; // Await the remixOptions promise 41 | // Check if the target includes 'node' or 'async-node' 42 | if (api.context.target.includes('node') || api.context.target.includes('async-node')) { 43 | const serverBuildPathDir = path.dirname(remixConfig.serverBuildPath); // Get the directory name of the server build path 44 | setConfig(config, 'output.distPath.root', serverBuildPathDir); // Set the root of the output distPath to the server build path directory 45 | setConfig(config, 'source.alias[\'@remix-run/dev/server-build.js\']', serverBuildModule); // Set the alias for '@remix-run/dev/server-build.js' to the server build module 46 | const manifest = getManifest(); // Get the manifest 47 | const serverBuildEntry = createServerBuildEntry(remixConfig, manifest); // Create the server build entry 48 | fs.writeFileSync(serverBuildModule, serverBuildEntry, 'utf8'); // Write the server build entry to the server build module 49 | } else { 50 | // Set the entry points for the config 51 | setConfig(config, 'source.entry', { 52 | 'entry.client': remixConfig.entryClientFilePath, // Set the client entry point to the entry client file path 53 | ...getRoutes(remixConfig) // Spread the routes from the remix config 54 | }) 55 | setConfig(config, 'output.distPath.root', remixConfig.assetsBuildDirectory); // Set the root of the output distPath to the assets build directory 56 | } 57 | return config; // Return the modified config 58 | }); 59 | 60 | api.modifyRspackConfig(async (config, options) => { // Modify the Rspack config 61 | const remixConfig = await remixOptions; // Await the remixOptions promise 62 | const isModule = remixConfig.serverModuleFormat === 'esm'; // Check if the server module format is 'esm' 63 | if (!options.isServer) { // If the options do not include 'isServer' 64 | setConfig(config, 'target', 'web'); // Set the target to 'web' 65 | setConfig(config, 'name', 'browser'); // Set the name to 'browser' 66 | setConfig(config, 'output.publicPath', remixConfig.publicPath || 'auto'); // Set the public path to the remix config public path or 'auto' if it does not exist 67 | 68 | // Rspack HMR do not support module chunk format yet 69 | // ref: https://github.com/web-infra-dev/rspack/blob/37ba8d745312c05bf81ae3a1e21a19f503dcd010/crates/rspack_plugin_runtime/src/module_chunk_format.rs#L95-L97 70 | // setConfig(config, 'output.module', true); // Set the output module to true 71 | // setConfig(config, 'output.library', { type: 'module' }); // Set the output library type to 'module' 72 | // setConfig(config, 'output.chunkFormat', 'module'); // Set the output chunk format to 'module' 73 | // setConfig(config, 'output.chunkLoading', 'import'); // Set the output chunk loading to 'import' 74 | // setConfig(config, 'experiments.outputModule', true); // Set the experiments output module to true 75 | // setConfig(config, 'externalsType', 'module'); // Set the externals type to 'module' 76 | 77 | setConfig(config, 'output.assetModuleFilename', '_assets/[name]-[contenthash][ext]'); // Set the output asset module filename 78 | setConfig(config, 'output.cssChunkFilename', '_assets/[name]-[contenthash].css'); // Set the output CSS chunk filename 79 | setConfig(config, 'output.filename', '[name]-[contenthash].js'); // Set the output filename 80 | setConfig(config, 'output.chunkFilename', '[name]-[contenthash].js'); // Set the output chunk filename 81 | config.plugins.push(new RemixAssetsManifestPlugin(remixConfig)); // Push a new instance of RemixAssetsManifestPlugin to the plugins array 82 | } else { 83 | const ext = isModule ? 'mjs' : 'js'; // Set the extension to 'mjs' if the server module format is 'esm', otherwise set it to 'js' 84 | setConfig(config, 'name', 'server'); // Set the name to 'server' 85 | setConfig(config, 'output.filename', path.basename(remixConfig.serverBuildPath, path.extname(remixConfig.serverBuildPath)) + '.' + ext); // Set the output filename 86 | setConfig(config, 'output.library', { type: isModule ? 'module' : 'commonjs' }); // Set the output library type to 'module' if the server module format is 'esm', otherwise set it to 'commonjs' 87 | setConfig(config, 'output.libraryTarget', isModule ? 'module' : 'commonjs2' ); // Set the output library target to 'module' if the server module format is 'esm', otherwise set it to 'commonjs2' 88 | setConfig(config, 'output.chunkFormat', isModule ? 'module' : 'commonjs'); // Set the output chunk format to 'module' if the server module format is 'esm', otherwise set it to 'commonjs' 89 | setConfig(config, 'output.chunkLoading', isModule ? 'import' : undefined); // Set the output chunk loading to 'import' if the server module format is 'esm', otherwise set it to undefined 90 | setConfig(config, 'output.module', isModule); // Set the output module to the value of isModule 91 | setConfig(config, 'output.publicPath', remixConfig.publicPath); // Set the public path to the remix config public path 92 | setConfig(config, 'output.assetModuleFilename', '_assets/[name]-[contenthash][ext]'); // Set the output asset module filename 93 | setConfig(config, 'output.cssChunkFilename', '_assets/[name]-[contenthash].css'); // Set the output CSS chunk filename 94 | setConfig(config, 'output.chunkFilename', '[name]-[chunkhash].' + ext); // Set the output chunk filename 95 | setConfig(config, 'externals', [ // Set the externals 96 | nodeExternals({ // Use the nodeExternals function 97 | allowlist: [/^@remix-run\/dev/], // Allowlist '@remix-run/dev' 98 | importType: isModule ? 'module' : 'commonjs' // Set the import type to 'module' if the server module format is 'esm', otherwise set it to 'commonjs' 99 | }) 100 | ]); 101 | setConfig(config, 'externalsType', isModule ? 'module' : undefined); // Set the externals type to 'module' if the server module format is 'esm', otherwise set it to undefined 102 | setConfig(config, 'externalsPresets', { node: true }); // Set the externals presets to { node: true } 103 | if (isModule) setConfig(config, 'experiments.outputModule', isModule); // If the server module format is 'esm', set the experiments output module to true 104 | config.entry = remixConfig.serverEntryPoint || serverBuildModule; // Set the entry to the server entry point or the server build module if the server entry point does not exist 105 | } 106 | return config; // Return the modified config 107 | }); 108 | } 109 | }); 110 | 111 | -------------------------------------------------------------------------------- /src/manifest.mjs: -------------------------------------------------------------------------------- 1 | import * as fs from "node:fs"; 2 | import * as path from "node:path"; 3 | 4 | import { getExports } from "./get-exports.mjs"; 5 | 6 | function createUrl(publicPath, file) { 7 | return ( 8 | publicPath.split(path.win32.sep).join("/") + 9 | (file || "").split(path.win32.sep).join("/") 10 | ); 11 | } 12 | 13 | /** 14 | * 15 | * @param {import("webpack").StatsCompilation} stats 16 | * @param {string} publicPath 17 | * @returns {(group: string) => string[]} 18 | */ 19 | function createNamedChunkGroupFactory(stats, publicPath) { 20 | const chunksById = new Map(stats.chunks?.map((chunk) => [chunk.id, chunk])); 21 | return (group) => { 22 | /** @type {Set} */ 23 | const files = new Set(); 24 | stats.namedChunkGroups?.[group].chunks?.forEach((chunkId) => { 25 | const chunk = chunksById.get(chunkId); 26 | chunk?.files?.forEach((file) => files.add(createUrl(publicPath, file))); 27 | }); 28 | return [...files]; 29 | }; 30 | } 31 | 32 | /** 33 | * @param {webpack.StatsCompilation} param0 34 | * @param {string} entrypointId 35 | */ 36 | const getAssets = ({ entrypoints }, entrypointId) => { 37 | if (entrypoints === undefined) throw Error("todo"); 38 | const { assets } = entrypoints[entrypointId]; 39 | if (assets === undefined) throw Error("todo"); 40 | return assets; 41 | }; 42 | 43 | /** 44 | * @param {import("@remix-run/dev").ResolvedRemixConfig} remixConfig 45 | * @param {import("webpack").Stats} stats 46 | * @returns {import("@remix-run/dev").AssetsManifest} 47 | */ 48 | export async function toManifest(remixConfig, stats) { 49 | const compilationStats = stats.toJson({ 50 | modules: true, 51 | entrypoints: true, 52 | assets: true, 53 | groupAssetsByChunk: true, 54 | hash: true, 55 | }); 56 | const getByNamedChunkGroup = createNamedChunkGroupFactory( 57 | compilationStats, 58 | remixConfig.publicPath 59 | ); 60 | 61 | const entryImports = getByNamedChunkGroup("entry.client"); 62 | const entryModule = createUrl( 63 | remixConfig.publicPath, 64 | getAssets(compilationStats, "entry.client").slice(-1)[0].name 65 | ); 66 | const rootImports = getByNamedChunkGroup("root"); 67 | 68 | // TODO: what are runtime imports? dynamic imports? 69 | // let runtimeImports = compilationStats.assetsByChunkName["runtime"].map( 70 | // (asset) => createUrl(remixConfig.publicPath, asset) 71 | // ); 72 | 73 | const routes = Object.fromEntries( 74 | Object.entries(remixConfig.routes).map(([routeId, route]) => { 75 | const assets = getAssets(compilationStats, routeId); 76 | const routeImports = assets 77 | .slice(0, -1) 78 | .map((asset) => createUrl(remixConfig.publicPath, asset.name)); 79 | const routeModule = createUrl( 80 | remixConfig.publicPath, 81 | assets.slice(-1)[0].name 82 | ); 83 | const routePath = path.resolve(remixConfig.appDirectory, route.file); 84 | const routeExports = getExports(routePath, remixConfig); 85 | return [ 86 | routeId, 87 | { 88 | id: route.id, 89 | parentId: route.parentId, 90 | path: route.path, 91 | index: route.index, 92 | caseSensitive: route.caseSensitive, 93 | module: routeModule, 94 | imports: routeImports, 95 | hasAction: routeExports.includes("action"), 96 | hasLoader: routeExports.includes("loader"), 97 | hasCatchBoundary: routeExports.includes("CatchBoundary"), 98 | hasErrorBoundary: routeExports.includes("ErrorBoundary"), 99 | }, 100 | ]; 101 | }) 102 | ); 103 | 104 | const version = compilationStats.hash; 105 | if (version === undefined) throw Error("todo"); 106 | return { 107 | version, 108 | url: createUrl( 109 | remixConfig.publicPath, 110 | `manifest-${version.toUpperCase()}.js` 111 | ), 112 | entry: { 113 | imports: [ 114 | ...new Set([/* ...runtimeImports, */ ...entryImports, ...rootImports]), 115 | ], 116 | module: entryModule, 117 | }, 118 | routes, 119 | }; 120 | } 121 | 122 | export function writeManifest(config, manifest) { 123 | fs.mkdirSync("./.cache", { recursive: true }); 124 | fs.writeFileSync( 125 | "./.cache/manifest.json", 126 | JSON.stringify(manifest, null, 2), 127 | "utf8" 128 | ); 129 | 130 | fs.mkdirSync(config.assetsBuildDirectory, { recursive: true }); 131 | fs.writeFileSync( 132 | path.resolve(config.assetsBuildDirectory, path.basename(manifest.url)), 133 | `window.__remixManifest=${JSON.stringify(manifest)};` 134 | ); 135 | } 136 | 137 | /** 138 | * @returns {import("@remix-run/dev").AssetsManifest} 139 | */ 140 | export function getManifest() { 141 | return JSON.parse(fs.readFileSync("./.cache/manifest.json", "utf8")); 142 | } 143 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist", 4 | "baseUrl": "./", 5 | "target": "ES2019", 6 | "lib": ["ESNext"], 7 | "allowJs": true, 8 | "module": "Node16", 9 | "strict": true, 10 | "declaration": true, 11 | "isolatedModules": true, 12 | "esModuleInterop": true, 13 | "skipLibCheck": true, 14 | "jsx": "preserve", 15 | "resolveJsonModule": true, 16 | "moduleResolution": "Node16" 17 | }, 18 | "include": ["src"] 19 | } 20 | --------------------------------------------------------------------------------