|
| 1 | +(ns eden.esbuild |
| 2 | + (:require [clojure.string :as str])) |
| 3 | + |
| 4 | +(defn args |
| 5 | + "Generate esbuild CLI arguments. |
| 6 | + Options map can include: |
| 7 | + - :entry-points - vector of entry point files |
| 8 | + - :outfile - output file path |
| 9 | + - :outdir - output directory path |
| 10 | + - :bundle - boolean, whether to bundle |
| 11 | + - :minify - boolean, whether to minify |
| 12 | + - :log-level - string, Disable logging ('verbose', 'debug', 'info', 'warning', 'error', 'silent'), default 'info' |
| 13 | + - :sourcemap - boolean or string ('inline', 'external', 'both') |
| 14 | + - :target - string or vector of targets (e.g. 'es2020' or ['chrome58', 'firefox57']) |
| 15 | + - :platform - string ('browser', 'node', 'neutral') |
| 16 | + - :format - string ('iife', 'cjs', 'esm') |
| 17 | + - :loader - map of file extensions to loader types |
| 18 | + - :external - vector of modules/patterns to mark as external |
| 19 | + - :define - map of global identifiers to replace |
| 20 | + - :pure - vector of function names to mark as pure |
| 21 | + - :watch - boolean, whether to watch for changes |
| 22 | + - :serve - map with :port and optionally :host |
| 23 | + - :metafile - boolean, whether to generate metafile |
| 24 | + - :splitting - boolean, whether to enable code splitting |
| 25 | + - :jsx - string ('transform', 'preserve', 'automatic') |
| 26 | + - :jsx-factory - string, JSX factory function |
| 27 | + - :jsx-fragment - string, JSX fragment function" |
| 28 | + [& {:as options}] |
| 29 | + (let [add-flag (fn [args flag value] |
| 30 | + (cond |
| 31 | + (true? value) (conj args (str "--" (name flag))) |
| 32 | + (false? value) args |
| 33 | + (string? value) (conj args (str "--" (name flag) "=" value)) |
| 34 | + (keyword? value) (conj args (str "--" (name flag) "=" (name value))) |
| 35 | + :else args)) |
| 36 | + |
| 37 | + add-multi-flag (fn [args flag values] |
| 38 | + (reduce (fn [acc v] |
| 39 | + (conj acc (str "--" (name flag) ":" v))) |
| 40 | + args |
| 41 | + values)) |
| 42 | + |
| 43 | + add-loader (fn [args loaders] |
| 44 | + (reduce (fn [acc [ext loader]] |
| 45 | + (conj acc (str "--loader:" (name ext) "=" (name loader)))) |
| 46 | + args |
| 47 | + loaders)) |
| 48 | + |
| 49 | + add-define (fn [args defines] |
| 50 | + (reduce (fn [acc [k v]] |
| 51 | + (conj acc (str "--define:" (name k) "=" v))) |
| 52 | + args |
| 53 | + defines)) |
| 54 | + |
| 55 | + entry-points (vec (:entry-points options []))] |
| 56 | + |
| 57 | + (-> entry-points |
| 58 | + ;; Output options |
| 59 | + (add-flag :outfile (:outfile options)) |
| 60 | + (add-flag :outdir (:outdir options)) |
| 61 | + |
| 62 | + ;; Basic options |
| 63 | + (add-flag :bundle (:bundle options)) |
| 64 | + (add-flag :minify (:minify options)) |
| 65 | + (add-flag :sourcemap (:sourcemap options)) |
| 66 | + (add-flag :splitting (:splitting options)) |
| 67 | + (add-flag :watch (:watch options)) |
| 68 | + (add-flag :metafile (:metafile options)) |
| 69 | + (add-flag :log-level (:log-level options)) |
| 70 | + |
| 71 | + ;; Target and platform |
| 72 | + (add-flag :platform (:platform options)) |
| 73 | + (add-flag :format (:format options)) |
| 74 | + (cond-> |
| 75 | + (string? (:target options)) (add-flag :target (:target options)) |
| 76 | + (sequential? (:target options)) (add-flag :target (str/join "," (:target options)))) |
| 77 | + |
| 78 | + ;; JSX options |
| 79 | + (add-flag :jsx (:jsx options)) |
| 80 | + (add-flag :jsx-factory (:jsx-factory options)) |
| 81 | + (add-flag :jsx-fragment (:jsx-fragment options)) |
| 82 | + |
| 83 | + ;; Loaders |
| 84 | + (cond-> |
| 85 | + (:loader options) (add-loader (:loader options))) |
| 86 | + |
| 87 | + ;; External modules |
| 88 | + (cond-> |
| 89 | + (:external options) (add-multi-flag :external (:external options))) |
| 90 | + |
| 91 | + ;; Define replacements |
| 92 | + (cond-> |
| 93 | + (:define options) (add-define (:define options))) |
| 94 | + |
| 95 | + ;; Pure functions |
| 96 | + (cond-> |
| 97 | + (:pure options) (add-multi-flag :pure (:pure options))) |
| 98 | + |
| 99 | + ;; Serve options |
| 100 | + (cond-> |
| 101 | + (:serve options) |
| 102 | + (add-flag :serve (if (map? (:serve options)) |
| 103 | + (str (get-in options [:serve :port] 8000)) |
| 104 | + "8000")))))) |
| 105 | + |
| 106 | + |
| 107 | +(comment |
| 108 | + (args |
| 109 | + {:entry-points ["src/app.js"] |
| 110 | + :bundle true |
| 111 | + :minify true |
| 112 | + :sourcemap :external |
| 113 | + :outfile "dist/app.js" |
| 114 | + :target ["chrome58" "firefox57"] |
| 115 | + :loader {:.png :file |
| 116 | + :.jpg :file |
| 117 | + :.svg :dataurl} |
| 118 | + :external ["react" "react-dom"] |
| 119 | + :define {:DEBUG "false" |
| 120 | + :API_URL "\"https://api.example.com\""}}) |
| 121 | + |
| 122 | + (args :metafile "/dev/*") |
| 123 | +) |
0 commit comments