UPDATE 12/7/2019: This article, and accompanying GitHub repository, has been update to reflect email@example.com
UPDATE: This article, and accompanying GitHub respository, has been updated to reflect firstname.lastname@example.org, email@example.com, and firstname.lastname@example.org
I scoured the web for a decent development environment for a reason react web application with some success. I first started with reason-scripts, since I come from react land and was accustom to “convention over configuration” with create-react-app. Initially it was a success but eventually, I ran into compiling issues. At times it would compile with errors and other times it wouldn’t. This back and forth of saving and waiting for it to compile, or error out, was hampering the speed at which I could develop. I knew I had to find something else.
I then found razzle with an accompanying with-reason-react setup. I really love the work Jared Palmer does so it was awesome to find this setup. But this too came with its own trade-offs. For example, it uses an older version of bs-platform so it was out of date with some libraries. Even though I felt constrained using razzle it did give me ideas for how to build my own dev environment with bs-platform and webpack.
ReasonReact is still in its early days and with that comes a lot of instability and changes. If you are beginning to use ReasonReact yourself it’s probably better to create your own setup that you can control in order to move quickly with the changes that are occurring in the ecosystem. This tutorial aims to help get you started in order to do just that.
Pro-tip: If you are using vscode and would like editor intelligence check out reason-vscode.
First initialize the project with yarn.
yarn init -y
Next, install the dependencies for the project.
yarn add email@example.com firstname.lastname@example.org reason-react bs-css normalize.css
Next, install the dev dependencies.
yarn add --dev @babel/core @babel/preset-env @babel/preset-react babel-loader bs-platform clean-webpack-plugin concurrently html-loader html-webpack-plugin webpack webpack-cli webpack-dev-server style-loader css-loader
Nowadays I like to keep the folder structure of my applications as flat as possible. Only when explicit and discernible patterns emerge will I start to place files in separate folders. This prevents the app from becoming too rigid at the start, which makes it easier to change later on.
Here is what the folder structure will be for this application:
. ├── lib │ └── es6\_global │ └── src │ └── App.js ├── src │ ├── App.re │ ├── client.js │ └── index.html ├── .gitignore ├── .merlin ├── .node-version ├── .nvmrc ├── .yarnrc ├── README.md ├── bsconfig.json ├── package.json ├── webpack.config.js └── yarn.lock
Pro-tip: To create a tree structure like what I have above I ran the mac os command
tree -a --dirsfirst -I ‘node_modules|bs|.git’on my directory.
Let’s get the simple stuff out of the way first. The
.merlin file is auto-generated. If you read through it, you will see it points to the local reason libraries, found in
node_modules, the BuckleScript compiler will use in order to compile the modules correctly. The compilation process is also based on the settings found in the
bsconfig.json file. Obviously,
yarn.lock lists the exact dependencies of the project, which creates more deterministic builds. A condensed version of the dependencies and dev dependencies are listed in
package.json. Our webpack config is found in
webpack.config.js. I wanted to lock down dependencies and the node engine so I added
Now the not so obvious stuff. The
lib folder. The
index.html file will be a template and you will use
html-webpack-plugin to inject the bundle script into the markup. The
build folder will be where your output goes. It’s not as important for development as it is for production.
In order to use reason how you would like to you need to set up a
More information about the
bsconfig.json spec can be found here.
Next, you will need to set up your webpack config.
Now you can start writing some reason. Create a simple stateless reason component and export it so it can be used inside of
In order to get this to work, you need to run some commands. You will put these commands inside of the
scripts property in
package.json for convenience.
The secret sauce here is using
concurrently. When files change in reason, BuckleScript will update those changes in the
client.js to change, which webpack will recompile using hot module replacement. Pretty cool, huh?
yarn start to see if this actually works. If it doesn’t, then go to the repository here and clone it 😄. If it does work, good for you, you know how to copy/paste really well.
Type Safe CSS 🎨
I want to briefly show how you can write type safe styles in ReasonReact using
bs-css. I will create some styles using
bs-css syntax which will highlight some of its features.
The first thing you probably noticed with the styles is that they are in camelCase, same as if you were writing them using the DOM or as a style prop in React. However, there are parentheses after, not colons. This is because the style declaration is a function. The function will take a parameter but the parameter needs to be type safe as well. For example, for the property
maxWidth, it accepts a
Css.length. Here I am using
px for pixels that accepts an
int, aka integer. You can also write this as
px(500) as well. Type in a float instead of an integer, for example
500.0, and see the compiler yell at you.
This expression has type float but an expression was expected of type int
You probably also noticed labeled parameters like
~v. In the case of
margin2, this stands for the vertical margin, whereas the
~h stands for the horizontal margin.
And lastly, you noticed the styles can be dynamic as well. Simply create a function and pass in the parameter in order to make the style change based on what is supplied.
In this article, you learned how to “easily” set up a ReasonReact project. Hopefully, this gets you up and running without too much hassle. Along the way, I hope you learned the importance of each file and configuration decision. From here you can build out a simple front-end application. If you are inspired to do more such as server-side rendering then check out razzle and gain inspiration from their setup.