-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The initial commit, gutted out from Fusion.
- Loading branch information
0 parents
commit 01ba656
Showing
4 changed files
with
174 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.cpcache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Shadow-Cljs Tailwind JIT | ||
|
||
Build hooks for enabling [Tailwind | ||
JIT](https://tailwindcss.com/docs/just-in-time-mode) within Shadow Projects. | ||
|
||
## Installation and configuration | ||
|
||
Install the required node dependencies in your project: | ||
|
||
``` | ||
npm install --save-dev postcss-cli tailwindcss autoprefixer cssnano | ||
``` | ||
|
||
Add the clojure library to your project via your preferred method (either | ||
shadow's own `deps` or in your `deps.edn` file). | ||
|
||
Next, add the required build hooks to your `shadow-cljs.edn` build configuration: | ||
|
||
|
||
```clj | ||
{:builds | ||
{:ui | ||
{;; ... | ||
:dev | ||
{:build-hooks | ||
[(teknql.tailwind/start-watch!)]}} | ||
:release | ||
{:build-hooks | ||
[(teknql.tailwind/compile-release!)]} | ||
:devtools | ||
{:http-root "resources/public/" ;; Must be set to infer default purge targets. | ||
:http-port 3000} | ||
:tailwind/output "resources/public/css/site.css"}}} | ||
``` | ||
|
||
## Customization | ||
|
||
The following options are supported via namespaced keys within the `shadow-cljs` build config: | ||
|
||
|
||
- `:tailwind/output` - Where the generated CSS will be written to. Default: | ||
`resources/public/css/site.css` | ||
- `:tailwind/config` - A map that is used for the `tailwind.config.js`. Automatically encodes kebab | ||
cased keys into camel cased. | ||
|
||
## How it works | ||
|
||
This library works by sourcing options in your `shadow-cljs.edn` to make a temporary project | ||
project directory with the required files to configure PostCSS + Tailwind to compile CSS for | ||
your project. We then shell out to `postcss-cli` using the temporary configs. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{:paths ["src"] | ||
:pablo/config | ||
{:github "teknql/shadow-cljs-tailwind-jit" | ||
:desc "Tailwind JIT buildhooks for Shadow CLJS" | ||
:target :jar | ||
:group-id teknql | ||
:artifact-id shadow-cljs-tailwind-jit} | ||
:deps | ||
{metosin/jsonista {:mvn/version "0.3.2"} | ||
funcool/cuerdas {:mvn/version "2020.03.26-3"} | ||
babashka/process {:mvn/version "0.0.2"}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
(ns teknql.tailwind | ||
(:require [jsonista.core :as j] | ||
[cuerdas.core :as str] | ||
[babashka.process :as proc]) | ||
(:import [java.nio.file Files] | ||
[java.nio.file.attribute FileAttribute])) | ||
|
||
(def default-config | ||
"Default tailwind config" | ||
{:future {} | ||
:purge [] | ||
:mode "jit" | ||
:theme {:extend {}} | ||
:variants {} | ||
:plugins []}) | ||
|
||
(defn- ->json | ||
"Encode the provided value to JSON" | ||
[val] | ||
(j/write-value-as-string | ||
val | ||
(j/object-mapper {:encode-key-fn (comp str/camel name)}))) | ||
|
||
(defn ->export-json | ||
"Return the provided val as an string with a `module.exports`. | ||
Used for generating the various *.config.js files that the Node ecosystem loves" | ||
[val] | ||
(str "module.exports = " (->json val) ";")) | ||
|
||
(defn- cfg-get | ||
"Behaves identical to `get` but logs the default value back to the user." | ||
[config key default] | ||
(or (get config key) | ||
(do (println "No build config value for " key ". Using default value.") | ||
default))) | ||
|
||
(defn create-tmp-tailwind-project! | ||
"Create a temporary tailwind project with the necessary assets to build the project using the JIT. | ||
Return the path to the temporary directory." | ||
[postcss-cfg tailwind-cfg] | ||
(let [tmp-dir (-> (Files/createTempDirectory "tailwind" (make-array FileAttribute 0)) | ||
(.toFile) | ||
(.getAbsolutePath)) | ||
tmp-css-path (str tmp-dir "/" "tailwind.css") | ||
tmp-tw-cfg-path (str tmp-dir "/" "tailwind.config.js") | ||
tmp-postcss-cfg-path (str tmp-dir "/" "postcss.config.js")] | ||
(spit tmp-css-path "@tailwind base;\n@tailwind components;\n@tailwind utilities;") | ||
(spit tmp-tw-cfg-path (->export-json tailwind-cfg)) | ||
(spit tmp-postcss-cfg-path (-> postcss-cfg | ||
(assoc-in [:plugins :tailwindcss :config] tmp-tw-cfg-path) | ||
(->export-json))) | ||
tmp-dir)) | ||
|
||
(defn start-watch! | ||
"Start the tailwind JIT" | ||
{:shadow.build/stage :configure} | ||
[build-state] | ||
(let [config (:shadow.build/config build-state) | ||
output-path (cfg-get config :tailwind/output "resources/public/css/site.css") | ||
http-root (-> config | ||
:devtools | ||
:http-root) | ||
tmp-dir (create-tmp-tailwind-project! | ||
{:plugins {:tailwindcss {}}} | ||
(merge default-config | ||
{:purge [(str http-root "/**/*.js") | ||
(str http-root "/**/*.html")]} | ||
(cfg-get config :tailwind/config nil)))] | ||
(proc/process | ||
["./node_modules/.bin/postcss" | ||
(str tmp-dir "/tailwind.css") | ||
"--config" | ||
tmp-dir | ||
"--watch" | ||
"-o" | ||
output-path] | ||
{:env {"NODE_ENV" "development" | ||
"TAILWIND_MODE" "watch"} | ||
:err :inherit | ||
:out :inheirt}) | ||
build-state)) | ||
|
||
(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") | ||
http-root (-> config | ||
:devtools | ||
:http-root) | ||
tmp-dir (create-tmp-tailwind-project! | ||
{:plugins {:tailwindcss {} | ||
:autoprefixer {} | ||
:cssnano {:preset "default"}}} | ||
(merge default-config | ||
{:purge [(str http-root "/**/*.js") | ||
(str http-root "/**/*.html")]} | ||
(cfg-get config :tailwind/config nil)))] | ||
(-> (proc/process | ||
["./node_modules/.bin/postcss" | ||
(str tmp-dir "/tailwind.css") | ||
"--config" | ||
tmp-dir | ||
"-o" | ||
output-path] | ||
{:env {"NODE_ENV" "production" | ||
"TAILWIND_MODE" "build"}}) | ||
deref) | ||
build-state)) |