Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Learning ClojureScript

You're reading from   Learning ClojureScript Master the art of agile single page web application development with ClojureScript

Arrow left icon
Product type Paperback
Published in Jun 2016
Publisher
ISBN-13 9781785887635
Length 320 pages
Edition 1st Edition
Languages
Arrow right icon
Authors (2):
Arrow left icon
Allen Rohner Allen Rohner
Author Profile Icon Allen Rohner
Allen Rohner
W. David Jarvis W. David Jarvis
Author Profile Icon W. David Jarvis
W. David Jarvis
Arrow right icon
View More author details
Toc

Table of Contents (9) Chapters Close

Preface 1. Getting Ready for ClojureScript Development 2. ClojureScript Language Fundamentals FREE CHAPTER 3. Advanced ClojureScript Concepts 4. Web Applications Basics with ClojureScript 5. Building Single Page Applications 6. Building Richer Web Applications 7. Going Further with ClojureScript 8. Bundling ClojureScript for Production

Live coding ClojureScript with Figwheel

Figwheel ( https://github.com/bhauman/lein-figwheel ) is a Leiningen plugin that builds ClojureScript programs and delivers them to the browser for interactive evaluation. In contrast with nREPL-based work-flows, Figwheel does not rely on third-party REPLs. It is a self-contained library with its own ClojureScript REPL that relies on websockets to push your work to the browser as you edit your ClojureScript code. Figwheel also supports CSS live reloading in the browser, hence providing for a completely interactive web development experience. In this next section, we'll use Figwheel to get set up a ClojureScript live-coding experience on the browser.

Setting up Figwheel for browser live coding

Figwheel comes as a self-contained library that automatically builds and loads the generated JavaScript into the browser. This means we won't have to manually build the JavaScript that'll be pushed to the browser in order to establish the connection to the Figwheel REPL. Everything will be handled for us.

Let's begin by creating a new project that we will use to experiment with Figwheel:

lein new figwheel-project

We'll now need to change our project.clj file so that our project is aware of the lein-figwheel plugin:

(defproject figwheel-project "0.1.0-SNAPSHOT" 
  :dependencies [[org.clojure/clojure "1.8.0"] 
    [org.clojure/clojurescript "1.8.51"]] 
  :plugins [[lein-figwheel "0.5.1"]] 
  :clean-targets [:target-path "out"] 
  :cljsbuild { 
    :builds [{:id "dev" 
      :source-paths ["src"] 
      :figwheel true 
      :compiler {:main "figwheel-project.core"}}]})
        :asset-path "js/out"
        :output-to "resources/public/js/main.js"
        :output-dir "resources/public/js/out"}}]})

Create a file named core.cljs under src/figwheel_project/ so we can have a ClojureScript program that will be built and pushed to the browser. Code changes will be pushed to the browser automatically later on via this loaded file:

(ns figwheel-project.core) 
 
(js/alert "Hello from Figwheel!") 

As before, in order to load the compiled JavaScript that'll connect our browser to the running Figwheel process we need to have an HTML page. Since we're still compiling ClojureScript to the main.js file, we must load this file in order to get it evaluated in the browser. Create a greet.html file that you'll put in the root of your project. This page will contain the following:

<html> 
  <body> 
    <script type="text/javascript" src="main.js"></script> 
  </body> 
</html> 

Let's launch Figwheel. Note how this is done as a Leiningen plugin, and how we don't need to load a specific ClojureScript on top of an nREPL as we did with Piggieback:

lein figwheel

Your terminal should show a message that states that it is awaiting the client connection:

Prompt will show when figwheel connects to your application

For this, we are going to simply use the web server that comes embedded within Figwheel. Provided that we’ve put the previous greet.html in our browser. Open that HTML page as a regular file under the public/resources folder visit the following URL, http://localhost:3449/greet.html. As soon as the page loads, you'll see the greeting we programmed to show in the ClojureScript file, and once you've clicked on the OK button, you'll notice that the Figwheel invite is now showing a prompt accepting user requests for ClojureScript evaluation:

cljs.user=> _

Let's try to evaluate something in the browser. Type the following:

cljs.user=> (js/alert "Hi from Figwheel Again!")

Once again, this new greeting should pop up in your browser!

We've seen how it was easy to set up a browser live-coding session with Figwheel. In the next section, we'll experiment with Node.js evaluations.

Node.js interactive development workflows with Figwheel

Figwheel is mainly intended for the browser, and as such, configuring it to connect to Node.js is a bit trickier than what we just did. Since Figwheel does not rely on the core ClojureScript REPL or nREPL, and hence, there are some actions that need to be taken in order to add Node.js support to its default stack.

Getting Figwheel to provide a Node.js REPLs is a matter of preparing a special JavaScript artifact that, when run with Node.js, will implement a server that connects via websocket to a running Figwheel session. This server will evaluate the compiled JavaScript from the Figwheel REPL via the WebSocket connection. Let's implement this.

First create a new Clojure project and name it figwheel_node. Next, prepare the ClojureScript Node.js script that, once launched, will connect via a WebSocket to the REPL served by Figwheel:

(ns ^:figwheel-always figwheel-node-repl.core 
  (:require [cljs.nodejs :as nodejs])) 
(nodejs/enable-util-print!) 
(def -main (fn [] nil)) 
(set! *main-cli-fn* -main) 

Next, let's modify our project.clj file to target the Node.js runtime using the relevant bootstrapping library. We could configure the bootstrapping library ourselves, but instead we'll use a popular Leiningen plugin, Cljsbuild (https://github.com/emezeske/lein-cljsbuild), to automate this process for us. Let's add and configure it by editing your project.clj as follows:

(defproject figwheel-node "0.1.0-SNAPSHOT" 
  :dependencies [[org.clojure/clojure "1.7.0"] 
    [org.clojure/clojurescript "1.7.122"]] 
  :plugins [[lein-cljsbuild "1.1.0"] 
    [lein-figwheel "0.4.0"]] 
  :clean-targets ^{:protect false} ["out"] 
  :cljsbuild { 
    :builds [{:id "server-dev" 
      :source-paths ["src"] 
      :figwheel true 
      :compiler {:main figwheel-node-repl.core
                 :output-to "out/figwheel_node_repl.js"
                 :output-dir "out"
                 :target :nodejs
                 :optimizations :none
                 :source-map true}}]}
  :figwheel {})

Note that setting the figwheel-node-repl.core namespace as a main entry point will ensure that all the necessary imports are added to our compiled output before we execute any of the program logic via websockets. This way, the script can be painlessly run by Node.js.

Next, let's install the Node.js websockets client library, ws, so that our script can connect to the Figwheel session:

npm install ws

As we've done with the browser setup, launch the Figwheel REPL:

lein figwheel server-dev

As usual, you will see a prompt telling you that the Figwheel environment is awaiting a client connection. This time, the client will be the Node.js script we just developed. Launch it in a different terminal window from the one currently running our Figwheel server:

node out/figwheel_node_repl.js

At this point, you have two running environments: the Figwheel REPL, which now shows the cljs.user=> prompt and the Node.js process, which is actively evaluating the compiled JavaScript that is being pushed to it by Figwheel.

Let's evaluate, on the Figwheel REPL, the HTTP server we used in the previous sections:

cljs.user=> (def http (js/require "http"))
cljs.user=> (.listen (.createServer http
       #_=>                         (fn [req res]
       #_=>                         (do
       #_=>                         (.writeHead res
       #_=>                         200
       #_=>                         (js-obj
       #_=>                         "Content-Type"
                                          "text/plain"))
       #_=>                         (.end res
       #_=>                         "Hello World from
                                          Node.js http server!"))))
       #_=>                         1337
       #_=>                         "127.0.0.1")

If you visit the URL exposed by this HTTP server, http://127.0.0.1:1337, you should see a greeting from Node.js, meaning that the ClojureScript you typed in the Figwheel REPL has been successfully compiled to JavaScript and evaluated by the running Node.js process.

We've studied two alternatives for exposing ClojureScript REPLs-one of them based on nREPL with Piggieback and the other using a standalone REPL environment based on Figwheel. In the next sections, we'll talk about how to set up development environments for ClojureScript on Emacs.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image