diff --git a/README.md b/README.md index 911ff26..d91c0c5 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,35 @@ equivalent functionality). In the example above, there needn't be a corresponding entry for `echo` in `project.clj`. +#### Lumo compiler + +Alternatively you can use the [Lumo](https://github.com/anmonteiro/lumo) +[compiler](https://anmonteiro.com/2017/02/compiling-clojurescript-projects-without-the-jvm/). + +In order to enable it either pass the `--lumo` switch to either `deploy` or `package`: + +```shell +serverless deploy --lumo +``` + +Or add the following to your `serverless.yml`: + +```yaml +custom: + cljsCompiler: lumo +``` + +The source paths and compiler options will be read from `serverless-lumo.edn`: + +```clojure +{:source-paths ["src"] + :compiler-options {:output-to "out/my/artifact.js" ;; defaults to out/lambda.js + :output-dir "out/my" ;; defaults to out + :optimizations :simple ;; defaults to :none + :source-map false ;; defaults to false because of lumo bug #132 + ...other options...}} +``` + ## License serverless-cljs-plugin is free and unencumbered public domain software. For more diff --git a/index.js b/index.js index 6ff6083..51280a9 100644 --- a/index.js +++ b/index.js @@ -52,8 +52,10 @@ function basepath(config, service, opts) { function cljsLambdaBuild(serverless, opts) { const fns = slsToCljsLambda(serverless.service.functions, opts); + const compiler = _.get(serverless.service, 'custom.cljsCompiler'); + let cmd; - if(opts.lumo) { + if(compiler == "lumo" || opts.lumo) { cmd = (`lumo -c ${path.resolve(__dirname, 'serverless-cljs-plugin')} ` + `-m serverless-lumo.build ` + `--zip-path ${serverless.service.__cljsArtifact} ` + diff --git a/lumo-example/serverless.yml b/lumo-example/serverless.yml index 57cc218..26df267 100644 --- a/lumo-example/serverless.yml +++ b/lumo-example/serverless.yml @@ -1,5 +1,8 @@ service: lumo-example +custom: + cljsCompiler: lumo + provider: name: aws runtime: nodejs4.3 diff --git a/serverless-cljs-plugin/serverless_lumo/build.cljs b/serverless-cljs-plugin/serverless_lumo/build.cljs index aa088b6..40ca4c2 100644 --- a/serverless-cljs-plugin/serverless_lumo/build.cljs +++ b/serverless-cljs-plugin/serverless_lumo/build.cljs @@ -1,5 +1,6 @@ (ns serverless-lumo.build (:require fs path archiver + [lumo.core] [clojure.string :as str] [goog.string.format] [cljs.reader :as reader] @@ -10,8 +11,15 @@ (defn zip! "Create the zip in output-dir. Return a promise containing the path. - The dirs will be included in the zip, the compression level defaults - to 9." + The zip-opts map is: + + {:dirs #{\"dir1\" \"dir2\"} + :files #{[\"path/to/file\" {:name \"file\"}] + \"another/file\"}} + + Seqable :files entries are passed as parameters to the archiver.file + function, for details check: + https://archiverjs.com/docs/Archiver.html#file" [output-path zip-opts compiler-opts] (let [archiver (archiver "zip" #js {:zlib {:level 9}}) @@ -19,12 +27,18 @@ (js/Promise. (fn [resolve-fn reject-fn] (.on output-stream "close" #(resolve-fn output-path)) + (.on archiver "warning" (fn [err] + (if (= (.-code err) "ENOENT") + (js/console.warn (.-message err)) + (reject-fn err)))) (.on archiver "error" reject-fn) - (.pipe archiver output-stream) - (doseq [d (zip-opts :dirs)] + (doseq [d (:dirs zip-opts)] (.directory archiver d)) - (.file archiver (zip-opts :index) #js {:name "index.js"}) + (doseq [f (:files zip-opts)] + (if (string? f) + (.file archiver f) + (.apply (.-file archiver) archiver (clj->js (seq f))))) (.finalize archiver))))) (defn compile! @@ -40,7 +54,7 @@ (defn generate-index "Generate the necessary index.js" [opts compiler] - (index/generate-index (opts :functions) compiler)) + (index/generate-index (:functions opts) compiler)) (defn write-index [content outpath] (.writeFileSync fs outpath content) @@ -65,19 +79,19 @@ :optimizations :none}}) (defn- output-dir [compiler] - (let [s (compiler :output-dir)] + (let [s (:output-dir compiler)] (str/replace s #"/+$" ""))) (defn build! "Build a project." [opts cljs-lambda-opts] - (let [compiler (cljs-lambda-opts :compiler) + (let [compiler (:compiler cljs-lambda-opts) index (-> (generate-index opts compiler) - (write-index (.resolve path (opts :zip-path) "../index.js")))] - (compile! (cljs-lambda-opts :source-paths) compiler) - (zip! (opts :zip-path) + (write-index (.resolve path (:zip-path opts) "../index.js")))] + (compile! (:source-paths cljs-lambda-opts) compiler) + (zip! (:zip-path opts) {:dirs #{(output-dir compiler) "node_modules"} - :index index} + :files #{[index {:name "index.js"}]}} compiler))) (def cli-option-map @@ -96,8 +110,14 @@ k (cli-option-map k k)]] [k (parse-option k v)]))) +(defn cmd-line-args [] + (if-let [args cljs.core/*command-line-args*] ;; for lumo > 1.7.0 + args + (when-let [args lumo.core/*command-line-args*] ;; for lumo <= 1.7.0 + args))) + (defn ^:export -main [& args] - (let [opts (cli-options *command-line-args*) + (let [opts (cli-options (cmd-line-args)) conf (read-conf!)] (build! opts (merge-with merge default-config (read-conf!)))))