Skip to content

Proposal: Load foreign code with ES Module Shims and import maps #263

Closed
@thomashoneyman

Description

@thomashoneyman

Try PureScript is going to have to be reworked when the PureScript compiler switches from CommonJS to ES modules for foreign code. This issue details a proposal for how to handle this rewrite.

Current Implementation

We currently parse through the generated JavaScript on Try PureScript to discover all dependencies present via require() statements. For every dependency we find we do one of:

  1. Load the JS from compile.purescript.org (for example, Data.EuclidianRing/foreign.js)
  2. Look up its URL from the Shim.purs file which lists CDN locations for some common FFI libraries like react, and then load the contents

Once we know what dependencies to load, we take their contents and insert them into the code iframe. Finally, we load their contents via the evalSources function in frame.js.

Issues

This code is no longer going to work. PureScript 0.15 will only work with ES modules, so the code in Shim.purs, Loader.purs, and frame.js will all need to be updated to work with ES modules instead of CommonJS modules -- in other words, there is no more require or module.exports; instead, there's import and export.

I also don't think we can instantiate the code the same way we do now, which I believe happens here:

new Function("module", "exports", "require", sources[name])(module, module.exports, require);

Finally, if we swap all the way over to ES modules, we lose all Internet Explorer support, which we have historically not wanted to lose.

Proposal: SystemJS

We're clearly going to have to rewrite how we handle foreign code in Try PureScript. After a brief discussion with @natefaubion on the PureScript chat I would like to propose that we use two technologies:

  1. SystemJS, which covers IE11
  2. Import maps, which are supported in SystemJS, including for IE11

The SystemJS documentation on import maps does a good job of explaining how we can use this tool to replace our existing shim + loader + frame.js setup. If I'm reading correctly, we'd strip out almost everything and move the contents of Shim.purs into an import map. We'd rely on SystemJS for everything else.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions