Skip to content

Modify purs bundle to just accept an output directory as input, and typecheck main during bundling #3621

Description

@hdgarrood

At the moment, purs bundle accepts as input a list of JS files, but it can only accept JS files which are from a compiler's output directory. It needs to handles regular JS output modules and FFI modules differently, so in order to decide which kind of module it has received, it looks at the file path; anything called index.js is treated as a regular output module and anything called foreign.js is treated as an FFI module. If a file is called something other than index.js or foreign.js, we throw an error.

Since purs bundle only works with JS files which are from a compiler's output directory, I would like to modify its CLI so that instead it only needs to accept an output directory rather than a list of files. That way, we avoid having to leak details of the format of the compiler output directory to the extent that we do now. It also better communicates that purs bundle is specifically for PureScript compiler output and not any old collection of JS files. This in turn makes it easier to justify having purs bundle inspect externs files when it is asked to generate code to call main, to make sure that the module designated as the main module does in fact export main and that main has an appropriate type.

We previously discussed typechecking main during bundling in #2086 and decided that it would be better for external tools to do this. After reflecting on this more recently though I've changed my mind: currently pulp is forced to poke around inside externs files to achieve this, and I think this is a worse state of affairs because the externs files are not part of the compiler's public API.

Here's a concrete proposal:

  • Modify purs bundle so that the first argument is a PureScript compiler output directory. For the sake of backwards compatibility, if we receive more than one argument on the command line, infer the location of the output directory by finding the common prefix of all the files provided. In this case, we should also print a warning that the old CLI (i.e. providing a list of JS files) is deprecated.
  • If we have been requested to generate code to call main, use the externs files to check that the designated main module exports main, and that the type of main matches Effect a before producing JS output. Note that this will not be quite the same as a regular "do these types unify" check, because e.g. main :: Partial => Effect Unit or main :: MonadEffect m => m Unit should both be rejected, because their runtime representation won't conform to what we need: namely, a nullary function which performs the effects of main when invoked.
  • Add an option or options to purs bundle to allow using types other than Effect for this check, or for disabling the check entirely. Pulp currently does this with --check-main-type TYPE option which allows you to provide a type to use instead of Effect, and a --skip-main-check flag which allows you to disable the check entirely; unless anyone has any objections I'd suggest using the same scheme here.

If we agree that this is a good idea we should probably implement these two things separately; I just opened one issue because I thought it would make sense to discuss them together.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    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