Skip to content

Proposal: Remove the PureScript bundler #4226

@thomashoneyman

Description

@thomashoneyman

Summary

I am proposing that we remove the PureScript bundler once we support ES modules in the compiler (once #3791 merges and #3613 is closed). With ES modules in place, the bundler is no longer necessary to develop applications in the browser or on Node. Since the bundler is slow, buggy, and difficult to work on -- a high risk, low reward part of the compiler -- removing it reduces the maintenance burden on the already-thin compiler team.

Two weeks ago I opened an RFC on Discourse titled RFC: The Future of the PureScript Bundler in which the community has so far seemed entirely in favor of this proposal.

Motivation

The PureScript compiler includes a bundler that performs dead code elimination and produces a single .js file from PureScript sources, which can then be used in the browser or on Node. The bundler exists for a few reasons:

  1. To ensure users can run their PureScript code in the browser and on Node without requiring additional tools
  2. To trim the size of the generated code by performing dead code elimination while bundling

Enter ES modules, which we have already agreed to support in the compiler. We have two paths forward for ES modules support as far as the bundler is concerned:

  1. We fix the bundler so it works for ES modules -- which is trickier than it may at first appear
  2. We remove the bundler altogether

Why has (2) even become an option at all, when it hasn't historically been an option? Because things have changed with ES modules:

  1. ES modules are usable in the browser without bundling. Therefore user interfaces can be developed in PureScript without the need for a bundler.
  2. ES modules are usable in Node experimentally since v12, and fully in Node since v14 -- which will be the oldest supported version by the time PureScript 0.15 comes out -- so long as you use the file extension .mjs or set type: "module" in a package.json file. For now, the compiler output contains a package.json file containing type: "module".
  3. Bundlers like webpack and esbuild are able to provide dead code elimination for ES modules comparable with purs bundle optimized with zephyr, and may even perform better if we make other compiler changes like changing the representation of data types. These bundlers of course are also able to produce a single .js file for use in the browser or on Node, and so they are able to replace purs bundle.

Points (1) and (2) mean that PureScript users can run their code in the browser and on Node without requiring any additional tools, and point (3) means that users can get effective dead code elimination without using the PureScript bundler.

My understanding is that there is little appetite among the compiler team for sinking engineering resources into the bundler; this is part of why ES modules support has taken so long. @kl0tl, the author of the ES modules PR to the compiler and member of the core team, has indicated their preference for removing the bundler.

Unfortunately: users would no longer get effective dead code elimination without external tooling. Still, I don't think this is much of a problem, because:

  1. Dead code elimination is not necessary during development (it's typically an optimization needed for production builds)
  2. It is already a best practice to rely on external tools for dead code elimination (namely, Zephyr).
  3. Every production project I'm aware of (other than Try PureScript) already uses a JS bundler like Webpack or esbuild, which will perform the dead code elimination on the JS on your behalf.
  4. If you have any JS dependencies in your PureScript project, then you already must use a JS bundler like Webpack or esbuild (or take your FFI dependencies via a CDN, which is exceedingly uncommon).

Proposal

Therefore, my proposal is that we remove the bundler altogether as part of supporting ES modules. The purs bundle command would be completely removed and the compiler would only produce the output directory. Downstream tools like Spago could implement their own spago bundle commands that rely on an industry-standard JS bundler like esbuild or webpack.

There is an issue on Spago tracking the spago bundle command.

Examples

The ES modules working group is producing more examples of the ES modules compiler being usable with bundlers like esbuild or snowpack or webpack, and the compiler being usable for unbundled development, but preliminary results show that JS bundlers are competitive with purs bundle.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions