feat: use iife build for sdk (#10255)

Vite uses `Rollup` for bundling, when building the sdk, we effectively
run a separate vite config, with `Library Mode`. When migrating from
Webpack to Vite, I selected `umd` format, i.e. Universal Module
Definition, which works as `amd`, `cjs` and `iife` all in one. However a
lot of Chatwoot users ran into issues where UMD sdk.js won't work.
Especially so when used with Google Tag Manager.

As a hotfix we moved the format from `umd` to `cjs`. Here's the thing
CJS is supposed to be used for Node packages. But for some-reason it was
working on browsers too, its no surprising, since the output is a valid
JS and the code we wrote was written for the browser.

There's a catch though, when minifying, esbuild would use tokens like
`$` and `_`, since `CJS` build is not scoped, unlike a `UMD` file, or
(spoiler alert) `IIFE`. Any declarations would be global, and websites
using `jQuery` (uff, culture) and `underscore-js` would break. We pushed
another hotfix disabling the name replacement in `esbuild` unless we
test out `IIFE` builds (which is this PR)

This PR fixes this by using `IIFE` instead, it is always scoped in a
function, so it never binds things globally, unless specifically written
to do so (example. `window.$chatwoot`).

I've tested this SDK on Safari, Chrome and iOS Safari on paperlayer test
site, it seems to be working fine. The sdk build is also scoped
correctly.

---------

Co-authored-by: Pranav <pranav@chatwoot.com>
This commit is contained in:
Shivam Mishra
2024-10-11 00:44:36 +05:30
committed by GitHub
parent a2f32f7232
commit 4c7a539f9d

View File

@@ -42,11 +42,6 @@ if (isLibraryMode) {
plugins = [vue(vueOptions)];
}
const esbuildOptions = {
minifyIdentifiers: false,
keepNames: true,
};
export default defineConfig({
plugins: plugins,
build: {
@@ -71,7 +66,7 @@ export default defineConfig({
lib: isLibraryMode
? {
entry: path.resolve(__dirname, './app/javascript/entrypoints/sdk.js'),
formats: ['cjs'], // CJS format for single file
formats: ['iife'], // IIFE format for single file
name: 'sdk',
}
: undefined,
@@ -112,5 +107,4 @@ export default defineConfig({
mockReset: true,
clearMocks: true,
},
esbuild: isLibraryMode ? esbuildOptions : undefined,
});