ReasonML with Phoenix?

I’ve been in the same issue today while trying to use BuckleScript for the first time in a Phoenix + Brunch project. Adding a require("bs-platform/lib/js/curry.js"); in a JavaScript file bundled by Brunch works as a workaround. Though this is quite strange because ElementRe.js is bundled and contains exactly:

var Curry = require("bs-platform/lib/js/curry.js");

Does it work correctly with Webpack? I haven’t yet set up a working environment with it, but since Phoenix is migrating to it I consider using Webpack myself for new projects.

That particular issue had it’s continuation in this topic:

i.e. a similar issue cropped up with Rollup.

If I remember correctly it boiled down to (incorrect) mixing of JS module formats.

Rollup is ESM oriented, while Brunch needs CJS - so you have tweak the Bucklescript transpilation configuration accordingly.

In Rollup’s case, it was bothered by the transpiled (CJS-version) of phoenix.js and much happier with the non-transpiled ESM-version of phoenix.js.

So it wouldn’t surprise me one bit if success with webpack depends largely on getting the various output JS module formats all correctly lined up.

1 Like

Webpack is the only one that works out of the box, yes. Using it to bundle only the BuckleScript apps is what we do right now and there have been no issues whatsoever. Ideally we’d skip brunch alltogether but messing with something that works in the scope of JS is just inviting needless issues.

Here are some config files (some names changed because this is contract code):
webpack.config.js:

const path = require('path');

module.exports = {
  mode: "production",
  entry: {
    "app_one": "./bucklescript/app_one.bs.js",
    "two": "./bucklescript/two.bs.js",
    "three": "./bucklescript/three.bs.js",
    "example-app": "./bucklescript/example_app.bs.js"
  },
  output: {
    path: path.resolve(__dirname, "..", "priv", "static", "js"),
    filename: "[name]-bs.js"
  }
};

This means that our packaged apps will show up alongside our brunch bundles as <app-name>-bs.js and that’s how we’d refer to them in pages.

bsconfig.json

{
  "name": "project-name",
  "sources": { "dir": "bucklescript" },
  "generate-merlin": true,
  "bs-dependencies": [
    "bs-webapi",
    "bucklescript-phx",
    "@glennsl/bs-json",
    "bucklescript-tea"
  ],
  "package-specs": {
    "module": "commonjs",
    "in-source": true
  },
  "suffix": ".bs.js",
  "bsc-flags": [
    "-bs-super-errors -no-alias-deps",
    "-color",
    "always",
    "-w",
    "-40+6+7+27+32..39+44+45",
    "-w @8"
  ]
}

Watchers:

  watchers: [
    node: [
      "node_modules/.bin/bsb",
      "-clean-world",
      "-make-world",
      "-w",
      cd: Path.expand("../assets", __DIR__)
    ],
    sh: [
      "../priv/scripts/run-delayed-webpack.sh",
      cd: Path.expand("../assets", __DIR__)
    ],
    node: [
      "node_modules/brunch/bin/brunch",
      "watch",
      "--stdin",
      cd: Path.expand("../assets", __DIR__)
    ]
  ]

Note that if you use an earlier version of bsb it wasn’t suitable for using as a watcher so you’d have to run a script that took care of closing when STDIO closed, etc. The delayed webpack script is just a script that waits a bit for bsb to compile everything and then does packaging because it was easier than figuring out if there is a way to have webpack not complain about the entry points not being there.

For docker I’ve made a version of the build that precompiles the bucklescript compiler and never pulls it from npm and the bs toolchain compilation is cached, so making changes to the code really only means having the rest of the npm stuff taking time, not the super dumb “Oh, you don’t have an OCaml compiler, ninja and bsb? We’ll build all three” thing that happens. The only way I managed to get the behavior I wanted was by using yarn link to get the behavior I thought npm link should’ve been (npm overwrites links if you do npm install). This way you can get a set bsb version that works within the whole JS build flow for a cost you pay only when you change something foundational in your Dockerfile:

