From df73f8fd254a273acfba9201f69071f83779b10a Mon Sep 17 00:00:00 2001 From: Dylan Staley <88163+dstaley@users.noreply.github.com> Date: Tue, 2 Dec 2025 11:16:17 -0600 Subject: [PATCH 1/2] fix(clerk-js): Dynamically load Web3WalletButtons --- packages/clerk-js/bundlewatch.config.json | 8 ++-- packages/clerk-js/rspack.config.js | 25 +++++++++++- .../SignInFactorOneSolanaWalletsCard.tsx | 37 ++++++++++------- .../SignUp/SignUpStartSolanaWalletsCard.tsx | 40 +++++++++++-------- 4 files changed, 72 insertions(+), 38 deletions(-) diff --git a/packages/clerk-js/bundlewatch.config.json b/packages/clerk-js/bundlewatch.config.json index 509aa6dfaba..44d4dab338d 100644 --- a/packages/clerk-js/bundlewatch.config.json +++ b/packages/clerk-js/bundlewatch.config.json @@ -1,11 +1,11 @@ { "files": [ - { "path": "./dist/clerk.js", "maxSize": "840KB" }, + { "path": "./dist/clerk.js", "maxSize": "918KB" }, { "path": "./dist/clerk.browser.js", "maxSize": "81KB" }, { "path": "./dist/clerk.channel.browser.js", "maxSize": "81KB" }, { "path": "./dist/clerk.legacy.browser.js", "maxSize": "123KB" }, { "path": "./dist/clerk.headless*.js", "maxSize": "65KB" }, - { "path": "./dist/ui-common*.js", "maxSize": "117.1KB" }, + { "path": "./dist/ui-common*.js", "maxSize": "119KB" }, { "path": "./dist/ui-common*.legacy.*.js", "maxSize": "122KB" }, { "path": "./dist/vendors*.js", "maxSize": "47KB" }, { "path": "./dist/coinbase*.js", "maxSize": "38KB" }, @@ -16,11 +16,11 @@ { "path": "./dist/organizationswitcher*.js", "maxSize": "5KB" }, { "path": "./dist/organizationlist*.js", "maxSize": "5.5KB" }, { "path": "./dist/signin*.js", "maxSize": "18KB" }, - { "path": "./dist/signup*.js", "maxSize": "9.5KB" }, + { "path": "./dist/signup*.js", "maxSize": "11KB" }, { "path": "./dist/userbutton*.js", "maxSize": "5KB" }, { "path": "./dist/userprofile*.js", "maxSize": "16KB" }, { "path": "./dist/userverification*.js", "maxSize": "5KB" }, - { "path": "./dist/onetap*.js", "maxSize": "1KB" }, + { "path": "./dist/onetap*.js", "maxSize": "3KB" }, { "path": "./dist/waitlist*.js", "maxSize": "1.5KB" }, { "path": "./dist/keylessPrompt*.js", "maxSize": "6.5KB" }, { "path": "./dist/pricingTable*.js", "maxSize": "4.02KB" }, diff --git a/packages/clerk-js/rspack.config.js b/packages/clerk-js/rspack.config.js index 18e842bb3d5..5583da52086 100644 --- a/packages/clerk-js/rspack.config.js +++ b/packages/clerk-js/rspack.config.js @@ -129,19 +129,40 @@ const common = ({ mode, variant, disableRHC = false }) => { signUp: { minChunks: 1, name: 'signup', - test: module => !!(module.resource && module.resource.includes('/ui/components/SignUp')), + test: module => + !!( + module instanceof rspack.NormalModule && + module.resource && + module.resource.includes('/ui/components/SignUp') + ), }, common: { minChunks: 1, name: 'ui-common', priority: -20, - test: module => !!(module.resource && !module.resource.includes('/ui/components')), + test: module => + !!( + module instanceof rspack.NormalModule && + module.resource && + !module.resource.includes('/ui/components') && + !module.resource.includes('node_modules') + ), }, defaultVendors: { minChunks: 1, test: /[\\/]node_modules[\\/]/, name: 'vendors', priority: -10, + /** + * Only apply to initial chunks. Dependencies used exclusively by async chunks + * (like Solana packages and their transitive deps) will be bundled with those + * async chunks instead of being forced into the shared vendors bundle. + * + * This ensures that lazy-loaded features (like Web3 wallet support) don't + * bloat the initial bundle, and their dependencies are automatically + * code-split without needing explicit configuration. + */ + chunks: 'initial', }, react: { chunks: 'all', diff --git a/packages/clerk-js/src/ui/components/SignIn/SignInFactorOneSolanaWalletsCard.tsx b/packages/clerk-js/src/ui/components/SignIn/SignInFactorOneSolanaWalletsCard.tsx index e5049bff82c..b0f8930a487 100644 --- a/packages/clerk-js/src/ui/components/SignIn/SignInFactorOneSolanaWalletsCard.tsx +++ b/packages/clerk-js/src/ui/components/SignIn/SignInFactorOneSolanaWalletsCard.tsx @@ -1,4 +1,5 @@ import { useClerk } from '@clerk/shared/react'; +import { lazy, Suspense } from 'react'; import { withRedirectToAfterSignIn, withRedirectToSignInTask } from '@/ui/common/withRedirect'; import { descriptors, Flex, Flow, localizationKeys } from '@/ui/customizables'; @@ -6,9 +7,12 @@ import { BackLink } from '@/ui/elements/BackLink'; import { Card } from '@/ui/elements/Card'; import { useCardState, withCardStateProvider } from '@/ui/elements/contexts'; import { Header } from '@/ui/elements/Header'; -import { Web3WalletButtons } from '@/ui/elements/Web3WalletButtons'; import { web3CallbackErrorHandler } from '@/ui/utils/web3CallbackErrorHandler'; +const Web3WalletButtons = lazy(() => + import('@/ui/elements/Web3WalletButtons').then(m => ({ default: m.Web3WalletButtons })), +); + import { useSignInContext } from '../../contexts'; import { useRouter } from '../../router'; @@ -35,20 +39,23 @@ const SignInFactorOneSolanaWalletsCardInner = () => { direction='col' gap={4} > - { - return clerk - .authenticateWithWeb3({ - customNavigate: router.navigate, - redirectUrl: ctx.afterSignInUrl || '/', - secondFactorUrl: 'factor-two', - signUpContinueUrl: ctx.isCombinedFlow ? '../create/continue' : ctx.signUpContinueUrl, - strategy: 'web3_solana_signature', - walletName, - }) - .catch(err => web3CallbackErrorHandler(err, card.setError)); - }} - /> + + { + return clerk + .authenticateWithWeb3({ + customNavigate: router.navigate, + redirectUrl: ctx.afterSignInUrl || '/', + secondFactorUrl: 'factor-two', + signUpContinueUrl: ctx.isCombinedFlow ? '../create/continue' : ctx.signUpContinueUrl, + strategy: 'web3_solana_signature', + walletName, + }) + .catch(err => web3CallbackErrorHandler(err, card.setError)); + }} + /> + + + import('@/ui/elements/Web3WalletButtons').then(m => ({ default: m.Web3WalletButtons })), +); + import { useSignUpContext } from '../../contexts'; import { useRouter } from '../../router'; @@ -35,22 +39,24 @@ const SignUpStartSolanaWalletsCardInner = () => { direction='col' gap={4} > - { - return clerk - .authenticateWithWeb3({ - customNavigate: router.navigate, - redirectUrl: ctx.afterSignUpUrl || '/', - signUpContinueUrl: '../continue', - strategy: 'web3_solana_signature', - unsafeMetadata: ctx.unsafeMetadata, - // TODO: Add support to pass legalAccepted status - // legalAccepted: , - walletName, - }) - .catch(err => web3CallbackErrorHandler(err, card.setError)); - }} - /> + + { + return clerk + .authenticateWithWeb3({ + customNavigate: router.navigate, + redirectUrl: ctx.afterSignUpUrl || '/', + signUpContinueUrl: '../continue', + strategy: 'web3_solana_signature', + unsafeMetadata: ctx.unsafeMetadata, + // TODO: Add support to pass legalAccepted status + // legalAccepted: , + walletName, + }) + .catch(err => web3CallbackErrorHandler(err, card.setError)); + }} + /> + Date: Tue, 2 Dec 2025 12:57:21 -0600 Subject: [PATCH 2/2] fix(clerk-js): Fix chunk loading --- packages/clerk-js/bundle-check.mjs | 4 +-- packages/clerk-js/bundlewatch.config.json | 8 +++--- packages/clerk-js/rspack.config.js | 25 +++++++++++-------- .../SignInFactorOneSolanaWalletsCard.tsx | 4 ++- .../SignUp/SignUpStartSolanaWalletsCard.tsx | 4 ++- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/packages/clerk-js/bundle-check.mjs b/packages/clerk-js/bundle-check.mjs index b3058837813..ee31203690a 100644 --- a/packages/clerk-js/bundle-check.mjs +++ b/packages/clerk-js/bundle-check.mjs @@ -5,7 +5,7 @@ import path from 'node:path'; import { pipeline } from 'node:stream'; import zlib from 'node:zlib'; -import { chromium } from 'playwright'; +import { chromium } from '@playwright/test'; /** * This script generates a CLI report detailing the gzipped size of JavaScript resources loaded by `clerk-js` for a @@ -212,7 +212,7 @@ function report(url, responses) { /** * Loads the given `url` in `browser`, capturing all HTTP requests that occur. - * @param {import('playwright').Browser} browser + * @param {import('@playwright/test').Browser} browser * @param {string} url */ async function getResponseSizes(browser, url) { diff --git a/packages/clerk-js/bundlewatch.config.json b/packages/clerk-js/bundlewatch.config.json index 44d4dab338d..8c4f108d52b 100644 --- a/packages/clerk-js/bundlewatch.config.json +++ b/packages/clerk-js/bundlewatch.config.json @@ -1,13 +1,13 @@ { "files": [ { "path": "./dist/clerk.js", "maxSize": "918KB" }, - { "path": "./dist/clerk.browser.js", "maxSize": "81KB" }, - { "path": "./dist/clerk.channel.browser.js", "maxSize": "81KB" }, - { "path": "./dist/clerk.legacy.browser.js", "maxSize": "123KB" }, + { "path": "./dist/clerk.browser.js", "maxSize": "84KB" }, + { "path": "./dist/clerk.channel.browser.js", "maxSize": "85KB" }, + { "path": "./dist/clerk.legacy.browser.js", "maxSize": "125KB" }, { "path": "./dist/clerk.headless*.js", "maxSize": "65KB" }, { "path": "./dist/ui-common*.js", "maxSize": "119KB" }, { "path": "./dist/ui-common*.legacy.*.js", "maxSize": "122KB" }, - { "path": "./dist/vendors*.js", "maxSize": "47KB" }, + { "path": "./dist/vendors*.js", "maxSize": "50KB" }, { "path": "./dist/coinbase*.js", "maxSize": "38KB" }, { "path": "./dist/stripe-vendors*.js", "maxSize": "1KB" }, { "path": "./dist/createorganization*.js", "maxSize": "5KB" }, diff --git a/packages/clerk-js/rspack.config.js b/packages/clerk-js/rspack.config.js index 5583da52086..b05305035e9 100644 --- a/packages/clerk-js/rspack.config.js +++ b/packages/clerk-js/rspack.config.js @@ -150,19 +150,22 @@ const common = ({ mode, variant, disableRHC = false }) => { }, defaultVendors: { minChunks: 1, - test: /[\\/]node_modules[\\/]/, + test: module => { + if (!(module instanceof rspack.NormalModule) || !module.resource) { + return false; + } + // Exclude Solana packages and their known transitive dependencies + if ( + /[\\/]node_modules[\\/](@solana|@solana-mobile|@wallet-standard|bn\.js|borsh|buffer|superstruct|bs58|jayson|rpc-websockets|qrcode)[\\/]/.test( + module.resource, + ) + ) { + return false; + } + return /[\\/]node_modules[\\/]/.test(module.resource); + }, name: 'vendors', priority: -10, - /** - * Only apply to initial chunks. Dependencies used exclusively by async chunks - * (like Solana packages and their transitive deps) will be bundled with those - * async chunks instead of being forced into the shared vendors bundle. - * - * This ensures that lazy-loaded features (like Web3 wallet support) don't - * bloat the initial bundle, and their dependencies are automatically - * code-split without needing explicit configuration. - */ - chunks: 'initial', }, react: { chunks: 'all', diff --git a/packages/clerk-js/src/ui/components/SignIn/SignInFactorOneSolanaWalletsCard.tsx b/packages/clerk-js/src/ui/components/SignIn/SignInFactorOneSolanaWalletsCard.tsx index b0f8930a487..187191216e0 100644 --- a/packages/clerk-js/src/ui/components/SignIn/SignInFactorOneSolanaWalletsCard.tsx +++ b/packages/clerk-js/src/ui/components/SignIn/SignInFactorOneSolanaWalletsCard.tsx @@ -10,7 +10,9 @@ import { Header } from '@/ui/elements/Header'; import { web3CallbackErrorHandler } from '@/ui/utils/web3CallbackErrorHandler'; const Web3WalletButtons = lazy(() => - import('@/ui/elements/Web3WalletButtons').then(m => ({ default: m.Web3WalletButtons })), + import(/* webpackChunkName: "web3-wallet-buttons" */ '@/ui/elements/Web3WalletButtons').then(m => ({ + default: m.Web3WalletButtons, + })), ); import { useSignInContext } from '../../contexts'; diff --git a/packages/clerk-js/src/ui/components/SignUp/SignUpStartSolanaWalletsCard.tsx b/packages/clerk-js/src/ui/components/SignUp/SignUpStartSolanaWalletsCard.tsx index ded066fc0e4..6c1f327035a 100644 --- a/packages/clerk-js/src/ui/components/SignUp/SignUpStartSolanaWalletsCard.tsx +++ b/packages/clerk-js/src/ui/components/SignUp/SignUpStartSolanaWalletsCard.tsx @@ -10,7 +10,9 @@ import { Header } from '@/ui/elements/Header'; import { web3CallbackErrorHandler } from '@/ui/utils/web3CallbackErrorHandler'; const Web3WalletButtons = lazy(() => - import('@/ui/elements/Web3WalletButtons').then(m => ({ default: m.Web3WalletButtons })), + import(/* webpackChunkName: "web3-wallet-buttons" */ '@/ui/elements/Web3WalletButtons').then(m => ({ + default: m.Web3WalletButtons, + })), ); import { useSignUpContext } from '../../contexts';