Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(legacy): use swc to transform esm to es5 #20

Merged
merged 21 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 81 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This is a JavaScript library to easily configure the loading of the [hCaptcha](h
1. [Installation](#installation)
2. [Implementation](#implementation)
3. [Props](#props)
3. [Legacy Support](#legacy-support)

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

### Props
| Name | Values/Type | Required | Default | Description |
|-------------------|-------------|----------|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
| `loadAsync` | Boolean | No | `true` | Set if the script should be loaded asynchronously. |
| `cleanup` | Boolean | No | `true` | Remove script tag after setup. |
| `crossOrigin` | String | No | `-` | Set script cross origin attribute such as "anonymous". |
| `scriptSource` | String | No | `https://js.hcaptcha.com/1/api.js` | Set script source URI. Takes precedence over `secureApi`. |
| `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. |
| `secureApi` | Boolean | No | `false` | See enterprise docs. |
| `apihost` | String | No | `-` | See enterprise docs. |
| `assethost` | String | No | `-` | See enterprise docs. |
| `endpoint` | String | No | `-` | See enterprise docs. |
| `hl` | String | No | `-` | See enterprise docs. |
| `host` | String | No | `-` | See enterprise docs. |
| `imghost` | String | No | `-` | See enterprise docs. |
| `recaptchacompat` | String | No | `-` | See enterprise docs. |
| `reportapi` | String | No | `-` | See enterprise docs. |
| `sentry` | Boolean | No | `-` | See enterprise docs. |
| `custom` | Boolean | No | `-` | See enterprise docs. |
| Name | Values/Type | Required | Default | Description |
|-------------------|-------------|----------|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
| `loadAsync` | Boolean | No | `true` | Set if the script should be loaded asynchronously. |
| `cleanup` | Boolean | No | `true` | Remove script tag after setup. |
| `crossOrigin` | String | No | `-` | Set script cross origin attribute such as "anonymous". |
| `scriptSource` | String | No | `https://js.hcaptcha.com/1/api.js` | Set script source URI. Takes precedence over `secureApi`. |
| `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. |
| `secureApi` | Boolean | No | `false` | See enterprise docs. |
| `apihost` | String | No | `-` | See enterprise docs. |
| `assethost` | String | No | `-` | See enterprise docs. |
| `endpoint` | String | No | `-` | See enterprise docs. |
| `hl` | String | No | `-` | See enterprise docs. |
| `host` | String | No | `-` | See enterprise docs. |
| `imghost` | String | No | `-` | See enterprise docs. |
| `recaptchacompat` | String | No | `-` | See enterprise docs. |
| `reportapi` | String | No | `-` | See enterprise docs. |
| `sentry` | Boolean | No | `-` | See enterprise docs. |
| `custom` | Boolean | No | `-` | See enterprise docs. |



## Legacy Support
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.

- `polyfills.js`: Provides polyfills for features not supported in older browsers.
- `index.es5.js`: **@hcaptcha/loader** package compiled for ES5 environments.

### Import Bundle(s)
Both bundles generated use IIFE format rather than a more modern import syntax such as `require` or `esm`.

```js
// Optional polyfill import
import '@hCaptcha/loader/dist/polyfills.js';
// ES5 version of hCaptcha Loader
import '@hCaptcha/loader/dist/index.es5.js';

hCaptchaLoader().then(function(hcaptcha) {
var element = document.createElement('div');
// hCaptcha API is ready
hcaptcha.render(element, {
sitekey: 'YOUR_SITE_KEY',
// Additional options here
});
});

```
### TypeScript
To handle typescript with ES5 version, use the following statement.
```ts
declare global {
interface Window {
hCaptchaLoader: any;
}
}
```

### CDN
The hCaptcha Loader targeted for older browsers can also be imported via CDN by using UNPKG](https://www.unpkg.com/), see example below.


```html
<!DOCTYPE html>
<head>
<script type="text/javascript" src="https://unpkg.com/@hcaptcha/loader@latest/dist/polyfills.js"></script>
<script type="text/javascript" src="https://unpkg.com/@hcaptcha/loader@latest/dist/index.es5.js"></script>
</head>
<body>
<div id="container"></div>
<script type="text/javascript">
hCaptchaLoader().then(function(hcaptcha) {
// hCaptcha API is ready
hcaptcha.render('container', {
sitekey: 'YOUR_SITE_KEY',
// Additional options here
});
});
</script>
</body>
</html>
```
52 changes: 51 additions & 1 deletion lib/esbuild.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { fileURLToPath } from 'url';

import { build, context, analyzeMetafile } from 'esbuild';
import * as dotenv from 'dotenv';
import swc from '@swc/core';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
Expand Down Expand Up @@ -44,6 +45,14 @@ const config = {
sourcemap: BUILD === 'development',
};

const swcOptions = {
minify: true,
sourceMaps: BUILD === 'development',
jsc: {
target: 'es5',
},
};


if (WATCH) {
const ctx = await context({
Expand All @@ -57,6 +66,7 @@ if (WATCH) {
});
await ctx.watch();
} else {
// Transpile TypeScript to ESM
const resultESM = await build({
...config,
format: 'esm',
Expand All @@ -67,11 +77,46 @@ if (WATCH) {
]
});

// Transpile TypeScript to CommonJS
const resultCJS = await build({
...config,
format: 'cjs',
outfile: resolve(DIST, 'index.cjs'),
treeShaking: true
treeShaking: true,
});

// Transform to ES5
const transformedESM = await swc.transformFile(resolve(DIST, 'index.mjs'), swcOptions);

// Build ES5 bundle
const resultES5 = await build({
...config,
entryPoints: undefined,
globalName: 'hCaptchaLoaderPkg',
stdin: {
contents: transformedESM.code,
resolveDir: DIST,
sourcefile: 'index.es5.js',
},
outfile: resolve(DIST, 'index.es5.js'),
footer: {
js: 'window.hCaptchaLoader = hCaptchaLoaderPkg.hCaptchaLoader;',
},
treeShaking: true,
target: [
'es5',
]
});

// Add Polyfills
await build({
...config,
entryPoints: [resolve(SRC, 'polyfills.ts')],
outfile: resolve(DIST, 'polyfills.js'),
treeShaking: true,
target: [
'es5',
]
});

if (DEBUG) {
Expand All @@ -81,7 +126,12 @@ if (WATCH) {
const analyzeCJS = await analyzeMetafile(resultCJS.metafile, {
verbose: false
});
const analyzeES5 = await analyzeMetafile(resultES5.metafile, {
verbose: false
});

console.log(analyzeESM);
console.log(analyzeCJS);
console.log(analyzeES5);
}
}
3 changes: 2 additions & 1 deletion lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"test:unit": "jest"
},
"dependencies": {
"@sentry/browser": "^7.73.0"
"@sentry/browser": "^7.73.0",
"core-js": "^3.35.1"
},
"devDependencies": {
"@hcaptcha/types": "^1.0.3",
Expand Down
2 changes: 1 addition & 1 deletion lib/src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,6 @@ export async function loadScript(params, retries = 0) {
}


export async function hCaptchaLoader(params) {
export async function hCaptchaLoader(params = {}) {
return await loadScript(params);
}
4 changes: 4 additions & 0 deletions lib/src/polyfills.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import 'core-js/es/array/find';
import 'core-js/es/object/assign';
import 'core-js/es/object/entries';
import 'core-js/es/object/get-own-property-descriptors';
3 changes: 3 additions & 0 deletions lib/tsconfig.types.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@

"include": [
"src/**/*"
],
"exclude": [
"src/polyfills.ts"
]
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@hcaptcha/loader",
"description": "This is a JavaScript library to easily configure the loading of the hCaptcha JS client SDK with built-in error handling.",
"version": "1.2.1",
"version": "1.2.2",
"author": "hCaptcha team and contributors",
"license": "MIT",
"keywords": [
Expand Down
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading