Skip to content

Node.js development with figwheel

Julien Gonzalez edited this page Nov 23, 2019 · 16 revisions

Content

  1. Node.js standalone application development with figwheel
  2. Node.js module development with figwheel

Node.js standalone application development with figwheel

(Last tested with: clojurescript "1.8.51", figwheel "0.5.14")

You want to write a program in Clojurescript that you can run with Node and you want to connect figwheel to it. You need to:

  1. Create a ClojureScript Node script f.ex. as described in the Cljs Quick-Start guide (but using Leiningen for builds)

A minimal script:

;; ./server_src/figwheel4node_server/core.cljs
(ns ^:figwheel-always figwheel4node-server.core
  (:require [cljs.nodejs :as nodejs]))
(nodejs/enable-util-print!)
(println "Hello from the Node!")
(def -main (fn [] nil))
(set! *main-cli-fn* -main) ;; this is required
  1. Add :target :nodejs to the build so that it will create the required goog/bootstrap/nodejs.js:
;; ./project.clj
(defproject figwheel4node "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [org.clojure/clojurescript "1.7.107"]]
  :plugins [[lein-cljsbuild "1.0.6"]
            [lein-figwheel "0.3.9"]]
  :clean-targets ^{:protect false} ["target"]
  :cljsbuild {
    :builds [{:id "server-dev"
              :source-paths ["server_src"]
              :figwheel true
              :compiler {:main figwheel4node-server.core
                         :output-to "target/server_out/figwheel4node_server_with_figwheel.js"
                         :output-dir "target/server_out"
                         :target :nodejs
                         :optimizations :none
                         :source-map true }}]}
  :figwheel {})

Thanks to :main, the resulting figwheel4node_server_with_figwheel.js connect script will contain all the necessary imports etc. (in addition to an invocation of figwheel.client/start) to be runnable directly by Node.

  1. Install dependencies (figwheel will warn you if missing):
npm install ws
# Optionally: npm install source-map-support
  1. Start figwheel (which will compile the code and insert figwheel.client/start call to it)
$ lein figwheel server-dev # or rlwrap lein figwheel server-dev
#-> ...
#-> Figwheel: Starting server at http://localhost:3449
#-> Focusing on build ids: server-dev
#-> Compiling "target/server_out/figwheel4node_server.js" ...
#-> ...
#-> Prompt will show when figwheel connects to your application
  1. Start the Node application
$ node target/server_out/figwheel4node_server_with_figwheel.js
#-> Hello from the Node!
#-> Figwheel: trying to open cljs reload socket
#-> Figwheel: socket connection established

(At this point you should see the cljs.user=> prompt in the figwheel terminal)

To see the start of a reloadable express app in cljs look here: https://gist.github.com/bhauman/c63123a5c655d77c3e7f

Node.js module development with figwheel

You want to create a Node module that you can include in an existing Node (JavaScript) application and/or you want to connect figwheel REPL to an existing Node application.

Common

  1. Export the function from your Cljs code:
;; snippet of ./server_src/figwheel4node_server/core.cljs
(set! (.-exports js/module) #js {:hello #(println "Hello from ClojureScript!")})

Development build for figwheel

(Using the same build and code as in the standalone Node application section.)

  1. Use it from a Node code:
// ./main.js:
require("./target/server_out/figwheel4node_server_with_figwheel.js");
var cljs = require("./target/server_out/figwheel4node_server/core.js");
console.log("See ma, a JS object", cljs)
cljs.hello();
  1. Run it:

    $ lein figwheel server-dev $ node main.js

Production build

  1. Use it from a Node module:
// ./main.js:
var clj = require("./path/to/figwheel4node/target/server_out/figwheel4node_server_with_figwheel.js");
console.log("See ma, a JS object", clj)
clj.hello();
  1. Configure the build
;; ./project.clj snippet of :cljsbuild :builds
             {:id "server-prod"
              :source-paths ["server_src"]
              :compiler {:main figwheel4node-server.core
                         :output-to "target/server_out/figwheel4node-server.core.js"
                         :target :nodejs
                         :optimizations :simple ;; notice this!
                         }}
  1. Compile: lein cljsbuild once server-prod

  2. Run it: node main.js