Skip to content

Leverage rollup's --config* feature for choosing bundles #477

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 15, 2020

Conversation

jasonkarns
Copy link
Contributor

@jasonkarns jasonkarns commented May 7, 2020

Summary

Rollup provides a feature specifically designed for passing in config
options to the rollup configuration module. That is: --config-* options.
(It is documented deeply under
https://rollupjs.org/guide/en/#configuration-files )

I believe this is a superior mechanism for passing options to rollup's
config because they do not impact process.env.

Environment variables have a very specific capability, which is that
they are inherited by child processes. These are settings that quite
literally "configure the environment under which a process runs".
They are the correct tool for setting env vars that should be set
within node during compilation, but not a proper replacement for
cli "flags".

Their use prior to this commit was an abuse in order to simply
pass an option to the rollup configuration that would control which
bundles to build. Rollup's --config* feature is superior for this role,
because the option is only intended to go so far as the configuration
module itself. Thus, using them to control which bundle(s) are built
does not leak extraneous information into the ahem environment of the
build process.

As a side benefit, the cli invocation is cleaner!

Another major benefit of this is that it allows explicitly choosing a
subset of bundles to build. ie:

  • rollup -c --config-cjs to build all commonjs bundles
  • rollup -c --config-json --config-umd to build the jsonSchema bundle
    and the UMD bundle.

And since the flags match on substrings, cross-matrices are supported, too.

For instance, say the following bundles were available:

  • cjs-node, cjs-react, cjs-browser, esm-node, esm-browser

It would be possible to build all the node bundles or all the ESM bundles,
or all the cjs bundles or esm bundles.

rollup -c --config-esm
rollup -c --config-cjs
rollup -c --config-node
rollup -c --config-browser

Notably, the implementation dedupes the options, so if a given bundle
is matched by multiple flags, it's only built once.

This implementation is flexible so users may build precisely the bundles
they want, without waiting on extraneous bundles to build.
The developer ergonomics are clean so it's simple when invoking the rollup
CLI directly.
And the flags themselves are clean explicit enough that intent is "clear"
when being read from npm-scripts. (ie, "self-documenting")

A couple other quick nits in this PR:

  • the pre-build step is extracted to an npm-clean script, per convention.
  • the clean script is invoked automatically before building. (leveraging
    npm's pre/post hooks keeps scripts clearly explicit as to their primary
    purpose)
  • the rollup config variable names are changed to reflect what they
    represent. ("config" is an overly general term. each rollup config represents
    an output bundle, so that term is used instead. I mean, the entire
    rollup configuration module is "config" so... that's almost meaningless)
  • the common cjs helper function is renamed (virtually every function
    "gets" something. prefixing a function with "get" is akin to doFoo.
    this dispenses with the imperative naming and names the function
    for what it returns. Because a function's name at the callsite is literally
    replaced with its return value, so what it returns is what it should be
    named.)
  • runs prettier on the entire config to clear up any inconsistency
  • adds an unminified ESM output bundle:
    many ESM consumers will be running their own rollup/webpack
    bundlers, and therefore doing their own minification. Providing
    an unminified ESM entrypoint makes their debugging easier.

(Last note, a portion of this PR is whitespace thanks to prettier,
so when reviewing the diff on github, disabling whitespace will make
the rendered diff smaller/cleaner.)

jasonkarns added 3 commits May 7, 2020 14:26
Rollup provides a feature specifically designed for passing in config
options to the rollup configuration module. That is: --config-* options.
(It is documented deeply under
https://rollupjs.org/guide/en/#configuration-files )

I believe this is a superior mechanism for passing options to rollup's
config because they do not impact process.env.

Environment variables have a very specific capability, which is that
they are inherited by child processes. These are settings that quite
literally "configure the environment under which a process runs".

However, their use prior to this commit was an abuse in order to simply
pass an _option_ to the rollup configuration that would control which
bundles to build. Rollup's --config* feature is superior for this role,
because the option is only intended to go so far as the configuration
module itself. Thus, using them to control which bundle(s) are built
does not leak extraneous information into the *ahem* environment of the
build process.

As a side benefit, the cli invocation is cleaner!
ESM consumers are very likely using their own bundler (rollup, webpack)
and would probably prefer to consume non minified ESM entrypoint so they
can minifiy it themselves with their preferred minification tools.
Copy link
Contributor

@mjc1283 mjc1283 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Agree that the --config option is a better approach than environment variables. Also the unminified ESM output is great to have.

@mjc1283 mjc1283 merged commit 764135b into optimizely:master May 15, 2020
@jasonkarns jasonkarns deleted the rollup-config branch May 20, 2020 17:54
jasonkarns added a commit to github/optimizely-javascript-sdk that referenced this pull request May 20, 2020
* master:
  Leverage rollup's --config* feature for choosing bundles (optimizely#477)
zashraf1985 added a commit that referenced this pull request Apr 11, 2022
## Background

This PR is copied from [484](#484). It was contributed by @jasonkarns a couple of years ago. I just pulled his changes, merged master and resolved conflicts.

## Summary

ESM entrypoints are very very likely to be consumed by bundlers, not loaded directly into browsers. Therefore it is preferable that the bundlers have access to the unminified source so that consumers can have more control over the final output.

~~This change _adds_ an ESM output bundle that is not minified with terser.~~ (#477 has merged which also adds the unminified ES bundle, so this PR now just makes the unminified bundle the `module` entrypoint.)
Notably, the unminified bundle is created _in addition to_ the minified bundle;
so the minified bundle is still distributed with the package (at the same output location).

This way users who do actually want the minified bundle may still use it.

However, the `package.json#module` entrypoint is changed to reference the unminified bundle, as this is most likely what users will want when consuming from a bundler. (And bundlers are virtually the exclusive consumers of the `module` entrypoint.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants