Skip to content

Commit

Permalink
fix: provide both browser and node cjs bundles (#2457)
Browse files Browse the repository at this point in the history
### 🎯 Goal

Although it rarely makes sense to SSR chat, import `stream-chat-react`
on server ideally shouldn't fail.

### πŸ›  Implementation details

We now build two CJS bundles: one with node-specific dependencies
(esbuild `platform: 'node'`), one with browser-specific dependencies
(esbuild `platform: 'browser'`). The node version is exposed as a
`"node"` export in package.json, so frameworks like Next.js should
prefer it for SSR.

---------

Co-authored-by: Anton Arnautov <[email protected]>
  • Loading branch information
myandrienko and arnautov-anton authored Aug 15, 2024
1 parent 4e60c07 commit 273ea2a
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/size.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ jobs:
- uses: preactjs/compressed-size-action@v2
with:
repo-token: '${{ secrets.GITHUB_TOKEN }}'
pattern: './dist/**/*.{js,css,json}'
pattern: './dist/**/*.{js,cjs,css,json}'
34 changes: 26 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,44 @@
"url": "https://github.com/GetStream/stream-chat-react.git"
},
"types": "dist/index.d.ts",
"main": "dist/index.cjs.js",
"main": "dist/index.node.cjs",
"module": "dist/index.js",
"jsdelivr": "./dist/browser.full-bundle.min.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.cjs.js",
"import": "./dist/index.js",
"node": {
"require": "./dist/index.node.cjs",
"import": "./dist/index.js"
},
"browser": {
"require": "./dist/index.browser.cjs",
"import": "./dist/index.js"
},
"default": "./dist/index.js"
},
"./emojis": {
"types": "./dist/plugins/Emojis/index.d.ts",
"require": "./dist/plugins/Emojis/index.cjs.js",
"import": "./dist/plugins/Emojis/index.js",
"node": {
"require": "./dist/plugins/Emojis/index.node.cjs",
"import": "./dist/plugins/Emojis/index.js"
},
"browser": {
"require": "./dist/plugins/Emojis/index.browser.cjs",
"import": "./dist/plugins/Emojis/index.js"
},
"default": "./dist/plugins/Emojis/index.js"
},
"./mp3-encoder": {
"types": "./dist/plugins/encoders/mp3.d.ts",
"require": "./dist/plugins/encoders/mp3.cjs.js",
"import": "./dist/plugins/encoders/mp3.js",
"node": {
"require": "./dist/plugins/encoders/mp3.node.cjs",
"import": "./dist/plugins/encoders/mp3.js"
},
"browser": {
"require": "./dist/plugins/encoders/mp3.browser.cjs",
"import": "./dist/plugins/encoders/mp3.js"
},
"default": "./dist/plugins/encoders/mp3.js"
},
"./dist/css/*": {
Expand Down Expand Up @@ -242,7 +260,7 @@
"test": "jest",
"types": "tsc --noEmit --skipLibCheck false",
"validate-translations": "node scripts/validate-translations.js",
"validate-cjs": "node scripts/validate-cjs-bundle.cjs",
"validate-cjs": "concurrently 'node scripts/validate-cjs-node-bundle.cjs' 'node scripts/validate-cjs-browser-bundle.cjs'",
"semantic-release": "semantic-release",
"browse-examples": "ladle serve",
"e2e": "playwright test",
Expand Down
16 changes: 13 additions & 3 deletions scripts/bundle.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,26 @@ const deps = Object.keys({
});
const external = deps.filter((dep) => !bundledDeps.includes(dep));

/** @type esbuild.BuildOptions */
const cjsBundleConfig = {
entryPoints: [sdkEntrypoint, emojiEntrypoint, mp3EncoderEntrypoint],
bundle: true,
format: 'cjs',
platform: 'browser',
target: 'es2020',
external,
outdir: outDir,
entryNames: '[dir]/[name].cjs',
outExtension: { '.js': '.cjs' },
sourcemap: 'linked',
};

await esbuild.build(cjsBundleConfig);
// We build two CJS bundles: for browser and for node. The latter one can be
// used e.g. during SSR (although it makes little sence to SSR chat, but still
// nice for import not to break on server).
const bundles = ['browser', 'node'].map((platform) =>
esbuild.build({
...cjsBundleConfig,
entryNames: `[dir]/[name].${platform}`,
platform,
}),
);
await Promise.all(bundles);
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// As the community transitions to ESM, we can easily break our CJS bundle.
// This smoke test can help to detect this early.

// First, set up minimal browser-like environment:
const { JSDOM } = require('jsdom');
const dom = new JSDOM('', {
url: 'https://localhost',
Expand All @@ -15,5 +14,4 @@ for (const key of Object.keys(window)) {
}
}

// Then, try importing our CJS bundle:
require('../dist/index.cjs.js');
require('../dist/index.browser.cjs');
4 changes: 4 additions & 0 deletions scripts/validate-cjs-node-bundle.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// As the community transitions to ESM, we can easily break our CJS bundle.
// This smoke test can help to detect this early.

require('../dist/index.node.cjs');

0 comments on commit 273ea2a

Please sign in to comment.