Skip to content

Instantly share code, notes, and snippets.

@geraldodev
Created July 15, 2023 15:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save geraldodev/f2ff01250d9ce28bccf14f717cdd5df7 to your computer and use it in GitHub Desktop.
Save geraldodev/f2ff01250d9ce28bccf14f717cdd5df7 to your computer and use it in GitHub Desktop.
;; This code was adapted from com.teknql/shadow-cljs-tailwind-jit
(ns helix-ui.tailwind
(:require
[clojure.string]
[babashka.process :as proc]
[clojure.pprint :refer [pprint]]
[clojure.spec.alpha :as s]
)
(:import [java.nio.file Files]
[java.nio.file.attribute FileAttribute]))
(def tailwind-path
"The path to the postcss command."
(if (clojure.string/starts-with?
(System/getProperty "os.name") "Windows")
"./node_modules/.bin/tailwindcss.cmd"
"./node_modules/.bin/tailwindcss"))
(defonce
^{:doc "Static state atom associating shadow-cljs build IDs to their respective state."}
projects
(atom {}))
(defn- log
"Log the provided `strs` to stderr with a prefix determined by the build ID
of the passed in `build-cfg`."
[build-cfg & strs]
(binding [*out* *err*]
(println (apply str "[" (:build-id build-cfg) "] " strs))))
(s/def ::input string?)
(s/def ::output string?)
(s/def ::config string?)
(s/def ::tailwindcss-param
(s/keys :req-un [::input ::output ::config]))
#_(defn compile-release!
"Compile the release build of the CSS generated by tailwind."
{:shadow.build/stage :flush}
[build-state]
(let [config (:shadow.build/config build-state)
output-path (cfg-get config :tailwind/output "resources/public/css/site.css")
tw-files (cfg-get config :tailwind/files nil)
http-root (-> config :devtools :http-root)
tmp-dir (create-tmp-tailwind-project!
(merge default-tailwind-config
{:content [(str http-root "/**/*.js")
(str http-root "/**/*.html")]}
(cfg-get config :tailwind/config nil)))
]
(log config "Generating tailwind output")
(-> (proc/process
[tailwind-path
"-i"
(or
(:tailwind.css tw-files)
(str tmp-dir "/tailwind.css"))
"--config"
(str
(or
(:base-path tw-files)
tmp-dir)
"/tailwind.config.js")
"--minify"
"-o"
output-path]
{:extra-env {"NODE_ENV" "production"
"TAILWIND_MODE" "build"}})
deref)
build-state))
; {:proc #object[java.lang.ProcessImpl 0x5c94bc93 Process[pid=50311, exitValue="not exited"]],
; :exit nil,
; :in #object[java.lang.ProcessImpl$ProcessPipeOutputStream 0xf8c3852 java.lang.ProcessImpl$ProcessPipeOutputStream@f8c3852],
; :out #object[java.lang.ProcessBuilder$NullInputStream 0x413aa740 java.lang.ProcessBuilder$NullInputStream@413aa740],
; :err #object[java.lang.ProcessBuilder$NullInputStream 0x413aa740 java.lang.ProcessBuilder$NullInputStream@413aa740],
; :prev nil,
; :cmd [./node_modules/.bin/tailwindcss -i /tmp/tailwind16695065361704692360/tailwind.css --config ./tailwind.config.js --watch -o resources/portfolio/public/css/portfolio.css]}
;; we are using stage :flush in order not to start the css watching when shadow-cljs is potentially
;; making a build from zero, in that case I have two machines that locked during the proccess
;; since we are using flush it'll be called every time the compiler flushes to disk, so we just
;; start the tailwind jit on the 1st call for the build-id
(defn start-watch!
"Start the tailwind JIT"
{:shadow.build/stage :flush}
[build-state]
(println "start-watch! invoked")
(let [config (:shadow.build/config build-state)
tailwindcss (:tailwindcss config)]
(cond
(not tailwindcss)
(println "Missing :tailwindcss key on build config to invoke tailwindcss command")
(not (s/valid? ::tailwindcss-param tailwindcss))
(throw (ex-info "Invalid tailwincss map. It requires keywords :input :output :config on par with tailwindcss"
(s/explain-data ::tailwindcss-param tailwindcss)))
:else
(let [
build-id (:build-id config)
; _ (pprint config)
project-def (get @projects build-id)
tailwind-cmd [tailwind-path
"--input"
(:input tailwindcss)
"--config"
(:config tailwindcss)
"--watch"
"--output"
(:output tailwindcss)]
]
(let [existing-proc (:process project-def)]
(when-not existing-proc
; (do (log config "Restarting tailwind process.")
; (proc/destroy existing-proc))
(log config "Starting tailwind process.")
(println tailwind-cmd)
(swap! projects
assoc
build-id
{:process
(proc/process
tailwind-cmd
{:extra-env {"NODE_ENV" "development"
"TAILWIND_MODE" "watch"}
:err :inherit
:out :inherit})})))))
build-state))
(comment
(prn (meta #'start-watch!))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment