Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Learning ClojureScript
Learning ClojureScript

Learning ClojureScript: Master the art of agile single page web application development with ClojureScript

eBook
$24.99 $35.99
Paperback
$43.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Table of content icon View table of contents Preview book icon Preview Book

Learning ClojureScript

Chapter 1. Getting Ready for ClojureScript Development

ClojureScript's promise is to bring the expressiveness and agility of the Clojure programming language to JavaScript developers. Having such power at hands means that teams working on single page applications—and on Node.js services as well—more productivity and less frustration.

But to be able to take complete advantage of this platform, we must grasp its inner mechanisms and, sometimes patiently, work our way towards the perfect ClojureScript live-coding environment. In this chapter, we'll cover the material necessary to achieve this objective.

We'll begin by studying the ClojureScript ecosystem, focusing on its compiler internals and talking about the Read-Eval-Print-Loop (REPL) it offers. We'll then present some alternative building blocks that make it possible to expose interactive ClojureScript development work-flows through third-party tools. We'll finally leverage all of this knowledge in order to build full-fledged, integrated, and interactive ClojureScript development environments. To get started with adopting this approach, we'll discuss the following:

  • Getting familiar with the ClojureScript ecosystem
  • Live coding ClojureScript on top of nREPL with PiggieBack and Weasel
  • Live coding ClojureScript with Figwheel
  • Setting up Emacs for ClojureScript development

Getting familiar with the ClojureScript ecosystem

At the heart of the ClojureScript's ecosystem lies the compiler. In this section, we'll gain an insight into its internals: what is its underlying architecture, how does it work, and how can its functioning be tweaked in order to allow for leaner ClojureScript development?

Inside the ClojureScript compiler

The ClojureScript compiler is a piece of Clojure software packaged as a JAR along with Clojure itself, so the package is self-contained and can be manipulated easily. As such, the ClojureScript compiler requires the JVM for its operation. Currently, as ClojureScript developers have baked in the compiler, among many other things, an integration mode for Nashorn, the Java 8 embedded JavaScript engine, they recommend using the same version of the JVM. But, Java 7 is sufficient for the sole operation of the compiler.

Note