RUN apk update && apk --update upgrade && apk add [a bunch of stuff] opam parallel m4 yarn

RUN opam init && opam update && opam switch 4.02.3+buckle-1 && opam install cppo

RUN git clone https://github.com/BuckleScript/bucklescript bs \
    && cd bs && git checkout 3.1.5

RUN cd bs && eval $(opam config env) \
    && yarn install \
    && cd vendor/ocaml \
    && ./configure -prefix `pwd` && make world.opt && make install \
    && cd ../.. && make && make install && yarn link

...

RUN parallel "sh -c" ::: "mix local.rebar --force" "mix local.hex --force" && \
    eval $(opam config env) && \
    mix deps.get --only prod && \
    parallel "sh -c" ::: "MIX_ENV=prod mix compile" \
    "cd 'apps/project_name/assets' && npm install --global brunch && yarn link bs-platform && yarn install --production --prefer-offline && bsb -make-world && node_modules/.bin/webpack && brunch build --production"

There are probably hundreds of ways to get this behavior and they might well be simpler than this one. This one is what I found after messing around with it, though.

6 Likes

ive been using reason for 2 months and i kinda like it, well until i ran into a problem, the community.
is there a recommended way to use ocaml to compile to reactjs or something similar that i can use to go to native, the whole reason for using reason it its supposed to allow to native compilation thereby alievating me from having to dig into kotlin, my project makes extensive use of websockets, which was a pain in reason to which i documented and submitted a pr. however the response to the simpelist of issues i ask on their discord channel has made me never want to deal with their community again, im looking for a better solution and one with a community of mature adults that are willing actually help noobs onboard rather than alienate them while they silo their knoweledge and look down their noses at ye stoopid plebs.

I’ve generally seen the reason community be pretty nice, but they are definitely on the younger side. The OCaml community tends to be more mature, very much like the erlang community. I think elixir and reason mirror each other a big like how erlang and ocaml communities do. ^.^;

But yeah, to use OCaml just use bucklescript straight out (it has a fantastic build system that wraps all the ocaml old horror-tools). Or if you don’t need as much javascript foreign calls and/or want to compile some source-less ocaml code then JSOO (java-script-of-ocaml) is the way to go (but you gotta use the old ocaml tools then). :slight_smile:

/me is always a fan of freely giving all knowledge

1 Like

A fresh boilerplate with phoenix 1.4!

enjoy

3 Likes

The funny thing is when I first came to Elixir I was surprised at how experienced everyone was - part of the reason I started the forum actually was to get more people like me (non-experts!) into Elixir :slight_smile: But yeah, on the whole I think we’ve got a good mix here now - and particularly over the last couple of years we’ve attracted many more newcomers to Elixir and some to programming in general as well.

I can’t speak for communities like OCaml, but I guess they are simply not attracting the same number of people other languages are - hence the people in their communities seem to be getting older with time, with fewer young people entering. Again I cannot speak for other communities but I would not always correlate maturity with age - I have seen (and hosted!) communities predominantly aimed at older people and they have been far from what we might consider mature.

In terms of community spirit though @mithereal, I think you will be hard pressed to find a more happy and helpful community than in Elixir :003:

1 Like

Ya the elixir forums are awesome, but then again so is elixir. lots of that has to do with how good the support and docs are erlangs docs i find are harder to parse through than elixirs, therefore i didnt use it nearly as much as i use elixir. I think Reasons are a bear as concepts arent fleshed out but i wanted that ios and android app that the docs promised lol. I wonder what age group is mostly on here in terms of programming years.

2 Likes

2 posts were split to a new topic: What questions can we ask for our 2019 bump of our polls?

After a lot of suffering with webpack, I moved to parcel, and succesfuly added SASS :slight_smile:
so it’s a REASON-PARCEL-SASS-PHOENIX 1.4 boilerplate !

5 Likes