Can one load reasonml es6 modules without a bundler

bsb

#1

I am trying to use my VSCODE liver server: vscode-live-server for development without having to run a (parceljs would be my favorite, since it has hot loading, but it is having issues with reasonml).

This almost works, but the the bucklescript compiler expects that the the node-modules to be on the path, and it appears bundlers find them, but not if one does a load this way:

##es5index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset=utf-8>
  <link rel=stylesheet href="./style.css">
  <title>Web Data Client</title>
  <script src="../src/client/App.bs.js" type=module></script>
</head>

<body>
  <div id="index"></div>
</body>

</html>

This is the error I get:

Uncaught TypeError: Failed to resolve module specifier "bs-platform/lib/es6/array.js". Relative references must start with either "/", "./", or "../".

which is to be expected since BSB created this in

App.bs.js

// Generated by BUCKLESCRIPT VERSION 4.0.18, PLEASE EDIT WITH CARE

import * as $$Array from "bs-platform/lib/es6/array.js";
import * as Block from "bs-platform/lib/es6/block.js";
import * as Curry from "bs-platform/lib/es6/curry.js";
import * as React from "react";
import * as Glamor from "bs-glamor/src/glamor.js";
import * as Js_exn from "bs-platform/lib/es6/js_exn.js";
import * as Js_dict from "bs-platform/lib/es6/js_dict.js";
import * as Js_json from "bs-platform/lib/es6/js_json.js";
import * as ReactDOMRe from "reason-react/src/ReactDOMRe.js";
import * as Caml_option from "bs-platform/lib/es6/caml_option.js";
import * as ReasonReact from "reason-react/src/ReasonReact.js";
import * as Editor$Webdataclient from "./Editor.bs.js";
import * as Loader$Webdataclient from "./Loader.bs.js";
import * as Mutations$Webdataclient from "./Mutations.bs.js";

now if the imports had were from the …/node-modules/* folder, I think all would work

bsconfig.json file:

// This is the configuration file used by BuckleScript's build system bsb. 
// Its documentation lives here: http://bucklescript.github.io/bucklescript/docson/#build-schema.json
{
  "name": "webdataclient",
  "version": "0.1.0",
  "sources": [
    {
      "dir": "src",
      "subdirs": true
    }
  ],
  "package-specs": {
    "module": "es6",
    "in-source": true
  },
  "suffix": ".bs.js",
  "namespace": true,
  "reason": {
    "react-jsx": 2
  },
  "refmt": 3,
  "ppx-flags": [
    "graphql_ppx/ppx"
  ],
  "bs-dependencies": [
    "reason-react",
    "bs-fetch",
    "bs-glamor"
  ]
}

Maybe I could use this shim:


#2

You can try using "module": "es6-global". https://bucklescript.github.io/docs/en/build-configuration#package-specs

"module": "es6-global" resolves node_modules using relative paths. Good for development-time usage of ES6 in conjunction with browsers like Safari and Firefox that support ES6 modules today. No more dev-time bundling!


#3

I tried that, and I am getting further, but the load of react is failing, Seems to be the only one.

import * as $$Array from "./../../node_modules/bs-platform/lib/es6/array.js";
import * as Block from "./../../node_modules/bs-platform/lib/es6/block.js";
import * as Curry from "./../../node_modules/bs-platform/lib/es6/curry.js";
import * as React from "react";
import * as Glamor from "./../../node_modules/bs-glamor/src/glamor.js";
import * as Js_exn from "./../../node_modules/bs-platform/lib/es6/js_exn.js";
import * as Js_dict from "./../../node_modules/bs-platform/lib/es6/js_dict.js";
import * as Js_json from "./../../node_modules/bs-platform/lib/es6/js_json.js";
import * as ReactDOMRe from "./../../node_modules/reason-react/src/ReactDOMRe.js";
import * as Caml_option from "./../../node_modules/bs-platform/lib/es6/caml_option.js";
import * as ReasonReact from "./../../node_modules/reason-react/src/ReasonReact.js";
import * as Editor$Webdataclient from "./Editor.bs.js";
import * as Loader$Webdataclient from "./Loader.bs.js";
import * as Mutations$Webdataclient from "./Mutations.bs.js";

#4

I dug into it some more, and it looks like BuckleScript can’t do this when there are external modules, including React. The relevant GitHub issue is here.

(Also answered on the SO question.)


#5

AFAIK ReasonReact always gets built as CommonJS, and React itself does not have an ES6 distribution. For a small project that uses Preact (which has a ES6 bundle), I was able to achieve this with some small changes.

Edit: I guess you’d still need a bundler to use preact-compat in this scenario, since preact-compat imports preact thus depends on Node.js module resolution. I’m guessing with React or Preact, you might be able to use moduleserve like the starter template does: https://github.com/BuckleScript/bucklescript/blob/master/jscomp/bsb/templates/react-hooks/index.html#L18

The only time I was able to get es6-global build work out of the box with browser-native module support was when I used bucklescript-tea, which is a pure Reason library that does not depend on any npm packages.