A bootstrapped version of ClojureScript, that is, one that uses pure ClojureScript for compilation, has recently been released. Cljs-bootstrap ( https://github.com/swannodette/cljs-bootstrap ), at the time of writing this, is still a work in progress, and offers worse performance than the JVM mainstream compiler. Besides, bootstrapped ClojureScript does not allow for the advanced compilation flags that its JVM counterpart offers.

At its most stripped down definition, the compiler accepts ClojureScript code, that is, mainly s-expressions obeying some Clojure subset semantics, and emits JavaScript artifacts that are passed on to the Google Closure Library ( https://developers.google.com/closure/ ) in order to get it "polished".

The Google Closure Library is a set of JavaScript optimizing tools open sourced by Google, which it uses to support the development of its JavaScript-rich applications, such as Gmail or Maps. Using this library has the following benefits:

  • It abstracts away the effort of managing inconsistencies across the many JavaScript engines of the market.
  • It takes advantage of the Google Closure's complete program optimization with features such as JavaScript minification or dead code elimination.
  • It exposes the namespace functionality, which is otherwise unavailable in Vanilla JavaScript. Actually, a ClojureScript namespace maps to a Google Closure namespace.

Now, let's see the ClojureScript compiler in action. To understand its fundamentals, we won't use any build-automation tooling such as Leiningen for the moment, though we'll for sure need it to construct our tooling later on. Let's begin by downloading the latest release of the compiler (1.7.48 as of the time of writing):

Note

Throughout this book, we assume that you are working on a POSIX compatible system, such as Linux or Mac OS X.

Create a new directory for your first project, label it cljs_first_project, and then download into it the compiler JAR:

mkdir cljs_first_project; cd cljs_first_project
wget \
https://github.com/clojure/clojurescript/releases/download/r1.7.48/cljs.jar

Once the compiler JAR is downloaded, you'll need to create a source directory and the path for your first namespace inside the project folder:

mkdir -p src/cljs_first_project; cd src/cljs_first_project

Now it's time to write your first ClojureScript namespace, which must conform to the path we're currently in (note that you should replace the underscores with dashes in the directory name). Type the following code in a file named core.cljs:

(ns cljs-first-project.core) 
(js/alert "Hello world!") 

This code just declares a namespace and the only operation that our program does is showing an alert popup with the familiar "Hello World!" greeting.

Now with the ClojureScript compiler being a Clojure library, we must write some Clojure code in order to trigger the building of the ClojureScript code we just wrote. Create a Clojure file at the root of our project (at the same level as the /src directory) and label it build.clj with the following Clojure code in it:

(require 'cljs.build.api) 
(cljs.build.api/build "src" {:output-to "out/main.js"}) 

Building ClojureScript is a matter of requiring the cljs.build.api namespace and then launching the build function that takes two arguments. The first argument is where to look for the ClojureScript source code to build, that is the src directory in our case, and second one is where to output the result JavaScript; out/main.js as far as this example is concerned.

With this helper Clojure program under our belt, we can launch the ClojureScript compilation process. It is about launching the embedded Clojure from the JAR we downloaded and passing to it the build program we just wrote. When we run Clojure this way, we make sure that the ClojureScript facilities are loaded, especially the cljs.build.api namespace. To be able to achieve this, we'll have to add the JAR we downloaded as well as the src directory to the classpath when we invoke Clojure with the help of the java command:

java -cp cljs.jar:src clojure.main ./src/build.clj

After you've run this command, you'll notice that an out directory containing our target main.js file has just been created. In order to launch the output JavaScript artifact, we'll need an HTML page, which when loaded into our browser will greet us with a popup. On our HTML page, we must surely load the generated main.js file, but we must also bootstrap the Google Closure Library by loading the out/goog/base.js script.

Also, note that the main.js file only contains a description of the different namespaces' dependencies managed by the Google Closure Library and no logic of execution. So, we must explicitly set an entry point to our program by telling the Google Closure Library to require a namespace to start with, and that's our cljs_first_project.core namespace (note how the dashes got transformed to underscores in the HTML page). Here's what the HTML page, which we'll store under the greet.html file, at the root folder of your project, looks like:

<html> 
  <body> 
    <script type="text/javascript" src="out/goog/base.js"></script> 
    <script type="text/javascript" src="out/main.js"></script> 
    <script type="text/javascript"> 
      goog.require("cljs_first_project.core"); 
    </script> 
  </body> 
</html> 

Accessing this page from your browser greets you with a JavaScript alert popup. Congratulations! You've successfully written and compiled your first ClojureScript program!

There are more advanced ways to work with the architecture of the build process. For example, to get rid of all the goog requires in your HTML page, you can tell the compiler in your Clojure build program which namespace should be set as an entry point, as follows:

(require 'cljs.build.api) 
(cljs.build.api/build "src" 
  {:main 'cljs-first-project.core 
    :output-to "out/main.js"}) 

This lets you strip the necessary script declarations in your greet.html page down to the following:

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

Another way to optimize the build process is to set the auto-build of your ClojureScript code on. The compiler can be triggered to be on the watch mode, thus recompiling the output JavaScript as soon as it observes any changes in the src directory. Set your Clojure build program to use the watch function instead of build, as shown here:

(require 'cljs.build.api) 
 
(cljs.build.api/watch "src" 
  {:main 'first-cljs-project.core 
    :output-to "out/main.js"}) 

We've taken quite a deep dive inside the compiler. But, to be able to keep the promise of bringing agile development to JavaScript land, ClojureScript ought to offer a REPL to its users, as any decent lisp would do. Let's discover how ClojureScript addresses this matter in the next section.

Working with the ClojureScript REPL

ClojureScript comes bundled with REPL support for the browser, Node.js, Rhino, and Nashorn. The REPL functionality can be triggered through a call to the repl function from the cljs.repl namespace present in the ClojureScript JAR. Just as we did for the building process, we must create a REPL launching Clojure program. In this program, we begin by building our project and then launch the interactive REPL session. Create a repl.clj Clojure program containing the following listing:

(require 'cljs.repl) 
(require 'cljs.build.api) 
(require 'cljs.repl.browser) 
 
(cljs.build.api/build "src" 
  {:main 'cljs-first-project.core 
    :output-to "out/main.js" 
    :verbose true}) 
 
(cljs.repl/repl (cljs.repl.browser/repl-env) 
  :watch "src" 
  :output-dir "out") 

Here, we'll build a REPL with evaluation on the browser, as we've used the cljs.repl.browser namespace. Note how we set the :watch option, so our REPL automatically gets fresh versions of the output JavaScript, providing for interactive ClojureScript code evaluation. The :output-dir directive tells the REPL where to look for generated artifacts so that they can be loaded into the relevant evaluation environment. As the interactive evaluation session goes, output of the compilation goes into out/watch.log, so we can follow along what's going on while the code interacts with the REPL.

Now, you must set a connection to the REPL inside your ClojureScript program, core.cljs. Once built, the resulting JavaScript program will stay in tune with the REPL environment, by pushing to the browser any changes made to the ClojureScript source:

(ns cljs-first-project.core 
  (:require [clojure.browser.repl :as repl])) 
 
(defonce conn 
  (repl/connect "http://localhost:9000/repl")) 
 
(js/alert "Hello world!") 

The connection has been defined with the defonce parameter to make sure that the same connection is used across the many builds that will occur while the user interacts with the REPL and triggers a new build per evaluation.

Now, launch the REPL, preferably using the rlwrap command, so the display on the terminal is properly rendered:

rlwrap java -cp cljs.jar:src clojure.main repl.clj

Be patient while the first build, involving the construction of the connection to the REPL, is completed. When it completes, you'll see the Waiting for browser to connect message in your terminal. Once you see this message, point your browser to the HTML page we prepared before (greet.html) now through http://localhost:9000/greet.html. Accept the first greeting popup and go back to your terminal; you'll see the following output:

Watch compilation log available at: out/watch.log 
To quit, type: :cljs/quit 
cljs.user=>  

Type another greeting to see if it gets automatically executed in your browser. Type in your REPL the following:

cljs.user=> (js/alert "Hello World From REPL!") 

You'll see new greetings from the REPL interactively popping up without hitting refresh on your browser:

Working with the ClojureScript REPL

So far, were able to come up with a ClojureScript REPL that empowered us to interact with the browser. But, we are far from having a full-fledged development environment yet; the terminal through which we are coding is quite limited, and we lack several essential features such as code completion, syntax coloring, source code exploration, refactoring, or version control management to name a few. We need a much more complete and fluid coding experience and that's what we will strive to achieve in the next sections. We'll begin by exploring the two most promising facilities that permit text editors or integrated development environments to take advantage from the ClojureScript REPL. Then, we'll showcase two Emacs setups based on those facilities-one based on CIDER and another one backed byinf-clojure.

Live coding ClojureScript on top of nREPL with Piggieback and Weasel

Network REPL (nREPL) ( https://github.com/clojure/tools.nrepl ) is a Clojure library designed primarily to offer remote Clojure code evaluation. It follows a client-server architecture in which the server exposes the REPL functionality by responding to client code evaluation queries. nREPL has been created to offer a means to the makers of development tools to connect and explore running Clojure environments in a way that is agnostic to the platform these tools may be running on.

Many prominent Clojure development tools rely on nREPL to implement their functionality. In fact, CIDER on Emacs or Cursive on Intellij IDEA, the most used tools for developing Clojure at the time of writing this, both rely on nREPL (CIDER relying more on nREPL for code introspection than Cursive).

Naturally, ClojureScript also benefits from nREPL.

Piggieback ( https://github.com/cemerick/piggieback ) is an nREPL middleware that seizes this opportunity. Piggieback hooks into nREPL and changes its operation so it can evaluate and load ClojureScript code, while being understandable to the vast majority of existing Clojure tooling. In the next section, we'll take a closer look at Piggieback.

Working with Piggieback

Piggieback changes the nREPL behavior to turn it into a ClojureScript remote evaluation environment. It does this by functioning as a middleware layer on top of nREPL. Let's see how to do this using Leiningen.

Note

Leiningen, the Clojure build tool, can be downloaded from  http://leiningen.org/ or https://github.com/technomancy/leiningen . You can also find detailed instructions and documentation on how to install and get started with Leiningen on both the sites. We'll be using Leiningen a lot in this book, so you'll definitely want to install it.

We'll use this project management tool to create a new Clojure project:

lein new piggieback_project

Then, we'll have to modify the project.clj file (where project-specific configuration is kept) in order to turn our project into a ClojureScript one, adding ClojureScript as a dependency:

(defproject piggieback_project "0.1.0-SNAPSHOT" 
  :description "FIXME: write description" 
  :url "http://example.com/FIXME" 
  :license {:name "Eclipse Public License" 
            :url "http://www.eclipse.org/legal/epl-v10.html"} 
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [org.clojure/clojurescript "1.8.51"]])7.228"]]) 

Now, it is time to add Piggieback into the mix. Add its dependencies and its middleware to the project.clj file:

(defproject piggieback_project "0.1.0-SNAPSHOT" 
  :description "FIXME: write description" 
  :url "http://example.com/FIXME" 
  :license {:name "Eclipse Public License" 
            :url "http://www.eclipse.org/legal/epl-v10.html"} 
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [org.clojure/clojurescript "1.7.228"]] 
  :profiles {:dev {:dependencies [[com.cemerick/piggieback"0.2.1"]

                                 [org.clojure/tools.nrepl"0.2.10"]]
  :repl-options {:nrepl-middleware
                 [cemerick.piggieback/wrap-cljs-repl]}}})

Piggieback is just an entry point to ClojureScript REPLs. Once we hook into our nREPL, we can operate in the same manner as we did when we were working with the REPL bundled with the compiler. Once again, we'll need to prepare a ClojureScript namespace that can define the connection to the REPL, and an HTML page that we can load into our browser. Create a core.cljs file under the src/piggieback_project folder:

(ns piggieback-project.core 
  (:require [clojure.browser.repl :as repl])) 
(defonce conn 
  (repl/connect "http://localhost:9000/repl")) 

Next, copy the greet.html file we wrote previously into the root of your new project.

We can now start an nREPL session. Type the following at the root of your project:

lein repl

In order to launch interactive code evaluation and loading in the browser, we must use some ClojureScript namespaces as to be able to hook Piggieback into our running nREPL session. We'll need to build the ClojureScript program we wrote at least once, so first we'll have to load the compiled JavaScript code to connect to the nREPL. Issue the following commands at the running REPL prompt:

user=> (require 'cljs.build.api)
user=> (cljs.build.api/build "src"
  #_=>   {:main 'piggieback-project.core
  #_=>    :output-to "out/main.js"
  #_=>    :verbose true})
user=> (require 'cljs.repl.browser)

We are now ready to hand over the code evaluation responsibility to Piggieback. Type the following:

user=>  (cemerick.piggieback/cljs-repl (cljs.repl.browser/repl-
      env))

You'll see that a JavaScript compilation process has been launched. It is our core.cljs file being compiled, and constructing a connection to the REPL. This will be our nREPL session—accessed through the JavaScript artifacts loaded via the greet.html page.

Once this operation has finished, you'll get the Waiting for browser to connect message that we previously encountered during our interaction with the REPL built by the ClojureScript compiler. As soon as you point your browser to http://localhost:9000/greet.html, you'll notice that the prompt has changed; it now shows the following:

cljs.user=>_

This means that the nREPL session has started accepting code to be compiled. The compiled JavaScript will automatically be evaluated on the connected browser. Try to generate a Hello World! popup from the browser from Piggieback this time:

cljs.user=> (js/alert "Hello World from Piggieback!")

And your browser says it with a popup, from your nREPL/Piggieback session.

We've now seen how we can change the nREPL's behavior so that it is turned into an entry point to the ClojureScript REPL. Code passed to the REPL executed on into the JavaScript environment-the browser in our context-via JavaScript files that are regenerated after each and every operation.

We can make this workflow even leaner by hot loading the JavaScript artifacts into the browser with websockets. This is what we will see in the next section, with the Weasel library.

Setting up Weasel with PiggieBack for browser live coding

Weasel ( https://github.com/tomjakubowski/weasel ) sets a up realtime communication channel using a websocket between a ClojureScript REPL and the JavaScript evaluation environment. The authors of this library say that choosing websockets as a means for delivering compiled JavaScript to runtime environments made it possible for them to profit from a simple and reliable transport. It also empowered them to reach a much wider range of JavaScript engines, especially those that don't properly support, the <iframe> tag (the main technology behind the vanilla ClojureScript browser REPL). Let's now add Weasel on top of the Piggieback-enabled nREPL environment that we've set up in the previous sections.

Let's first modify the piggieback_project file we worked on earlier to support Weasel by adding its dependency to the project.clj file:

(defproject piggieback_project "0.1.0-SNAPSHOT" 
  :description "FIXME: write description" 
  :url "http://example.com/FIXME" 
  :license {:name "Eclipse Public License" 
    :url "http://www.eclipse.org/legal/epl-v10.html"} 
  :dependencies [[org.clojure/clojure "1.8.0"] 
    [org.clojure/clojurescript "1.7.228"] 
    [weasel "0.7.0" :exclusions
      [org.clojure/clojurescript]]]
    :profiles {:dev {:dependencies
      [[com.cemerick/piggieback"0.2.1"] 
    [org.clojure/tools.nrepl "0.2.10"]] 
    :repl-options {:nrepl-middleware
      [cemerick.piggieback/wrap-     cljs-repl]}}})

Let's modify our ClojureScript code so that it can connect to the websocket opened by Weasel:

(ns piggieback-project.core 
  (:require [weasel.repl :as repl])) 
(when-not (repl/alive?) 
  (repl/connect "ws://localhost:9001")) 

Just like we did in the previous section, we'll need to connect to our nREPL and plug Piggieback in on top of it, but this time, we'll run it with a Weasel browser. After making sure that you are at the root of the project folder, type in a terminal:

lein repl

First, let's compile our ClojureScript source so we have our JavaScript ready to connect to the format as code websocket. Run the following from your nREPL session:

user=> (require 'cljs.build.api)
user=> (cljs.build.api/build "src"
   #_=>   {:main 'piggieback-project.core
   #_=>    :output-to "out/main.js"
   #_=>    :verbose true})

Next, we require the Weasel REPL namespace:

user=> (require 'weasel.repl.websocket)

We hook Piggieback onto the current session and ask it to use the Weasel websocket as the REPL environment (we also set the IP address and the port we want our websocket to be listening to):

user=> (cemerick.piggieback/cljs-repl
  #_=> (weasel.repl.websocket/repl-env :ip "0.0.0.0" :port
      9001))

After Piggieback is launched, Weasel shows a message to inform us that it is awaiting incoming connections:

<< waiting for client to connect ...

Open the greet.html file in your browser (you need to open it from the files manager on your OS, as we are not serving it over HTTP this time!). As soon as the file opens, you see the following message in your nREPL session:

<< waiting for client to connect ...  connected! >>

The prompt in your nREPL session should change to the following:

cljs.user=> _

As usual, let's salute the world and see if our greeting pops up in the browser:

cljs.user=> (js/alert "Hello World from Weasel!")

Your browser should now emit an alert with a greeting message on it.

Until this point, we have been able to put together a powerful environment for developing ClojureScript. Thanks to Piggieback being hooked on nREPL, we can benefit from the integrated development tools that already exist for Clojure. Before we go too much further on this subject, let's see how we can write ClojureScript programs that target other JavaScript environments. In the following section, we'll focus on setting up a Piggieback powered nREPL that evaluates code on the Node.js platform.

ClojureScript REPLs on Node.js with Piggieback

Setting up Node.js REPLs is simpler than targeting the browser. You don't need to set up connections from the REPL process to the browser with the help of some vanilla JavaScript. All you have to do is make sure that the source is compiled, and set the REPL target to Node.js, so that the compiled output is handed over to that evaluation environment for running.

First, make sure that Node.js is installed. Under piggieback_project, change the core.cljs file so that it looks like the following:

(ns piggieback-project.core 
  (:require [cljs.nodejs :as nodejs])) 
 
(nodejs/enable-util-print!) 
 
(defn -main [& args] 
  (println "Hello world from Node.js!")) 
 
(set! *main-cli-fn* -main) 

Launch an nREPL session for your project by typing the following:

lein repl

We then require the namespaces necessary for the launch of our Node.js REPL:

user=>(require 'cljs.build.api)
user=> (require 'cljs.repl.node)

Now, launch the first build of our ClojureScript core.cljs source:

user=> (cljs.build.api/build "src"
  #_=>   {:main 'piggieback-project.core
  #_=>    :output-to "out/main.js"
  #_=>    :verbose true})

We can now hook a Piggieback REPL into this running nREPL session. Issue the following command:

(cemerick.piggieback/cljs-repl (cljs.repl.node/repl-env))

The nREPL session responds with a message saying that a Node.js REPL has been launched:

ClojureScript Node.js REPL server listening on 49449

And as usual, the prompt has been changed so as to notify us that we have successfully launched a ClojureScript REPL on top of our nREPL session:

cljs.user=> _

At this point, we can implement a program similar to the Node.js "Hello World," a little HTTP server that greets the browser that queries it. Type the following in your, now, ClojureScript-enabled nREPL session (we'll elaborate more on the syntax later on):

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 navigate your browser to  http://127.0.0.1:1337, you should see the greeting from your Node.js server.

In the next section, we'll elaborate on a new contender in the realm of interactive ClojureScript coding environments: Figwheel, the new kid on the block that gets you to a ClojureScript browser REPL quickly.

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.

Setting integrated development environments for ClojureScript

Now that we've got the basic lay of the land, we can now focus on configuring a proper Integrated Development Environment. We'll also discuss how we can make it ClojureScript-aware using the REPLs we've covered so far.

In doing so, we strive to profit from the many ways IDEs can assist us. IDEs are powerful tools, exposing functionalities such as code completion, syntax highlighting, program structure introspection, and navigation.

We'll focus on Emacs, its Clojure development environment, CIDER, as well as another simpler package, inf-clojure. The reason why we chose these Emacs-based tools is that they are the most used IDEs for most Clojurists, and are actively maintained by a vibrant community of open source enthusiasts.

Working on Emacs with Piggieback and Weasel on CIDER

CIDER, or the Clojure Interactive Development Environment that Rocks for Emacs ( https://github.com/clojure-emacs/cider ), is an open source Emacs Library for working with Clojure on Emacs. Originally called nrepl.el, it is stable, feature-rich, and an active project that is highly beneficial to Clojure and ClojureScript developers.

If you're going to use CIDER, its authors have stated that they expect ClojureScript developers to use Piggieback and Weasel as their default toolkit.

Let's assume that you can launch a Piggieback/Weasel-enabled nREPL session for your ClojureScript project (refer to the Live-coding ClojureScript on top of nREPL with PiggieBack and Weasel section). We'll now focus on how CIDER empowers you to develop ClojureScript with Emacs.

Installing CIDER

Installing Cider is a matter of getting the relevant library from package.el (using MELPAMELPA Stable, or Marmalade repositories) and issuing the following command (in Emacs):

M-x package-install [RET] cider [RET]

Alternatively, add the following lines to your Emacs configuration file:

(unless (package-installed-p 'cider) 
  (package-install 'cider)) 

You'll also need to hook up the CIDER middleware into our nREPL. To do this, add the following to the :user section in your ~/.lein/profiles.clj file:

:plugins [[cider/cider-nrepl "x.y.z"]] 

We haven't spoken about Leiningen profiles too much prior to now. To learn more about how the profiles.clj file works, check out the Leiningen documentation at https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md#declaring-profiles. Take care, the "x.y.z" version number in cider-nrepl must match the CIDER version, otherwise you'll get a warning when trying to connect to a project's REPL.

Working with Clojure and ClojureScript REPLs on CIDER

At this point, you're free to tweak CIDER's configuration to add features like different autocompletion providers or syntax-highlighting behavior. Whether you choose to or not, you should have everything you need to get CIDER up and running at this point.

Once you have installed CIDER and its nREPL middleware, you can open a Clojure file (even an empty buffer to experiment in), launch an REPL on it and begin to work interactively. Most Clojure developers go back and forth between editing and sending code to the REPL for evaluation. To launch a Clojure nREPL session from Emacs use the following command:

M-x cider-jack-in

Now, how can we get this set up to work with ClojureScript? Let's go back to our piggieback_project from earlier in this chapter and get CIDER working for it.

First, we'll need to tell CIDER which ClojureScript evaluation environment we are going to use. CIDER defaults to Rhino, so for our case we'll need to tell CIDER to use Weasel. Customize the cider-cljs-repl file to set it to Weasel:

M-x customize-variable RET cider-cljs-repl RET Weasel RET 

Make certain that your ClojureScript file contains the following connection code:

(ns piggieback-project.core 
  (:require [weasel.repl :as repl])) 
 (when-not (repl/alive?) 
  (repl/connect "ws://localhost:9001")) 

Tip

Make sure that this ClojureScript code has been successfully compiled at least once. Otherwise, we won't be able to load the websocket client.

Next, we'll use the lein-cljsbuild package. To activate this plugin make sure that your project.clj file looks as follows:

(defproject piggieback_project "0.1.0-SNAPSHOT" 
  :description "FIXME: write description" 
  :url "http://example.com/FIXME" 
  :license {:name "Eclipse Public License" 
    :url "http://www.eclipse.org/legal/epl-v10.html"} 
  :plugins [[lein-cljsbuild "1.1.0"]] 
  :cljsbuild { 
    :builds [{:source-paths ["src"] 
    :compiler {:main piggieback-project.core 
    :output-to "out/main.js" 
    :output-dir "out" 
    :optimizations :none}}]} 
  :dependencies [[org.clojure/clojure "1.7.0"] 
    [org.clojure/clojurescript "1.7.122"] 
    [weasel "0.7.0" :exclusions [org.clojure/clojurescript]]] 
  :profiles {:dev {:dependencies [[com.cemerick/piggieback
    "0.2.1"] 
    [org.clojure/tools.nrepl "0.2.10"]] 
    :repl-options {:nrepl-middleware
      [cemerick.piggieback/wrap-cljs-repl]}}})

Now we'll  build the code responsible for creating the connection. While in the project directory, type the following:

lein cljsbuild once

Now open any ClojureScript file in Emacs, and launch the nREPL session with:

M-x cider-jack-in-clojurescript

You'll see two REPLs, one for Clojure and the other for ClojureScript. The ClojureScript REPL should notify you that it is waiting for the client to connect.

Working with Clojure and ClojureScript REPLs on CIDER

Connect your browser to the Weasel session by opening greet.html. You should get the following screen in Emacs:

Working with Clojure and ClojureScript REPLs on CIDER

Now, switch to the window containing the Clojure REPL and set it to show the buffer containing your test.cljs ClojureScript file.

Load the content of the file in your REPL using the following Emacs command:

C-c C-k

Then, set the namespace of the REPL to be the one declared by the current source file:

C-c M-n

Switch now to your ClojureScript REPL:

C-c C-z

Start typing the name of the function. You'll notice that code completion should be working. In the minibuffer, Emacs should also help you with the signature of your function.

Working with Clojure and ClojureScript REPLs on CIDER

Now let's evaluate some ClojureScript in our REPL:

piggieback-project.test> (defn test-fn [your-name] (js/alert (+
      "hello " your-name)))
piggieback-project.test> (test-fn "Rafik")

And a popup should happily greet you from your connected browser.

Working on Emacs with Figwheel and inf-clojure

In order to use Figwheel with Emacs, we'll need to use inf-clojure, an Emacs package offering basic interaction with a running Clojure subprocess. In conjunction with clojure-mode, this setup will make sure that we benefit from static code analysis features. inf-clojure is not as feature rich as CIDER, which is worth keeping in mind. It is nevertheless, able to load files, switch namespaces, evaluate expressions, show documentation and source of symbols, and do macro-expansion.

Installing inf-clojure

Type the following in your Emacs:

M-x package-install [RET] inf-clojure [RET]

You may also want to add the following snippet to your Emacs configuration file:

(unless (package-installed-p 'inf-clojure) 
  (package-install 'inf-clojure)) 

To enable inf-clojure whenever you visit a Clojure or ClojureScript file, add the following to your Emacs configuration file:

(add-hook 'clojure-mode-hook #'inf-clojure-minor-mode) 

Configuring inf-clojure to run Figwheel as a Clojure subprocess

In order for Emacs to know that we want to use Figwheel as our REPL environment, we'll need to configure it explicitly. To do this, add the following to your Emacs configuration file (usually ~/.emacs):

(defun figwheel-repl () 
  (interactive) 
  (run-clojure "lein figwheel")) 

Restart Emacs or re-evaluate the the configuration file buffer for the modifications to take effect. Next, let's open a file in the source directory of the figwheel_project we've set up for the browser, say core.cljs, and launch the ClojureScript powered inf-clojure session by typing the following:

M-x figwheel-repl

You'll end up to a configuration like the one shown in the following screenshot, where Figwheel, run from inf-clojure, is awaiting connection from the browser:

Configuring inf-clojure to run Figwheel as a Clojure subprocess

As soon as you open the greet.html file within your browser, the user prompt should change to notify you that the evaluation environment is successfully connected to the Figwheel REPL:

Configuring inf-clojure to run Figwheel as a Clojure subprocess

Let's evaluate some ClojureScript. Split your window in two using the following:

C-x 2

And load the buffer containing core.cljs:

C-x b  core.cljs [RET]

You should end up with something like the following:

Configuring inf-clojure to run Figwheel as a Clojure subprocess

Move the cursor to the (js-alert...) form and evaluate it by hitting the following:

C-c C-c

You should see the greeting showing up in the browser.

We've now seen two different possible setups on Emacs: one based on Piggieback/Weasel, which is harder to set up but offers a fully-fledged Clojure development environment—CIDER, and another using Figwheel but offering less integrated development functionality. Which one you choose to use relies pretty much on personal taste, and how much effort you feel like putting in.

Summary

This concludes our section on getting started with ClojureScript development. We introduced you to the ClojureScript compiler, demonstrating how it runs on the JVM and leverages the Google Closure Library to optimize compiled JavaScript and provide namespace functionality.

We learned how the ClojureScript compiler can be used to build ClojureScript programs into JavaScript artifacts, how to access these artifacts and, finally, how to interact with them via a REPL targeting different JavaScript environments.

We covered how to use Piggieback in order to expose a JavaScript-enabled nREPL session, how to push the compiled JavaScript via websockets to the browser thanks to Weasel, and how to target Node.js using this setup.

After that, we saw how we could use Figwheel to get a single self-contained Leiningen plugin for developing with the browser. We also learned how to target Node.js using Figwheel.

Finally, we saw how one can use one of these setups with an integrated development environment based on CIDER or inf-clojure.

Now that you have your computer configured for ClojureScript development, lets tackle the language properly. In the next chapter, we'll dig into the core of the ClojureScript language.

Left arrow icon Right arrow icon

Key benefits

  • Set up interactive development workflows for the browser or Node.js thanks to the ClojureScript ecosystem
  • Learn the basics of interactive single page web app development taking advantage of the functional nature of ClojureScript
  • Delve into advanced rich web application development concepts such as Om, along with core.async, using zippers and logic programming, and preparing code for production with testing or optimizing via the Google Closure Compiler

Description

Clojure is an expressive language that makes it possible to easily tackle complex software development challenges. Its bias toward interactive development has made it a powerful tool, enabling high developer productivity. In this book, you will first learn how to construct an interactive development experience for ClojureScript.. You will be guided through ClojureScript language concepts, looking at the basics first, then being introduced to advanced concepts such as functional programming or macro writing. After that, we elaborate on the subject of single page web applications, showcasing how to build a simple one, then covering different possible enhancements. We move on to study more advanced ClojureScript concepts, where you will be shown how to address some complex algorithmic cases. Finally, you'll learn about optional type-checking for your programs, how you can write portable code, test it, and put the advanced compilation mode of the Google Closure Compiler to good use.

Who is this book for?

This book is for web application developers who want to benefit from the power of ClojureScript to get an agile and highly productive development platform that targets mainly browser JavaScript. You are not required to be fluent in Clojure, but it will be easier for you if you have a basic understanding of browser and server-side JavaScript.

What you will learn

  • Understand how the ClojureScript compiler operates
  • Set up interactive development workflows for ClojureScript
  • Grasp the basics of the ClojureScript language, including basic syntax, data structures, variable scoping, namespaces, and finally the powerful sequence abstraction
  • Delve into advanced concepts such as functional programming, macro writing, asynchronous programming, app routing, and real-time web
  • Develop simple one page web applications
  • Explore techniques to make your web apps aware of the external world through external or embedded database access or Oauth 2 integration
  • Learn more advanced ClojureScript concepts like in app routing, real-time web
  • Prepare your work for production, getting insights into optional type-checking, writing portable Clojure/ClojureScript code, and testing
Estimated delivery fee Deliver to South Korea

Standard delivery 10 - 13 business days

$12.95

Premium delivery 5 - 8 business days

$45.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Jun 30, 2016
Length: 320 pages
Edition : 1st
Language : English
ISBN-13 : 9781785887635
Category :
Languages :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Estimated delivery fee Deliver to South Korea

Standard delivery 10 - 13 business days

$12.95

Premium delivery 5 - 8 business days

$45.95
(Includes tracking information)

Product Details

Publication date : Jun 30, 2016
Length: 320 pages
Edition : 1st
Language : English
ISBN-13 : 9781785887635
Category :
Languages :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 153.97
Clojure Programming Cookbook
$54.99
Learning ClojureScript
$43.99
Mastering Clojure
$54.99
Total $ 153.97 Stars icon

Table of Contents

8 Chapters
1. Getting Ready for ClojureScript Development Chevron down icon Chevron up icon
2. ClojureScript Language Fundamentals Chevron down icon Chevron up icon
3. Advanced ClojureScript Concepts Chevron down icon Chevron up icon
4. Web Applications Basics with ClojureScript Chevron down icon Chevron up icon
5. Building Single Page Applications Chevron down icon Chevron up icon
6. Building Richer Web Applications Chevron down icon Chevron up icon
7. Going Further with ClojureScript Chevron down icon Chevron up icon
8. Bundling ClojureScript for Production Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.4
(7 Ratings)
5 star 85.7%
4 star 0%
3 star 0%
2 star 0%
1 star 14.3%
Filter icon Filter
Top Reviews

Filter reviews by




Daniel Woelfel Mar 07, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I have quite a bit of experience building webapps in ClojureScript. I was the main author of CircleCI's cljs frontend and I cofounded PrecursorApp, a collaborative prototyping app with a cljs frontend. Both codebases are open-source on GitHub (circleci/frontend and PrecursorApp/precursor).I wish I would have had this book when I started working with ClojureScript. ClojureScript has one of the best developer experiences, with code-reloading and a REPL, but it can be a bit daunting to set it up the first time. This book takes you through all the steps and keeps you from missing out on some of the best aspects of developing with ClojureScript.The second and third chapters might be a bit too much to take in at once for people new to ClojureScript. I'd recommend you skim them the first time, then come back and use them as a reference when you start building your application.The rest of the book gives you a nice foundation for building applications in ClojureScript. I may have focused on a few different libraries, but the ones they cover are pretty solid, with one notable exception. I wouldn't recommend anybody use Dommy. I used it and found it very confusing--you're much better off using the tools you get for free from Google Closure.There's lots of other great stuff in the book. I'll definitely be coming back to the section on ClojureScript modules--Precursor ships with a 1.5mb (only 388k gzipped) javascript file and I'd love to get that down to a more reasonable size.
Amazon Verified review Amazon
Emergent Iguana Dec 23, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
In case you are even vaguely curious about ClojureScript and are wondering whether or not to learn it, I strongly encourage you to do so, as it has become obvious to me that it is the future of front-end web development. (Technically, it is one of several futures, but as it stands it has several years head start over most options except for CoffeeScript and of course native JavaScript. I have never programmed in CoffeeScript but having around 15 years experience with JavaScript I can safely tell you that ClojureScript provides a great many benefits to any programmer over JS, and that is even taking into account ES6 which does introduce a few of the benefits that have been native to ClojureScript since its inception.)I have been programming in ClojureScript for over a year now, and this book, which I bought last Christmas (directly in the Packt sale for a mere $5) helped my learning curve tremendously.The most important first step in learning any new language is setting up your development environment, and this book does an excellent job in covering this for ClojureScript. While it goes through a number of different scenarios, and this can seem confusing at first, by far the best option is to use Figwheel, which provides an as close to real-time live encoding flow as you are going to get for a compile-to-JS language.It also covers setting up Emacs as an IDE, which is probably at the very least the best editor (rather than IDE) available for programming in LISP dialects (of which ClojureScript is one), mostly due its paredit plugin. (I am much more of a Vim user but sadly I haven't found any plugin in Vim which comes close to the functionality that the emacs paredit plugin provides.)Chapters 2 and 3 cover the language fundamentals and some advanced features, including interop with JS and macros. The treatment of macros is adequate enough, however some more could have been written about them. Essentially, they allow you to write ClojureScript code which is rewritten, via macros, into some other ClojureScript code, which is ultimately compiled into JS. This is one of the most powerful features of the language, and once you have more experience with the language you will definitely want to write macros in certain situations where it makes sense.One area which is not covered adequately by the book is the ClojureScript and Clojure library core.async. This provides an amazing alternative way of handling events to that which is native to JS / the DOM. While events are still present when using core.async, event handlers become much more lightweight and the majority of event handling code is sent of to something known as a "go channel" which takes care of the bulk of work required, including any state management. There are a couple of excellent videos, one on youtube and one on Cognitect's website (entitles "core.async webinar") which show you some of the amazing things which you can achieve using core.async.Chapter 4 covers a decent selection of libraries which allow you to work with the DOM and do general web development, all of which are worth looking at if you are not using React.Chapter 5 covers React development, and herein is another major flaw of the book. There are several ClojureScript libraries available for working with React, and the book's authors chose to go with Om. I tried using Om following the guidelines in this book, together with the first two tutorials on the Om github page, and to cut a long story short, I couldn't get it to do what simple things I was trying to achieve. I found myself having to bend over backwards to fit my ideas into the Om framework, and after much hair-pulling, I gave up.Instead, I discovered Reagent, which is an amazing framework for building React applications using ClojureScript, not least of all because it is incredibly simple to use. I have been using Reagent for several months now and I have absolutely zero complaints, in short, it is an amazing framework and I cannot recommend it enough.Beyond this I have only read the section on testing, which again covers testing using the native cljs.test library more than adequately enough. However you should be aware that the developer of Figwheel created something called Devcards, which is designed primarily to test React components outside of their native application contexts, but also includes thorough testing capabilities which reports results in your browser rather than in a command-line session. If you search the web for "TDD in ClojureScript" you will find an article by Eric Smith which explains how to do this, it's well worth going through it all for the benefits you'll get.This is by far the best book available on ClojureScript at this time (there are only 3 others and one of those only covers Reagent), and I would highly recommend anyone starting out or with just a couple of month's experience in ClojureScript to read it and learn from it, it provides an incredibly invaluable resource to what I consider to be the most useful language for front-end web-development today.
Amazon Verified review Amazon
hswolff Aug 22, 2016
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This is a great and thorough introduction to ClojureScript. It makes no assumptions on what you may already know. Instead it focuses on building a strong foundation of knowledge. Two whole chapters are focused on just making sure you have a strong understanding of what ClojureScript is and what makes it different from JavaScript. That was invaluable as I went further into the book. From there the book teaches how to create a web application with React by way of Om. And rather than leave me high and dry with just a fun toy application the book wraps things up by teaching how to move code to a production environment. Definitely a strong recommend if you're interested in going from a ClojureScript beginner to a pro!
Amazon Verified review Amazon
DUPUCH Nov 21, 2016
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Pros :- Start from the basics and go through complex cases- Well written, can be seriously read in a 2/3 days period (if you have a little experience in clojure(script)- RecentCons:- Code examples in chapter 5 (om todo app with back-end) - some mistakes in code
Amazon Verified review Amazon
A Reader Aug 15, 2016
Full star icon Full star icon Full star icon Full star icon Full star icon 5
A very clear introduction to developing with Clojurescript. The pacing was excellent. The examples made a ton of sense. I really liked how the author included links and tips to upcoming tech as well (such as the js compiler.)
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela