Welcome back! This article is the last part of the “Getting started with Fable” series, so if you missed the previous articles please visit:
- Getting Started with Fable
- Getting Started with Fable. Scaffolding
- Getting Started with Fable. CSS
- Getting Started with Fable. Routing
- Getting Started with Fable. Node.js
In this last article, I want to share the migration experience from Fable v2 to v3, deployment experience, and some thoughts regarding Fable as a technology.
Frankly speaking, there were no major issues during migration from version 2 to version 3 of the Fable library. For me it was a bit strange decision to move from the
npm infrastructure to
.NET infrastructure, but it doesn’t make a huge difference.
What you need to do is to create a
.NET manifest file and install
Fable by running these commands:
dotnet new tool-manifest dotnet tool install fable
The new manifest file will be generated. It should look something like this:
After that you can safely remove all fable dependencies from your node dependencies:
yarn remove fable-compiler fable-loader fable-splitter
Now, we need to take care of scripts in our
package.json, because they won’t work anymore:
"postinstall": "dotnet tool restore", "build:server": "node server-prepare && dotnet fable src/api -o dist/api", "start": "dotnet fable watch src/app.fsproj -o dist/app --run webpack serve",
Let’s go line by line. The first thing I’ve added is the
postinstall script. This script will ensure that we’ve restored our
.NET dependencies after restoring
npm dependencies. The second script is a bit more interesting. As far as now
Fable is a part of
.NET infrastructure and it should be executed via
dotnet runner we are no longer relying on
webpack as the main build tool. Yet, we still need to do some preparation tasks, like copying the
package.json file to our distribution directory. The file looks pretty simple right now, but of course, it can be extended with any additional tasks:
// server-prepare.js const fs = require('fs'); fs.copyFileSync('src/api/package.json', 'dist/api/package.json');
The last script is using
Fable‘s ability to run any script after the execution of the
Fable script is finished. But to make this script working we need to update the
webpack configuration. The first thing we need to do is to remove the
Fable mentions from it because now
Fable build is a separate script. The second change is about switching the code from the source code to
Fable‘s build output. Here is the resulting configuration:
Basically, that’s all the changes you need to do to upgrade a small project from
Fable version 2 to version 3.
Now let’s talk a bit about hosting the app. For this Proof of Concept, I’ve chosen the Heroku, but it doesn’t really matter.
The first thing you need to do is to create a new Pipeline:
Then you need to create 2 new applications inside this pipeline. The nice thing about Heroku is that now it supports the ability to link GitHub repository directly to the application for build and deployment automation.
Now let’s talk a bit about problems. The first problem is that Heroku still doesn’t have native support for the
.NET applications. Luckily it supports the
Docker containers so we can create one that we need:
The second problem is a bit more complicated and I was not able to find a good solution for it. The problem that Heroku still doesn’t support monorepo development. You can only have one
heroku.yml in your repository and it can only have one set of instructions for one application which is a bit problematic for our case. The only working solution I’ve found is to create a branch and change
heroku.yml in this branch. But I understand that this approach won’t work for anything other than PoC:
After adding these configurations you should be able to deploy both applications and make them work.
As I’ve mentioned earlier this is the last article in the “getting started with Fable” series. I’ve created a small Proof of Concept application using the stack of technologies I was interested in and was able to successfully deploy it to real servers. Unfortunately, I don’t want to continue this project due to a couple of reasons which I want to share with you.
The first important thing is that I was having hard times using Fable in a way a front-end developer wants to write a front-end application. I want to emphasize that it’s not about Fable being a bad technology it’s all about false expectations. I’m a big fan of
TypeScript. Currently, I’m looking for technology that can replace
TypeScript in front-end development (at least partially). In my opinion,
TypeScript is a sort of workaround, it’s definitely not a well-designed modern language, yet it’s very flexible and covers most of the
Fable is more about doing one thing and doing it great. This technology works perfectly with the
Elmish architecture, there are plenty of samples and guides. But if you want to use your past front-end experience to build a
Fable application you are unlikely to succeed. There is no information about building
Redux-like applications using
Fable or building
Node.js applications using
Fable. And again, I’m not saying that this is bad. It’s really strange to expect a person who knows the
.NET to transpile
.NET code to
Node.js environment. It’s what I want to do, it’s not what someone else expects.
The second thing is a personal one. I had issues with type definition files. Unfortunately,
Fable is missing a lot of type definitions. It’s a very common practice in front-end development to find some useful
npm package and add it to the application. And if you are using a TypeScript there is a huge chance that this package already has a type definition file available. If not it’s not a big deal, just cast the library to a special type called “any” and you are good to go. It’s not so simple in the
Fable world. I know that there is an automated tool for converting the
TypeScript type definition files into
F#. But I was not able to get it working, most of the time I was getting partially working type definitions with compilation errors and missing members. Taking into account that I’m relatively new to the
F# I was not able to quickly fix those issues. Of course, injecting
Fable code is much harder than in
So at some point, I’ve caught myself breaking through a lot of issues to write even a couple of lines of code. At this point, I’ve decided that the goal is achieved and I want to try something new.
Again, I’m not saying that the Fable technology is bad. It’s really great and if it fits your needs (
.NET back-end +
React front-end) you should definitely give it a try. It’s just not what I was looking for.
Thanks a lot for reading! I hope you enjoyed it. If you find this material useful, don’t forget to subscribe and share it with your colleagues and friends! Thanks!