This assumes that you already have a working installation of ClojureScript and Node.js
Given:
math101
|-- package.json
|-- src
| `-- com
| `-- example
| `-- math.cljs
package.json
{
"name": "math101",
"version": "1.0.0",
"main": "dist/index.js",
"license": "MIT",
"devDependencies": {
"shadow-cljs": "^2.8.52",
"source-map-support": "^0.5.13"
}
}
Notes:
dist/index.js
- This will contain our ClojureScript code converted to JavaScript
shadow-cljs
- The build (and dependency management) tool that we need
source-map-support
- Required to run ClojureScript on Node.js
π£Please make sure you have installed these two NPM dependencies before you proceed further.
math.cljs
(ns com.example.math)
(defn add [x y]
(+ x y))
1. Setup the build tool
At the root of math101
run yarn shadow-cljs init
.
This will create a file called shadow-cljs.edn
with some default settings:
;; shadow-cljs configuration
{:source-paths
["src/dev"
"src/main"
"src/test"]
:dependencies
[]
:builds
{}}
Let's make some changes.
First you don't need that many source paths for this:
{:source-paths
["src"]
:dependencies
[]
:builds
{}}
Then let's add a build configuration:
;; shadow-cljs configuration
{:source-paths
["src"]
:dependencies
[]
:builds
{:math101 {:target :node-library
:output-to "dist/index.js"
:exports-var com.example.math/add}}}
Notes:
:math101
- This the build id that we will use later
:target :node-library
- This tells shadow-cljs
that you intend to author a library
:output-to "dist/index.js"
- The code you intend to publish
:exports-var com.example.math/add
- "Fully qualified name" of the function you intend to publish. This will produce a default export.
Additional notes:
The :target :node-library emits code that can be used (via require) as a standard node library, and is useful for publishing your code for re-use as a compiled Javascript artifact.
Source
There is a :npm-module
target available but so far :node-library
has checked all the boxes for me.
2. Let's build this!
Run yarn shadow-cljs compile math101
.
The first time you run this, shadow-cljs
will download a bunch of stuff. Eventually it will finish and when it does...
$ node
> var add = require('./dist')
> add(40, 2)
42
β¨β¨β¨
Need to export more than just one function? No problemo.
Let's add subtract
:
(ns com.example.math)
(defn add [x y]
(+ x y))
(defn subtract [x y]
(- x y))
And now let's update our build config:
;; shadow-cljs configuration
{:source-paths
["src"]
:dependencies
[]
:builds
{:math101 {:target :node-library
:output-to "dist/index.js"
:exports {:add com.example.math/add
:subtract com.example.math/subtract}}}}
Run yarn shadow-cljs compile math101
again and when it finishes:
$ node
> var math101 = require('./dist')
> math101.add(40, 2)
42
> math101.subtract(44, 2)
42
β¨β¨β¨β¨β¨β¨
ADDENDUM
This is only intended to get you started. shadow-cljs compile
generates non-production code (i.e. it's not minified, dead code is not removed AFAIK and Google Closure hasn't run any optimisation yet).
The command for generating production-ready code is shadow-cljs release
but you may want to tweak your build config before.
I would highly recommend that you invest time reading up the shadow-cljs documentation. It is an amazing tool.