Reason is not only a statically typed but also a functional language, with concepts like immutability and type inference built right into the language. No longer you will need to reach outside of your toolbox for things like ImmutableJS, Flow, Prettier, Lodash, etc. It all comes out of the box as part of the language.
The developer experience using Bucklescript is fantastic because it is fast, very fast. The compiler is optimized to do some impressive things, including incremental compilation in milliseconds while you modify your code and powerful type inference.
Bucklescript also has a bridge called FFI (Foreign Function interface) which allow us to interact with all of the NPM ecosystem. The only thing we need to do to work with an existing NPM package is using an existing binding package or creating your own if one does not exist.
React has finally come full circle from it’s alpha implementation which was done in StandardML, a language in the same family as ReasonML and OCaml.ReasonReact is of course the implementation of React in ReasonML. As you will see, there are a lot recognizable patterns from React, although there has been some improvements along the way.
There are a couple of ways to setup a new ReasonReact project, one of them is using a script similar to create-react-app (https://github.com/reasonml-community/reason-scripts) which we won’t cover here. I personally feel this way of generating a project, is too restrictive and obfuscates many of the internal workings that I like to have access to.
Instead we will be using Bucklescript to generate our project.
We first need to install the Buckscript compiler:
If you have an old version of Bucklescript installed, it is recommended that you remove the old version before installing the new one.
Once that is installed we can generate a reason react project and cd into the new folder:
Notice that there is a package.json file like any other npm based project. In it you can see that webpack, react and the bsb compiler are being installed.
There is a new file called bsconfig.json which holds the configuration settings for the Bucklescript compiler. In it you can find where the source files reside, dependencies and what kind of suffix to use for the compiled code among other things. You can find out what all these settings are by checking out the docs: https://bucklescript.github.io/docs/en/build-configuration#docsNav
There is a src/ folder containing the Reason code and an index.hml file.
Let’s install all the node dependencies of this project.
Let’s compile them by running the bsb compiler manually:
This folder will contain Ocaml intermediate compilation files which we can safely ignore for now.
Now we need to run the webpack to generate a js bundle:
Now we can open the index.html file inside our /build folder in our browser and see our first ReasonReact component.
As exciting as this was, we still don’t have a great user experience. For starters we need to rerun the Bucklescript compiler and the webpack in order to get any changes reflected on screen. Also it would be nice if we can run the app on webpack-server instead of opening it directly from disk. The final icing on the cake would be if we get hot-reloading working to see our code changes reflected immediately on the browser.
We can start by running the Bucklescript compiler with a watch flag on so that all our changes to Reason files will be immediately compiled.
Fortunately for us, the latest version of this project theme already comes with webpack-dev-server installed and ready to go.
Let's run it:
Now let’s run the Bucklescript compiler to watch for changes in the ReasonML files. Make sure you run this in a separate terminal window.
Now you can go to the browser and load the app from: http://localhost:8000/
In order to get the Hot Module Replacement going we will need to make a couple of changes in the webpack.config.js
First we need to change the publicPath configuration to ‘/‘, this will for webpack to use the memory stored version of the index.html and not the one on the /build folder. In fact we can now delete this folder and it won’t matter.
The second change is that we need to get rid of the inject: false line on the HtmlWebpackPlugin configuration. This will default to true and will enable us to reload the html when changes are detected.
Notice we don’t need to add hot to true under the devServer settings by default the latest webpack-dev-server will be hot reloading.
Make sure you re-run webpack-dev-server and then try to change the text of the src/Index.re file from a "Hello" to a "Bye". The app should reload automatically and instantly on your browser.
Now you have a fully working ReasonReact environment complete with webpack-dev-server and hot reloading. Note that most of the commands above do have a package.json shortcut that you can use via yarn or npm.