The use case
You're using one or more third party libraries (React, Preact, Lodash, ...) in an ES6 library you're creating for the browser.
Don't bundle
Don't bundle the third party libraries with your library.
- Your visitors might already have the third party libraries in their cache. If you bundle them with your library, then they're forced to download all of those bytes again.
- If you change your library, then your visitors are forced to download everything again: your library and all of the bundled (and unchanged) third party libraries.
The solution
First, import and use the third party libraries in your code as you normally would.
import { h } from "preact"; // 3rd party
import htm from "htm"; // 3rd party
const html = htm.bind(h);
// ...
Second, add the third party libraries' script tags to your HTML. Be sure to use UMD bundles that export a global.
<script src="https://cdn.jsdelivr.net/npm/preact?umd"></script>
<script src="https://cdn.jsdelivr.net/npm/htm?umd"></script>
Third, find the exact name of the global that each third party library exports. For these two libraries, I loaded their script tags into a test HTML file, opened up the console, and found preact
and htm
. In this case the globals matched the library names, but that's not always the case.
Finally, configure Rollup to replace the ES6 dependencies with the globals.
import externalGlobals from "rollup-plugin-external-globals";
import { terser } from "rollup-plugin-terser";
export default {
external: ["preact", "htm"],
input: "src/library.js",
output: [
{
file: "dist/library.js",
format: "iife",
},
{
file: "dist/library.min.js",
format: "iife",
plugins: [terser()],
},
],
plugins: [
externalGlobals({
preact: "preact", // <- must match the global name
htm: "htm", // <- must match the global name
["a-dashed-3rd-party-library"]: "globalVariable" // <- advanced example
}),
],
};
You'll need rollup-plugin-external-globals to perform the replacement and rollup-plugin-terser to minimize your library's code.
That's it! Rollup will now convert
import { h } from "preact"; // 3rd party
import htm from "htm"; // 3rd party
const html = htm.bind(h);
// ...
to simply
const html = htm.bind(preact.h);
// ...
Summary
- Don't bundle third party libraries with your browser library.
- Use the third party libraries in your code as you normally would, and then
- Use Rollup to replace the ES6 imports with globals.
Photo by Charles "Duck" Unitas on Unsplash