I've been working on a small utility that I've recently published to npm, and my goal with it was to target both a Node.js and a browser environment.
In order to accomplish this, I picked up a tool that I've been loathe to touch since the last time I used it, roughly a decade ago — Babel.
What's wrong with Babel?
While I wouldn't actually say there's something wrong with Babel, it does (necessarily) involve lots of complexity. It can be an absolute nightmare to configure, depending on your build process(es).
For this relatively simple project, within the space of a week and a half, I wrote, then threw away and rewrote my babel build configuration several times until I was satisfied with the end result.
Then why use a transpiler at all?
When used correctly, a build process that involves transpilation can strike the sweet spot where you're able to use the latest ECMAScript features while maintaining backward compatibility with a variety of target environments.
In my case, I wanted to be able to write my source code using ES Modules that enjoy widespread browser support, while compiling down to the CommonJS module system that's still widely used in Node.js.
Show, don't tell
Full disclaimer: while this is the result of a lot of trial and error, I don't claim to have met any standard of best practices, and would recommend you do your own homework. Decide what best meets your needs, rather than just following my (or anyone else's) example.
Start to finish, my build process consists of a some nested npm run scripts and a decent amount of bash:
-
dist
: kicks off additional run scripts per build target-
build-browser
: prepares the browser distributable by way of...-
concat-browser
: concatenates a few source files together into a singlebuild-main-browser.mjs
script -
transpile-browser
: runs babel on said script with the.babelrc.esm.json
config and an output filename
-
-
build-node
: prepares the node distributable by way of...-
concat-node
: concatenates a few source files together into a singlebuild-main-node.mjs
script -
transpile-node
: runs babel on said script with the.babelrc.cjs.json
config and an output filename - bash snippet that copies
import.mjs
for ESM export/import support on top of the transpiled CJS
-
-
This produces:
- a browser targeted script in
lib/
with the original ES Module exports, leveraging a browserslist query for which browser features to transpile support for - a Node v20 targeted script in
dist/
transpiled down to CommonJS, with an additional script to tack on ES Module exports
You can see the result on npm, if you're interested.
Top comments (0)