loading...

Integrating ClojureScript with JavaScript tooling

romanliutikov profile image Roman Liutikov ・3 min read

Recent release of ClojureScript introduced a new way to integrate with JavaScript tooling that makes it easier to import ClojureScript into existing JavaScript projects.

In this post we will explore how to setup and use these new features and integrate with bundlers such as Webpack.

First make sure you have OpenJDK installed and then install Clojure CLI. Once that is done, it's time to create a project.

Create project folder and navigate to it

mkdir hello-bundler && cd hello-bundler

Create Clojure deps file with ClojureScript in dependencies

echo '{:deps {org.clojure/clojurescript {:mvn/version "1.10.741"}}}' > deps.edn

Install Webpack and React. We are going to use React in this guide since it is exclusively used in ClojureScript for building web apps.

yarn add webpack webpack-cli react react-dom --save-dev

Next create basic Clojure project structure and entry point namespace

mkdir -p src/hello_bundler
touch src/hello_bundler/core.cljs

Here we require react and react-dom installed in node_modules. Put the code below into core.cljs.

(ns hello-bundler.core
  (:require [react]
            [react-dom]))

(def h1 (react/createElement "h1" nil "Hello!"))

(react-dom/render h1 (.getElementById js/document "root"))

Create ClojureScript build config file build.edn with the following contents

{:main hello-bundler.core
 :output-to "out/index.js"
 :output-dir "out"
 :target :bundle
 :bundle-cmd {:none ["npx" "webpack" "--mode=development"]
              :default ["npx" "webpack"]}}

When building ClojureScript sources the compiler will output entry point file into "out/index.js" and then run Webpack build with a command provided in :bundle-cmd option.

Now create Webpack config which will consume ClojureScript's output. Make webpack.config.js with the following contents

module.exports = {
  entry: "./out/index.js",
  output: {
    path: __dirname,
    filename: "bundle.js"
  }
}

Finally create index.html file in the root of the project which will load the final build artifact produced by Webpack.

echo '<div id="root"></div><script src="bundle.js"></script>' > index.html

And run ClojureScript build command

clj -m cljs.main -co build.edn --compile --repl

This will open your browser at http://localhost:9000/ and start ClojureScript REPL in the terminal where you can evaluate ClojureScript code in browser's context, try this for example

(js/alert "Hello!")

For a better interactive development experience you may want to connect to the REPL from your editor, for example here's a plugin for VS Code.

Production build

When building for production ClojureScript compiler will run a command specified in :default field in :bundle-cmd. To create production build and start a web server afterwards execute the following command.

clj -m cljs.main -co build.edn -O advanced --compile --serve

Conclusion

With a new :bundle compiler target ClojureScript is able to produce JavaScript that can be consumed by tools like Webpack that in turn will take care of including NPM dependencies into the final bundle, so ClojureScript compiler doesn't have to reinvent the wheel here.

That also means that existing JavaScript projects can depend on ClojureScript code much easier now. In the next post we will explore how to consume ClojureScript code from JavaScript modules.

Posted on by:

Discussion

markdown guide