Jul 17, 2018

Announcing BuckleScript 4.0 (Part One)

Hongbo Zhang
Compiler & Build System

Important: This is an archived blog post, kept for historical reasons. Please note that this information might be outdated.

Newest Changes

bs-platform 4.0.0 is released! It has some nice features that we want to share with you, a more detailed list of changes is available here

In this post, I will talk about a new development workflow, all toolchains are self-contained in bs-platform, Cristiano will talk about the new runtime encoding for optional.

A simple approach to accelerate feedback loop in a reliable way

For mordern day-to-day development, developers expect that whenever files are changed, the build process is re-triggered automatically and browser reloaded instantly, this feedback loop should be quick enough to make developers not get distracted.

What we have before this release is as below:

  • Source file changes detected by bsb watch mode, rebuild

  • Webpack noticed JS files modified, rebundle and update the browser state

Both bsb and webpack has a watch mode, but they are architectured in fundamentally different ways that they achive different levels of reliability.

In bsb watch mode, there is no long running memory-hungry process, so whenever a file changed, a fresh process is started very fast and dies quickly, our experiment shows that in practice, a long running bsb process can work for a week without going into bad state, and such feedback loop is still instant.

Webpack holds lots of objects in memory and running for a longtime, it results in less reliability and OOM from time to time.

Another complexity introduced by a JS bundler is that it explodes users directory structure, for beginners trying to get started with bucklescript, installing such huge amount of directories is intimidating. In a slow network, this used to result in installation failure.

We understand that existing JS bundler has a huge ecosystem and it is invaluable in production mode, but we are exploring whether we can provide similar or even more reliable development experience without introducing such complexity.

Below is a new workflow we are exploring in this release:

NodeJS module loader in browser

Instead of bundling the modules like normal bundlers, we provide a NodeJS module loader so that it simply reloads the module without bundling.

Note ideally this can be achieved using ES6 module spec, however, it is not practical due to following reasons:

  • Most dependencies are not strictly ES6 compilant, this is true even for libraries authored in ES6 style

JS
import {createElement} form "react" ; // not es6 compliant import {createElement} from "node_modules/react/index" // not es6 compilant import {createElement} from "./node_modules/react/index.js" // correct es6 module
  • ES6 modules does not allow an indirection, by introducing our own NodeJS module loader, we have an indirection and more meta-data about each module, so that we can do more reflection work in the future.

Loading in clean state without packing seems to introduce some redundant work, but on the contratry, it is very fast, it used to load 200 modules under 150ms, even better, since there is no cached state in a long running process, it is much more reliable.

WebSocket integration with bsb

We need a mechanism to communciate between browser and the build system so that whenever a rebuild finished, the browser get notified.

Instead of introducing more dependencies, we implemented a minimal websocket interface so that whenever a rebuild finishes, the weboscket clients which subscribe the port will get notified.

To conclude and try it out

So the proposed new work flow is as below: whenever a source file is changed, the bsb rebuild, if it build successfully, it will notify the browser to reload the NodeJS modules directly.

All the devtools are provided by bs-platform, the good thing is that there is no long running memory-hungry process, so that we expect it will deliver a more reliable and consistent experience.

You can try it out in bs-platform@4.0.0

SH
bsb -init test -theme react-lite cd test npm install npm start http-server # start a http server

Open localhost:port/index.html, changes the reason source code and expect the browser show the changes.

Want to read more?
Back to Overview