ReasonML with Phoenix?

Why didn’t you use the React OCaml library, like it is used here for instance ?

Because React has a few issues that I really don’t agree with, one is that it is substantially slower than mine, much heavier code to bring in (substantially larger), much longer startup time, and it’s not very functional (in the functional programming sense).

1 Like

Kind of let my “looking into React” slide but recently went back to some tutorials that I had lined up in my queue - but I have been doing them with ReasonReact instead.

I find Bucklescript/ReasonML really makes it obvious when React is being sloppy (sometimes things get ornery in a “I’m sorry Dave, I’m afraid I can’t do that” way.).

For one there’s no setState in ReasonReact - you have to use a reducerComponent with and reducer function that returns a ReasonReact.update type.

There is no Redux integration because it has it’s own Reductive library.

Personally, I don’t see the react-router bindings going anywhere. As far as I can tell react-router has a tendency to introduce deep coupling into components - in ReasonML it makes far more sense to capture the URI essentials in a variant at the top level and to convert it as required as it gets closer and closer to the leaf components.

And JSX seems even more loosey-goosey than usual - for the time being ReasonReact.element and ReasonReact.createDomElement make frequent appearances - to the point where you wish people would just realize that JSX isn’t markup but just source for a code generator (so can we just let go of the pretense).

So depending on how serious FB is about ReasonML, it may actually cause React to clean up it’s act (or at least lead to an alternate, cleaner interface for ReasonML).

Aside:

People are reading way too much into Presentational vs Container components divide. Almost regretting I wrote that.

Dan Abramov referring to Presentational and Container Components.

In a way this seems to be in line with Elm’s “no components” stance. Traditionally people expect components to combine the presentational and behavioural UI aspects. Container/Presentation splits the traditional “visual component” into two separate responsibilities.

I was talking about the OCaml FRP library here, not Facebook React. This TodoMVC example shows how it can be used to implement something close to what Elm gives you

Hmm, a few things I immediately notice, first it seems to be far more verbose (more like the old Elm <0.16 way, which used signals/frp instead of the event processing model that it and I use now), and it looks like loops could happen where mine prevents that by holding messages if one is already being processed. where with FRP that is significantly harder to do properly and user code can easily break it (this was a problem elm had in older versions as well).

Remember, Elm is not FRP.

yes I agree it is more verbose, React is a general purpose FRP library and there, they implement TodoMVC the way it would be done in Elm… but I thought it looked OK

As they implemented it, it looks very close to how it was done in Elm back in 0.16- versions, 0.17 had the overhaul that got rid of FRP.

1 Like

Does anyone have an up to date version of how to use bucklescript with Phoenix and brunch? I’m running into some issues that I can only assume are unique to brunch.

In particular, if I set the module output to es6-global it seems to find all modules in node_modules correctly, but then brunch complains that imports cannot be done outside of a top level context (from bs-webapi). If I use the commonjs modules I get complaints about bs-platform not being available on page load. Any solid resources on how to use bucklescript with phoenix and brunch?

P.S: I likely won’t be able to change the JS build system on this project, so I kind of need it to work out with brunch even though I’d rather switch to something else.

Don’t use brunch for that part, just use bucklescript’s own watcher added to the phoenix definition (you can have multiple watchers listed), and have brunch just watch the output javascript directory (make sure to have brunch’s npm integration enabled in the config, it ‘should’ be by default), easy-peasy then. :slight_smile:

Ok, just to sort of expand on the scenario:

I want to use brunch just as we have previously, but I want to import code written in OCaml/Reason for use in the compiled brunch files.

What is happening currently, even though things seem to be compiling fine (I run bsb on the side and compile those file into the bundle currently) is that I get this runtime error:

Error: Cannot find module 'bs-platform/lib/js/curry.js' from 'bs-webapi/src/dom/nodes/ElementRe.js'  requestWait.js:61:11

Which suggests this way of simply compiling the files on the side and including them as just another JS file is not working.

It was told to me that this would be helped by the global module type in bs (es6-global is one such way and it will according to the bucklescript channel on discord check properly in node_modules). I don’t particularly care to have brunch deal with everything, I really only need this to work alongside it and currently it doesn’t seem to be happening.

This just means that brunch cannot find the npm files, don’t think this is a bucklescript/reason issue at all. Are you able to import other npm files via an ES6 javascript file directly? That’d definitely be the first thing I’d test.

I suppose it is possible that if BuckleScript is globally installed Brunch may not be able to find the packages.

Maybe npm link bs-platform etc.? If Brunch follows links …

Absolutely do not use globally installed packages with brunch. In fact never use globally installed bucklescript at all as it’s API has a tendency to break from version to version and thus a project that ‘was’ working suddenly does not work. You should put all NPM dependencies for a project (including bucklescript) as a devDependency in the packages.json file for NPM. Anyone that says that bucklescript can safely be installed globally (including the author, I really don’t know where he gets the idea that this is safe, as you can plainly see with such an issue) should be ignored.

This is one of the reasons that I’m leaning back to the, though more unreadable output, but actually and properly consistent js_of_ocaml over bucklescript. The gain in readability from bucklescript is not worth the breakages it keeps doing, especially it’s DSEL attributes it keeps adding all over the place.

Better yet I want webassembly to become in higher use now, that is the end-game way to go, and bucklescript won’t work there as it is, but js_of_ocaml (via normal ocaml) will.

Quickstart · Reason

So one basically has to assume that people will install it globally.

bs-platform is installed as a dev dependency and is present in node_modules. I also tried just now to use lodash because I saw it in there as well and that works without issue just after an import. Just to re-iterate: It loads bs-webapi that then tries to import bs-platform but fails, so I don’t think that the node_modules availability is really the issue here.

This issue looks similar

Can't find list.js · Issue #3 · glennsl/bs-json · GitHub

and unfortunately wasn’t resolved.

I have no idea how Brunch works internally … but lodash being strictly a library would be listed under dependencies. bs-platform being a transpiler, a tool is under devDependencies - but it also contributes libraries that are technically dependencies. Now in terms of npm package organization this may be a valid thing to do - but I have to wonder whether that structure is violating some assumptions that Brunch is making internally (technically one would assume that any library under node_modules that is imported somewhere would be bundled, as it would to seem to be more work to constrain it to packages that are listed under dependencies).

The differences between dependencies and devDependencies is that devDependencies are available to everything at non-server-running time, and dependencies are available at all times, regardless of a nodejs server running or not. Since the nodejs server is not used as a server with Phoenix then it doesn’t matter, it works with brunch regardless. :slight_smile:

I’m using an older bucklescript version at work though since they keep doing questionable things later, but it definitely works here, and I did use it with brunch at one point, but currently it is just passed to rollup for packing (which works so much better than brunch, pass the files to rollup then to babel).

Are you able to import one of the bs javascript files into a javascript module too?

1 Like

I’m unable to import both bs-webapi and bs-platform even though I can use both of these in the build process with bsb and they’re both present in the node_modules directory.

Funnily enough I saw on the discord server that this issue with modules not being available actually was solved (by some people) by linking to a global install of bucklescript instead of having it in the node_modules directory. Just to see if that was the case now I tried it as well, but to no avail.

1 Like

Hmm, maybe compare the pathing to ones that do work and see what differs?

Out of curiosity I tried using bs-fetch as a dependency to see if this was a general issue with using bs dependencies and it works without issue. As soon as I use anything from bs-webapi I get that error on page load.