Commonjs + node polyfills in rollup & esbuild
Latest update:
This is what I need from a bundler:
Import ES6 modules.
Wrap node built-in modules (that don't do IO) to work in a browser,
like browserify did (still does).
Import commonjs modules.
Don't require hours of reading its manual & scavenging github for
'plugins'.
Why are there no bundlers that do that w/o any config? Why can't I
write
$ some-js-bundler < main.js > bundle.js
Example
$ cat foo.js
import path from 'path'
import md5 from 'blueimp-md5' // nodejs implementation is too big
export function foo() {
return md5(path.dirname("foo/bar/baz.txt"))
}
$ cat main.js
import * as lib from './foo.js'
console.log(lib.foo())
$ echo '{"type":"module","dependencies":{"blueimp-md5":"*"}}' > package.json
$ npm i -s
$ node main.js
82d0f0fa8551de8b7eb5ecb65eae0261
Now we bring this main.js
to the browser.
rollup
The good thing about it that you can achieve that w/o a config. The
bad thing: I believe node polyfills are outside of a supported plugins
realm.
3 plugins are required:
$ npm i -s @rollup/plugin-commonjs @rollup/plugin-node-resolve rollup-plugin-polyfill-node
Then
$ rollup main.js --format iife -p rollup-plugin-polyfill-node -p @rollup/plugin-node-resolve -p @rollup/plugin-commonjs > rollup.1.js
An unminified bundle:
$ wc -c < rollup.1.js
19678
The same with a config?
$ cat rollup.config.js
import nodePolyfills from 'rollup-plugin-polyfill-node'
import {nodeResolve} from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
export default {
output: { format: 'iife' },
plugins: [nodePolyfills(), nodeResolve(), commonjs()]
}
$ rollup main.js -c > rollup.2.js
$ cmp rollup.1.js rollup.2.js
$ exit $?
0
The fact that you need explicitly tell rollup to use a config, even if
your named it in a 'recommended' way, annoys me immensely.
esbuild
Good news: no need for a node or commonjs plugin! Bad news: esbuild
mainterners don't particularly care about node polyfills, and the most
maintainable plugin actually reuses the rollup package.
Even worse news: as long as you use an external plugin, say goodbye to
the standard esbuild CLI--writing an esbuild 'wrapper' is required.
$ npm i -s esbuild @esbuild-plugins/node-modules-polyfill
$ cat esbuild.js
#!/usr/bin/env node
import { build } from 'esbuild'
import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill'
build({
plugins: [NodeModulesPolyfillPlugin()],
entryPoints: [process.argv[2] || usage()],
bundle: true,
})
function usage() { console.warn('Usage: esbuild.js file.js'), process.exit(1) }
$ chmod +x esbuild.js
I understand philosophical reasons for writing your own tooling every
time, but this is too common a case.
$ ./esbuild.js main.js > esbuild-bundle.js
$ wc -c < esbuild-bundle.js
13998
Anyway, with no additional tweaking, rollup seems to make slightly
smaller bundles than esbuild:
$ for i in rollup.1.js esbuild-bundle.js ; do
> terser $i --module -mc | gzip -c | wc -c
> done
2454
2716
-
Maybe it's a good thing, for another bespoke
attempt of copypasting node's stdlib makes little sense.
Tags: ойті
Authors: ag