-
-
Notifications
You must be signed in to change notification settings - Fork 208
Using Figwheel with Web Workers
NB: This workaround probably won't be needed soon, see https://github.com/bhauman/lein-figwheel/pull/659
The Web Workers API provides a way to spawn additional javascript processes in supported browsers. Because Web Workers don't have access to the DOM, much of the development tooling we are used to won't work, but Figwheel can do it with a little help:
First, we add a build to produce the Javascript for the worker. Use a distinct source path from the one in your main application.
;; Main app dev build
{:id "dev"
:source-paths ["src"]
:figwheel {:on-jsload "figwheel-worker-example.core/on-js-reload"}
:compiler {:main figwheel-worker-example.core
:asset-path "js/compiled/out"
:output-to "resources/public/js/compiled/app.js"
:output-dir "resources/public/js/compiled/out"
:source-map-timestamp true
:preloads [devtools.preload]
:closure-defines {goog.DEBUG true}}}
;; Add one for the worker...
{:id "dev-worker"
:source-paths ["src_worker"]
:figwheel true
:compiler {:output-to "resources/public/js/compiled/worker.js"
:output-dir "resources/public/js/compiled/out_worker"
:source-map-timestamp true
:optimizations :none}}
We didn't provide a :main
compiler option in the preceding config, because the ClojureScript compiler expects a document
to be present so it can inject Closure directives. In development we'll need to bootstrap Closure ourselves with a script like the following bootstrap_worker.js
:
CLOSURE_BASE_PATH = "compiled/out_worker/goog/";
/**
* Imports a script using the Web Worker importScript API.
*
* @param {string} src The script source.
* @return {boolean} True if the script was imported, false otherwise.
*/
this.CLOSURE_IMPORT_SCRIPT = (function(global) {
return function(src) {
global['importScripts'](src);
return true;
};
})(this);
if(typeof goog == "undefined") importScripts(CLOSURE_BASE_PATH + "base.js");
importScripts("compiled/worker.js");
goog.require('figwheel_worker_example.worker');
In development, we'll point to this file to load our worker:
(defonce worker (js/Worker. "js/bootstrap_worker.js"))
With all that set up, launch Figwheel on both builds:
$ lein figwheel dev dev-worker
A full example application is available here.