Skip to content

Instantly share code, notes, and snippets.

@athomasoriginal
Last active July 21, 2021 15:50
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save athomasoriginal/47913c6b946fc7416c3d839be101e600 to your computer and use it in GitHub Desktop.

I'm experimenting with different ways to organize a Clojure/ClojureScript Monorepo using the Clojure CLI Tools.

NOTE: My monorepo contains CLJ and CLJS projects

I started with Monorepo Version 1. Everything worked perfectly. I had to move off this because extra-paths no longer allows paths to specify files outside of the project. Why was I adding :extra-paths from outside my project? My Clojure project in a Clojure webserver. The other project is a CLJS front end app. During dev, I need my compiled CLJS (JS) to be served by my web server (app-server). That's why it had :extra-path of resources and target.

This document now explores the different approaches I found of tackling this issue:

Monorepo Version 1

├── packages
│   ├── app-client
│   │   ├── deps.edn # aliases, deps, paths
│   │   ├── resources/
│   │   ├── target/
│   │   ├── src/
│   ├── app-server
│   │   ├── deps.edn # aliases, deps, paths
│   │   ├── resources/
│   │   ├── src/
  • app-client
    • contains all the frontend code: html, css (resources/) and cljs (src/) and compiled cljs (target/)
    • CLJS compiles to js and output-to target dir
    • ratonale: No need for front end dev to be in same dir as backend (separate concerns)
  • app-server
    • has :extra-paths to app-client: resources/, target/. This enables me to dev front end in app-client and have app-server pickup all of the changes.

Monorepo Version 2

├── packages
│   ├── app-client
│   │   ├── deps.edn # aliases, deps, paths
│   │   ├── resources/
│   │   ├── target/
│   │   ├── src/
│   ├── app-server
│   │   ├── deps.edn # aliases, deps, paths
│   │   ├── resources/
│   │   ├── src/

The structure for the above is the same as in Monorepo Version 1. The difference is that I update app-client/deps.edn to have the top-level :paths key to include resources and target:

;; app-client/deps.edn
{:paths ["src" "resources" "target"]
 ;; ...
 }

and then in app-server I add a :dep in the :dev alias like this:

{:paths   [...] 
 :deps    {...}
 :aliases 
 {:dev 
  {:deps {app-client/app-client {:local/root "../app-client"}}}}

This get's rid of the warnings and makes all of my dev JS artifacts and front end assets accessible to app-server without getting any of the warnings.

Possible Cons

  • target is always being made available in app-server.

Monorepo Version 3

This version is inspired by Sean Corfield's deps.edn monorepo.

├── packages
│   ├── app
│   │   ├── deps.edn # deps only
│   │   ├── node_modules/
│   │   ├── resources/
│   │   ├── target/
│   │   ├── src/
│   ├── app-server
│   │   ├── deps.edn # deps only
│   │   ├── resources/
│   │   ├── src/
│   ├── deps.edn # NEW! aliases, paths

In the above structure, the difference when compared to the other versions:

  • Each package has it's own deps.edn with just dependencies
  • The packages dir get's it's own deps.edn file which has aliases and paths

What's the challenge? If you run figwheel.main from the root of the packages dir you will need to:

  • add the module name infront of resources in the build.edn file
  • specify the :target-dir
  • and figure out a way to make node_modules visible to the cljs compiler. no possible right now.
    • The CLJS compiler could be updated to allow customizations, but not a high priority for the team. (understandably)

The last point is the main blocker right now.

current issue

  • moving the CLJS packages figwheel-main commands to the top level might not be possible (still investigating)

Monorepo Version 4

It's the same as version 3, but in order to improve the developer experience we add babashka tasks because:

  • Avoid verbose and error prone CLI invocations
  • Improve discoverable commands
  • Consistent project commands
    • Give the appearence of all commands being controlled from the packages dir (CLJS projects)
    • Configuring env variables through bb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment