rollup vs esbuild:
iife is not umd

by — posted on

Rollup, Webpack, and new esbuild can bundle JS programs to be usable in webpages, to be added as a <script>. However, there's a problem with esbuild.

It produces opens in a new tab iife builds for browsers, not umd.

You might ask, what's the difference? They both work as intended in browsers, right?

Yes, but you can't import/require esbuild iife bundles and unit test them:

// test.js
import { stripHtml } from "../dist/string-strip-html.dev.umd";

// run unit tests on this stripHtml()

If we can't unit test all the builds — programs we produce — there's no way to completely guarantee the quality.

I've just had fixed a hardcore bug in CJS builds, caused by a single misconfigured line in Babel, loose set to true. Rollup built fine, except Babel was casually omitting spread operators here and there, in CJS builds only. All that time, ESM and UMD builds were fine. It just happened that I was assuming CJS will be solid; it should not break, at least without ESM failing too. Wrong.

Furthermore, since I write unit tests anyway, I can easily repurpose unit tests to check all three builds instead of one. All I need to do is to pipe them through an intermediary helper function opens in a new tab, calculate a result for each build, compare them to ensure they all match, then return the result of esm build for further consumption in unit test asserts.

It's easy in tap/ava the unit test runners, although commonly-used Jest does not pass t, the main test instance opens in a new tab so bad news Jest users. Basically, instead of:

test('did not rain', () => {
expect(inchesOfRain(value)).toBe(0);
});

We'd tap the test's instance, t, which in hypothetical Jest case would look like:

test('did not rain', (t) => {
t.expect(inchesOfRain(t, value)).toBe(0);
});

In real tap tests, it would rather resemble:

tap.test('did not rain', (t) => {
t.equal(inchesOfRain(t, value), 0);
});

And inchesOfRain() would add extra asserts, like doing extra calculations against different builds, then assert their differences, then return the result as normal.

Again, this shows how different programming and SPA web development workflows are — even unit test runner principles are different.

Takeaway

The esbuild iife builds are not umd opens in a new tab builds, iife builds can't be unit-tested, unlike Rollup's umd. It's a big deal.

Related packages:

📦 esbuild opens in a new tab
An extremely fast JavaScript bundler and minifier
📦 rollup opens in a new tab
Next-generation ES module bundler