Skip to content

Commit 6f4cf71

Browse files
dstaleyjacekradkoalexcarpenter
authored
feat(clerk-js): Introduce legacy browser variant (#5495)
Co-authored-by: Jacek Radko <[email protected]> Co-authored-by: Alex Carpenter <[email protected]>
1 parent 62a1c54 commit 6f4cf71

File tree

7 files changed

+178
-77
lines changed

7 files changed

+178
-77
lines changed

.changeset/social-pandas-return.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/clerk-js': minor
3+
---
4+
5+
Introduce `clerk.legacy.browser.js` for legacy browser support.

packages/clerk-js/bundlewatch.config.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,25 @@
33
{ "path": "./dist/clerk.js", "maxSize": "593kB" },
44
{ "path": "./dist/clerk.browser.js", "maxSize": "74.2KB" },
55
{ "path": "./dist/clerk.headless*.js", "maxSize": "55KB" },
6-
{ "path": "./dist/ui-common*.js", "maxSize": "100KB" },
7-
{ "path": "./dist/vendors*.js", "maxSize": "36KB" },
8-
{ "path": "./dist/coinbase*.js", "maxSize": "35.5KB" },
6+
{ "path": "./dist/ui-common*.js", "maxSize": "102KB" },
7+
{ "path": "./dist/vendors*.js", "maxSize": "39KB" },
8+
{ "path": "./dist/coinbase*.js", "maxSize": "38KB" },
99
{ "path": "./dist/createorganization*.js", "maxSize": "5KB" },
1010
{ "path": "./dist/impersonationfab*.js", "maxSize": "5KB" },
1111
{ "path": "./dist/organizationprofile*.js", "maxSize": "12KB" },
1212
{ "path": "./dist/organizationswitcher*.js", "maxSize": "5KB" },
1313
{ "path": "./dist/organizationlist*.js", "maxSize": "5.5KB" },
14-
{ "path": "./dist/signin*.js", "maxSize": "12.5KB" },
14+
{ "path": "./dist/signin*.js", "maxSize": "14KB" },
1515
{ "path": "./dist/signup*.js", "maxSize": "6.75KB" },
1616
{ "path": "./dist/userbutton*.js", "maxSize": "5KB" },
1717
{ "path": "./dist/userprofile*.js", "maxSize": "16KB" },
1818
{ "path": "./dist/userverification*.js", "maxSize": "5KB" },
1919
{ "path": "./dist/onetap*.js", "maxSize": "1KB" },
2020
{ "path": "./dist/waitlist*.js", "maxSize": "1.3KB" },
21-
{ "path": "./dist/keylessPrompt*.js", "maxSize": "5.9KB" },
22-
{ "path": "./dist/pricingTable*.js", "maxSize": "5.28KB" },
21+
{ "path": "./dist/keylessPrompt*.js", "maxSize": "6.5KB" },
22+
{ "path": "./dist/pricingTable*.js", "maxSize": "5.5KB" },
2323
{ "path": "./dist/checkout*.js", "maxSize": "3.05KB" },
24-
{ "path": "./dist/paymentSources*.js", "maxSize": "8.2KB" },
24+
{ "path": "./dist/paymentSources*.js", "maxSize": "8.5KB" },
2525
{ "path": "./dist/up-billing-page*.js", "maxSize": "2.5KB" },
2626
{ "path": "./dist/op-billing-page*.js", "maxSize": "2.5KB" },
2727
{ "path": "./dist/sessionTasks*.js", "maxSize": "1KB" }

packages/clerk-js/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
"test:coverage": "jest --collectCoverage && open coverage/lcov-report/index.html",
5353
"watch": "rspack build --config rspack.config.js --env production --watch"
5454
},
55-
"browserslist": "last 2 years, Safari > 12, iOS > 12",
55+
"browserslist": "last 2 years",
5656
"dependencies": {
5757
"@clerk/localizations": "workspace:^",
5858
"@clerk/shared": "workspace:^",
@@ -70,7 +70,7 @@
7070
"@zxcvbn-ts/language-common": "3.0.4",
7171
"browser-tabs-lock": "1.2.15",
7272
"copy-to-clipboard": "3.3.3",
73-
"core-js": "3.26.1",
73+
"core-js": "3.41.0",
7474
"crypto-js": "^4.2.0",
7575
"dequal": "2.0.3",
7676
"qrcode.react": "3.1.0",
@@ -94,5 +94,6 @@
9494
},
9595
"publishConfig": {
9696
"access": "public"
97-
}
97+
},
98+
"browserslistLegacy": "Chrome > 73, Firefox > 66, Safari > 12, iOS > 12, Edge > 18, Opera > 58"
9899
}

packages/clerk-js/rspack.config.js

Lines changed: 117 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const variants = {
1515
clerkBrowser: 'clerk.browser',
1616
clerkHeadless: 'clerk.headless',
1717
clerkHeadlessBrowser: 'clerk.headless.browser',
18+
clerkLegacyBrowser: 'clerk.legacy.browser',
1819
};
1920

2021
const variantToSourceFile = {
@@ -23,16 +24,18 @@ const variantToSourceFile = {
2324
[variants.clerkBrowser]: './src/index.browser.ts',
2425
[variants.clerkHeadless]: './src/index.headless.ts',
2526
[variants.clerkHeadlessBrowser]: './src/index.headless.browser.ts',
27+
[variants.clerkLegacyBrowser]: './src/index.legacy.browser.ts',
2628
};
2729

2830
/**
2931
*
3032
* @param {object} config
3133
* @param {'development'|'production'} config.mode
34+
* @param {string} config.variant
3235
* @param {boolean} [config.disableRHC=false]
3336
* @returns { import('@rspack/cli').Configuration }
3437
*/
35-
const common = ({ mode, disableRHC = false }) => {
38+
const common = ({ mode, variant, disableRHC = false }) => {
3639
return {
3740
mode,
3841
resolve: {
@@ -65,7 +68,7 @@ const common = ({ mode, disableRHC = false }) => {
6568
}),
6669
].filter(Boolean),
6770
output: {
68-
chunkFilename: `[name]_[fullhash:6]_${packageJSON.version}.js`,
71+
chunkFilename: `[name]_${variant}_[fullhash:6]_${packageJSON.version}.js`,
6972
},
7073
/**
7174
* Remove the Stripe dependencies from the bundle, if RHC is disabled.
@@ -156,8 +159,10 @@ const svgLoader = () => {
156159
};
157160
};
158161

159-
/** @type { () => (import('@rspack/core').RuleSetRule[]) } */
160-
const typescriptLoaderProd = () => {
162+
/** @type { (opts?: { targets?: string, useCoreJs?: boolean }) => (import('@rspack/core').RuleSetRule[]) } */
163+
const typescriptLoaderProd = (
164+
{ targets = packageJSON.browserslist, useCoreJs = false } = { targets: packageJSON.browserslist, useCoreJs: false },
165+
) => {
161166
return [
162167
{
163168
test: /\.(jsx?|tsx?)$/,
@@ -166,7 +171,13 @@ const typescriptLoaderProd = () => {
166171
loader: 'builtin:swc-loader',
167172
options: {
168173
env: {
169-
targets: packageJSON.browserslist,
174+
targets,
175+
...(useCoreJs
176+
? {
177+
mode: 'usage',
178+
coreJs: require('core-js/package.json').version,
179+
}
180+
: {}),
170181
},
171182
jsc: {
172183
parser: {
@@ -188,12 +199,20 @@ const typescriptLoaderProd = () => {
188199
},
189200
{
190201
test: /\.m?js$/,
202+
exclude: /node_modules[\\/]core-js/,
191203
use: {
192204
loader: 'builtin:swc-loader',
193205
options: {
194206
env: {
195-
targets: packageJSON.browserslist,
207+
targets,
208+
...(useCoreJs
209+
? {
210+
mode: 'usage',
211+
coreJs: '3.41.0',
212+
}
213+
: {}),
196214
},
215+
isModule: 'unknown',
197216
},
198217
},
199218
},
@@ -231,24 +250,28 @@ const typescriptLoaderDev = () => {
231250

232251
/**
233252
* Used for production builds that have dynamicly loaded chunks.
234-
* @type { () => (import('@rspack/core').Configuration) }
253+
* @type { (opts?: { targets?: string, useCoreJs?: boolean }) => (import('@rspack/core').Configuration) }
235254
* */
236-
const commonForProdChunked = () => {
255+
const commonForProdChunked = (
256+
{ targets = packageJSON.browserslist, useCoreJs = false } = { targets: packageJSON.browserslist, useCoreJs: false },
257+
) => {
237258
return {
238259
module: {
239-
rules: [svgLoader(), ...typescriptLoaderProd()],
260+
rules: [svgLoader(), ...typescriptLoaderProd({ targets, useCoreJs })],
240261
},
241262
};
242263
};
243264

244265
/**
245266
* Used for production builds that combine all files into one single file (such as for Chrome Extensions).
246-
* @type { () => (import('@rspack/core').Configuration) }
267+
* @type { (opts?: { targets?: string, useCoreJs?: boolean }) => (import('@rspack/core').Configuration) }
247268
* */
248-
const commonForProdBundled = () => {
269+
const commonForProdBundled = (
270+
{ targets = packageJSON.browserslist, useCoreJs = false } = { targets: packageJSON.browserslist, useCoreJs: false },
271+
) => {
249272
return {
250273
module: {
251-
rules: [svgLoader(), ...typescriptLoaderProd()],
274+
rules: [svgLoader(), ...typescriptLoaderProd({ targets, useCoreJs })],
252275
},
253276
};
254277
};
@@ -288,6 +311,14 @@ const commonForProd = () => {
288311
// minChunkSize: 10000,
289312
// })
290313
],
314+
resolve: {
315+
alias: {
316+
// SWC will inject imports to `core-js` into the source files that utilize polyfilled functions. Because we
317+
// use pnpm, imports from other packages (like `packages/shared`) will not resolve. This alias forces rspack
318+
// to resolve all `core-js` imports to the version we have installed in `clerk-js`.
319+
'core-js': path.dirname(require.resolve('core-js/package.json')),
320+
},
321+
},
291322
};
292323
};
293324

@@ -336,14 +367,21 @@ const prodConfig = ({ mode, env, analysis }) => {
336367
],
337368
}
338369
: {},
339-
common({ mode }),
370+
common({ mode, variant: variants.clerkBrowser }),
340371
commonForProd(),
341372
commonForProdChunked(),
342373
);
343374

375+
const clerkLegacyBrowser = merge(
376+
entryForVariant(variants.clerkLegacyBrowser),
377+
common({ mode, variant: variants.clerkLegacyBrowser }),
378+
commonForProd(),
379+
commonForProdChunked({ targets: packageJSON.browserslistLegacy, useCoreJs: true }),
380+
);
381+
344382
const clerkHeadless = merge(
345383
entryForVariant(variants.clerkHeadless),
346-
common({ mode }),
384+
common({ mode, variant: variants.clerkHeadless }),
347385
commonForProd(),
348386
commonForProdChunked(),
349387
// Disable chunking for the headless variant, since it's meant to be used in a non-browser environment and
@@ -362,50 +400,62 @@ const prodConfig = ({ mode, env, analysis }) => {
362400

363401
const clerkHeadlessBrowser = merge(
364402
entryForVariant(variants.clerkHeadlessBrowser),
365-
common({ mode }),
403+
common({ mode, variant: variants.clerkHeadlessBrowser }),
366404
commonForProd(),
367405
commonForProdChunked(),
368406
// externalsForHeadless(),
369407
);
370408

371-
const clerkEsm = merge(entryForVariant(variants.clerk), common({ mode }), commonForProd(), commonForProdBundled(), {
372-
experiments: {
373-
outputModule: true,
374-
},
375-
output: {
376-
filename: '[name].mjs',
377-
libraryTarget: 'module',
378-
},
379-
plugins: [
380-
// Include the lazy chunks in the bundle as well
381-
// so that the final bundle can be imported and bundled again
382-
// by a different bundler, eg the webpack instance used by react-scripts
383-
new rspack.optimize.LimitChunkCountPlugin({
384-
maxChunks: 1,
385-
}),
386-
],
387-
optimization: {
388-
splitChunks: false,
409+
const clerkEsm = merge(
410+
entryForVariant(variants.clerk),
411+
common({ mode, variant: variants.clerk }),
412+
commonForProd(),
413+
commonForProdBundled(),
414+
{
415+
experiments: {
416+
outputModule: true,
417+
},
418+
output: {
419+
filename: '[name].mjs',
420+
libraryTarget: 'module',
421+
},
422+
plugins: [
423+
// Include the lazy chunks in the bundle as well
424+
// so that the final bundle can be imported and bundled again
425+
// by a different bundler, eg the webpack instance used by react-scripts
426+
new rspack.optimize.LimitChunkCountPlugin({
427+
maxChunks: 1,
428+
}),
429+
],
430+
optimization: {
431+
splitChunks: false,
432+
},
389433
},
390-
});
434+
);
391435

392-
const clerkCjs = merge(entryForVariant(variants.clerk), common({ mode }), commonForProd(), commonForProdBundled(), {
393-
output: {
394-
filename: '[name].js',
395-
libraryTarget: 'commonjs',
396-
},
397-
plugins: [
398-
// Include the lazy chunks in the bundle as well
399-
// so that the final bundle can be imported and bundled again
400-
// by a different bundler, eg the webpack instance used by react-scripts
401-
new rspack.optimize.LimitChunkCountPlugin({
402-
maxChunks: 1,
403-
}),
404-
],
405-
optimization: {
406-
splitChunks: false,
436+
const clerkCjs = merge(
437+
entryForVariant(variants.clerk),
438+
common({ mode, variant: variants.clerk }),
439+
commonForProd(),
440+
commonForProdBundled(),
441+
{
442+
output: {
443+
filename: '[name].js',
444+
libraryTarget: 'commonjs',
445+
},
446+
plugins: [
447+
// Include the lazy chunks in the bundle as well
448+
// so that the final bundle can be imported and bundled again
449+
// by a different bundler, eg the webpack instance used by react-scripts
450+
new rspack.optimize.LimitChunkCountPlugin({
451+
maxChunks: 1,
452+
}),
453+
],
454+
optimization: {
455+
splitChunks: false,
456+
},
407457
},
408-
});
458+
);
409459

410460
/** @type { () => (import('@rspack/core').Configuration) } */
411461
const commonForNoRHC = () => ({
@@ -424,7 +474,7 @@ const prodConfig = ({ mode, env, analysis }) => {
424474

425475
const clerkEsmNoRHC = merge(
426476
entryForVariant(variants.clerkNoRHC),
427-
common({ mode, disableRHC: true }),
477+
common({ mode, disableRHC: true, variant: variants.clerkNoRHC }),
428478
commonForProd(),
429479
commonForProdBundled(),
430480
commonForNoRHC(),
@@ -441,7 +491,7 @@ const prodConfig = ({ mode, env, analysis }) => {
441491

442492
const clerkCjsNoRHC = merge(
443493
entryForVariant(variants.clerkNoRHC),
444-
common({ mode, disableRHC: true }),
494+
common({ mode, disableRHC: true, variant: variants.clerkNoRHC }),
445495
commonForProd(),
446496
commonForProdBundled(),
447497
commonForNoRHC(),
@@ -458,7 +508,16 @@ const prodConfig = ({ mode, env, analysis }) => {
458508
return [clerkBrowser];
459509
}
460510

461-
return [clerkBrowser, clerkHeadless, clerkHeadlessBrowser, clerkEsm, clerkEsmNoRHC, clerkCjs, clerkCjsNoRHC];
511+
return [
512+
clerkBrowser,
513+
clerkLegacyBrowser,
514+
clerkHeadless,
515+
clerkHeadlessBrowser,
516+
clerkEsm,
517+
clerkEsmNoRHC,
518+
clerkCjs,
519+
clerkCjsNoRHC,
520+
];
462521
};
463522

464523
/**
@@ -527,31 +586,31 @@ const devConfig = ({ mode, env }) => {
527586
// prettier-ignore
528587
[variants.clerk]: merge(
529588
entryForVariant(variants.clerk),
530-
common({ mode }),
589+
common({ mode, variant: variants.clerk }),
531590
commonForDev(),
532591
),
533592
// prettier-ignore
534593
[variants.clerkBrowser]: merge(
535594
entryForVariant(variants.clerkBrowser),
536595
isSandbox ? { entry: { sandbox: './sandbox/app.ts' } } : {},
537-
common({ mode }),
596+
common({ mode, variant: variants.clerkBrowser }),
538597
commonForDev(),
539598
),
540599
// prettier-ignore
541600
[variants.clerkBrowserNoRHC]: merge(
542601
entryForVariant(variants.clerkBrowserNoRHC),
543-
common({ mode, disableRHC: true }),
602+
common({ mode, disableRHC: true, variant: variants.clerkBrowserNoRHC }),
544603
commonForDev(),
545604
),
546605
[variants.clerkHeadless]: merge(
547606
entryForVariant(variants.clerkHeadless),
548-
common({ mode }),
607+
common({ mode, variant: variants.clerkHeadless }),
549608
commonForDev(),
550609
// externalsForHeadless(),
551610
),
552611
[variants.clerkHeadlessBrowser]: merge(
553612
entryForVariant(variants.clerkHeadlessBrowser),
554-
common({ mode }),
613+
common({ mode, variant: variants.clerkHeadlessBrowser }),
555614
commonForDev(),
556615
// externalsForHeadless(),
557616
),

0 commit comments

Comments
 (0)