shadow-cljs provides everything you need to compile your ClojureScript code with a focus on simplicity and ease of use.
Good configuration defaults so you don't have to sweat the detailsSeamless npm
integrationFast builds, reliable caching, ...Supporting various targets :browser
, :node-script
, :npm-module
, :react-native
, :chrome-extension
, ...Live Reload (CLJS + CSS)CLJS REPLCode splitting (via :modules
)To use shadow-cljs, add your configurations in a shadow-cljs.edn
file, and run:
npm install -g shadow-cljs
shadow-cljs compile app
Configurations
For a browser app, create a shadow-cljs.edn
file like:
{:source-paths ["src"]
:dependencies [[reagent "0.8.1"]]
:builds {:app {:target :browser
:output-dir "public/js"
:asset-path "/js"
:modules {:main {:init-fn app.main/main!}}}}}
{:source-paths ["src"]
:dependencies [[reagent "0.8.1"]]
:builds {:app {:target :browser
:output-dir "public/js"
:asset-path "/js"
:modules {:main {:init-fn app.main/main!}}}}}
CLI tools
Some useful shadow-cljs commands during development are:
shadow-cljs compile app
shadow-cljs watch app
shadow-cljs cljs-repl app
shadow-cljs node-repl
Running a release build optimized for production use.
shadow-cljs release app
Using modules from npm
With shadow-cljs, most npm modules for browser can be imported with modules installed locally.
(ns app.main
(:require ["md5" :as md5]
["fs" :as fs]))
(println (md5 "text"))
(fs/readFileSync "deps.den" "utf8")
Hot code swapping
shadow-cljs watches for file changes and re-compiles code incrementally. Warnings and errors are displayed after being prettified.
{:source-paths ["src"]
:dependencies [[mvc-works/hsl "0.1.2"]]
:dev-http {8080 "target/"}
:builds {:browser {:target :browser
:output-dir "target/browser"
:modules {:main {:init-fn app.main/main!}}
:devtools {:after-load app.main/reload!}}}}
None-code resources
There are various use cases where you’d want to use a static resource as part of the compilation of you source files. shadow-cljs provides a macro shadow.resource/inline
for loading files from inside classpaths:
(ns demo.app
(:require [shadow.resource :as rc]))
(def docs (rc/inline "./docs.md"))
This will resolve the ./docs.md
file relative to the current namespace, which means it will end up including demo/docs.md
from somewhere on the classpath.
Long-term caching
By setting in :module-hash-names
field you may tell shadow-cljs to add MD5 hash in the filenames generated. It's a trivial feature in Webpack and now it's a one-liner config in ClojureScript. Meanwhile the assets.edn
file can be emitted for indexing js files in HTML.
{:source-paths ["src"]
:dependencies [[mvc-works/hsl "0.1.2"]]
:builds {:browser {:target :browser
:output-dir "target/browser"
:modules {:main {:init-fn app.main/main!}}
:release {:output-dir "dist/"
:module-hash-names 8
:build-options {:manifest-name "assets.edn"}}}}}
After compilation, two files will be generated in dist/
with names:
=>> l dist/
assets.edn main.9683CD2F.js
Other features
There are more features in shadow-cljs, such as:
Read the User Guide to learn about all the features. Getting started
Here are some configurations you can start with: