ClojureScript on the Server

ClojureScript on the Server

Just as JavaScript works in the browser and on the server, via a library like Node.js, so does ClojureScript. In this book I’m using Node.js for the server side.

Getting Node.js®

You can get Node.js from the download page. This will also give you npm, Node’s package manager.

Creating a ClojureScript/Node.js Project

I created a project named node-project by following the instructions at the ClojureScript Quick Start page. (I am sick and tired of “Hello, world!” so I did something slightly different.)

Here is the file structure of the directory, with files organized by category rather than alphabetical order. Notice that the project name node-project has a hyphen in it, but when used in a directory name, you replace the hyphen with an underscore: node_project.

node_project
├── cljs.jar
├── src
│   └── node_project
│       └── core.cljs
└── node.clj

The cljs.jar file contains ClojureScript, downloaded from the link at the Quick Start page.

ClojureScript File src/node_project/core.cljs

This is the ClojureScript file for the project; it simply prints to the console.

(ns node-project.core
  (:require [cljs.nodejs :as nodejs]))

(nodejs/enable-util-print!)

(defn -main [& args]
  (println "It works!"))

(set! *main-cli-fn* -main)

File node.clj

This file builds the unoptimized project.

(require 'cljs.build.api)

(cljs.build.api/build "src"
  {:main 'node-project.core
   :output-to "main.js"
   :target :nodejs})

File node_repl.clj

This file will build the project and start a REPL.

(require 'cljs.repl)
(require 'cljs.build.api)
(require 'cljs.repl.node)

(cljs.build.api/build "src"
  {:main 'hello-world.core
   :output-to "out/main.js"
   :verbose true})

(cljs.repl/repl (cljs.repl.node/repl-env)
  :watch "src"
  :output-dir "out")

Using Node.js Modules

To use a Node.js module, you need to define a binding for the library via the js/require function. You can then use that binding’s methods and properties in your ClojureScript code. The following is a REPL session that shows the use of the built-in os module.

cljs.user=> (in-ns 'node-project.core)
node-project.core=> (def os (js/require "os"))
;; much output omitted
node-project.core=> (.hostname os)
"localhost.localdomain"
node-project.core=> (.platform os)
"linux"
example.core=> (.-EOL os) ;; this is a property
"\n"