Skip to content

Commit 16f8cb4

Browse files
faris-imibrdlyptrse271828-
authored
fix(legacy): use swc to transform esm to es5 (#20)
Co-authored-by: Brad Peters <brdlyptrs@gmail.com> Co-authored-by: e271828- <e271828-@users.noreply.github.com>
1 parent bb0abf3 commit 16f8cb4

File tree

8 files changed

+155
-22
lines changed

8 files changed

+155
-22
lines changed

README.md

Lines changed: 81 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This is a JavaScript library to easily configure the loading of the [hCaptcha](h
99
1. [Installation](#installation)
1010
2. [Implementation](#implementation)
1111
3. [Props](#props)
12+
3. [Legacy Support](#legacy-support)
1213

1314
### Installation
1415
```
@@ -30,21 +31,83 @@ const { response } = await hcaptcha.execute({ async: true });
3031
```
3132

3233
### Props
33-
| Name | Values/Type | Required | Default | Description |
34-
|-------------------|-------------|----------|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
35-
| `loadAsync` | Boolean | No | `true` | Set if the script should be loaded asynchronously. |
36-
| `cleanup` | Boolean | No | `true` | Remove script tag after setup. |
37-
| `crossOrigin` | String | No | `-` | Set script cross origin attribute such as "anonymous". |
38-
| `scriptSource` | String | No | `https://js.hcaptcha.com/1/api.js` | Set script source URI. Takes precedence over `secureApi`. |
39-
| `scriptLocation` | HTMLElement | No | `document.head` | Location of where to append the script tag. Make sure to add it to an area that will persist to prevent loading multiple times in the same document view. |
40-
| `secureApi` | Boolean | No | `false` | See enterprise docs. |
41-
| `apihost` | String | No | `-` | See enterprise docs. |
42-
| `assethost` | String | No | `-` | See enterprise docs. |
43-
| `endpoint` | String | No | `-` | See enterprise docs. |
44-
| `hl` | String | No | `-` | See enterprise docs. |
45-
| `host` | String | No | `-` | See enterprise docs. |
46-
| `imghost` | String | No | `-` | See enterprise docs. |
47-
| `recaptchacompat` | String | No | `-` | See enterprise docs. |
48-
| `reportapi` | String | No | `-` | See enterprise docs. |
49-
| `sentry` | Boolean | No | `-` | See enterprise docs. |
50-
| `custom` | Boolean | No | `-` | See enterprise docs. |
34+
| Name | Values/Type | Required | Default | Description |
35+
|-------------------|-------------|----------|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
36+
| `loadAsync` | Boolean | No | `true` | Set if the script should be loaded asynchronously. |
37+
| `cleanup` | Boolean | No | `true` | Remove script tag after setup. |
38+
| `crossOrigin` | String | No | `-` | Set script cross origin attribute such as "anonymous". |
39+
| `scriptSource` | String | No | `https://js.hcaptcha.com/1/api.js` | Set script source URI. Takes precedence over `secureApi`. |
40+
| `scriptLocation` | HTMLElement | No | `document.head` | Location of where to append the script tag. Make sure to add it to an area that will persist to prevent loading multiple times in the same document view. |
41+
| `secureApi` | Boolean | No | `false` | See enterprise docs. |
42+
| `apihost` | String | No | `-` | See enterprise docs. |
43+
| `assethost` | String | No | `-` | See enterprise docs. |
44+
| `endpoint` | String | No | `-` | See enterprise docs. |
45+
| `hl` | String | No | `-` | See enterprise docs. |
46+
| `host` | String | No | `-` | See enterprise docs. |
47+
| `imghost` | String | No | `-` | See enterprise docs. |
48+
| `recaptchacompat` | String | No | `-` | See enterprise docs. |
49+
| `reportapi` | String | No | `-` | See enterprise docs. |
50+
| `sentry` | Boolean | No | `-` | See enterprise docs. |
51+
| `custom` | Boolean | No | `-` | See enterprise docs. |
52+
53+
54+
55+
## Legacy Support
56+
In order to support older browsers, a separate bundle is generated in which all ES6 code is compiled down to ES5 along with an optional polyfill bundle.
57+
58+
- `polyfills.js`: Provides polyfills for features not supported in older browsers.
59+
- `index.es5.js`: **@hcaptcha/loader** package compiled for ES5 environments.
60+
61+
### Import Bundle(s)
62+
Both bundles generated use IIFE format rather than a more modern import syntax such as `require` or `esm`.
63+
64+
```js
65+
// Optional polyfill import
66+
import '@hCaptcha/loader/dist/polyfills.js';
67+
// ES5 version of hCaptcha Loader
68+
import '@hCaptcha/loader/dist/index.es5.js';
69+
70+
hCaptchaLoader().then(function(hcaptcha) {
71+
var element = document.createElement('div');
72+
// hCaptcha API is ready
73+
hcaptcha.render(element, {
74+
sitekey: 'YOUR_SITE_KEY',
75+
// Additional options here
76+
});
77+
});
78+
79+
```
80+
### TypeScript
81+
To handle typescript with ES5 version, use the following statement.
82+
```ts
83+
declare global {
84+
interface Window {
85+
hCaptchaLoader: any;
86+
}
87+
}
88+
```
89+
90+
### CDN
91+
The hCaptcha Loader targeted for older browsers can also be imported via CDN by using UNPKG](https://www.unpkg.com/), see example below.
92+
93+
94+
```html
95+
<!DOCTYPE html>
96+
<head>
97+
<script type="text/javascript" src="https://unpkg.com/@hcaptcha/loader@latest/dist/polyfills.js"></script>
98+
<script type="text/javascript" src="https://unpkg.com/@hcaptcha/loader@latest/dist/index.es5.js"></script>
99+
</head>
100+
<body>
101+
<div id="container"></div>
102+
<script type="text/javascript">
103+
hCaptchaLoader().then(function(hcaptcha) {
104+
// hCaptcha API is ready
105+
hcaptcha.render('container', {
106+
sitekey: 'YOUR_SITE_KEY',
107+
// Additional options here
108+
});
109+
});
110+
</script>
111+
</body>
112+
</html>
113+
```

lib/esbuild.config.js

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { fileURLToPath } from 'url';
33

44
import { build, context, analyzeMetafile } from 'esbuild';
55
import * as dotenv from 'dotenv';
6+
import swc from '@swc/core';
67

78
const __filename = fileURLToPath(import.meta.url);
89
const __dirname = path.dirname(__filename);
@@ -44,6 +45,14 @@ const config = {
4445
sourcemap: BUILD === 'development',
4546
};
4647

48+
const swcOptions = {
49+
minify: true,
50+
sourceMaps: BUILD === 'development',
51+
jsc: {
52+
target: 'es5',
53+
},
54+
};
55+
4756

4857
if (WATCH) {
4958
const ctx = await context({
@@ -57,6 +66,7 @@ if (WATCH) {
5766
});
5867
await ctx.watch();
5968
} else {
69+
// Transpile TypeScript to ESM
6070
const resultESM = await build({
6171
...config,
6272
format: 'esm',
@@ -67,11 +77,46 @@ if (WATCH) {
6777
]
6878
});
6979

80+
// Transpile TypeScript to CommonJS
7081
const resultCJS = await build({
7182
...config,
7283
format: 'cjs',
7384
outfile: resolve(DIST, 'index.cjs'),
74-
treeShaking: true
85+
treeShaking: true,
86+
});
87+
88+
// Transform to ES5
89+
const transformedESM = await swc.transformFile(resolve(DIST, 'index.mjs'), swcOptions);
90+
91+
// Build ES5 bundle
92+
const resultES5 = await build({
93+
...config,
94+
entryPoints: undefined,
95+
globalName: 'hCaptchaLoaderPkg',
96+
stdin: {
97+
contents: transformedESM.code,
98+
resolveDir: DIST,
99+
sourcefile: 'index.es5.js',
100+
},
101+
outfile: resolve(DIST, 'index.es5.js'),
102+
footer: {
103+
js: 'window.hCaptchaLoader = hCaptchaLoaderPkg.hCaptchaLoader;',
104+
},
105+
treeShaking: true,
106+
target: [
107+
'es5',
108+
]
109+
});
110+
111+
// Add Polyfills
112+
await build({
113+
...config,
114+
entryPoints: [resolve(SRC, 'polyfills.ts')],
115+
outfile: resolve(DIST, 'polyfills.js'),
116+
treeShaking: true,
117+
target: [
118+
'es5',
119+
]
75120
});
76121

77122
if (DEBUG) {
@@ -81,7 +126,12 @@ if (WATCH) {
81126
const analyzeCJS = await analyzeMetafile(resultCJS.metafile, {
82127
verbose: false
83128
});
129+
const analyzeES5 = await analyzeMetafile(resultES5.metafile, {
130+
verbose: false
131+
});
132+
84133
console.log(analyzeESM);
85134
console.log(analyzeCJS);
135+
console.log(analyzeES5);
86136
}
87137
}

lib/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"test:unit": "jest"
1313
},
1414
"dependencies": {
15-
"@sentry/browser": "^7.73.0"
15+
"@sentry/browser": "^7.73.0",
16+
"core-js": "^3.35.1"
1617
},
1718
"devDependencies": {
1819
"@hcaptcha/types": "^1.0.3",

lib/src/loader.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,6 @@ export async function loadScript(params, retries = 0) {
125125
}
126126

127127

128-
export async function hCaptchaLoader(params) {
128+
export async function hCaptchaLoader(params = {}) {
129129
return await loadScript(params);
130130
}

lib/src/polyfills.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import 'core-js/es/array/find';
2+
import 'core-js/es/object/assign';
3+
import 'core-js/es/object/entries';
4+
import 'core-js/es/object/get-own-property-descriptors';

lib/tsconfig.types.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,8 @@
1313

1414
"include": [
1515
"src/**/*"
16+
],
17+
"exclude": [
18+
"src/polyfills.ts"
1619
]
1720
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@hcaptcha/loader",
33
"description": "This is a JavaScript library to easily configure the loading of the hCaptcha JS client SDK with built-in error handling.",
4-
"version": "1.2.1",
4+
"version": "1.2.2",
55
"author": "hCaptcha team and contributors",
66
"license": "MIT",
77
"keywords": [

pnpm-lock.yaml

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)