Why cljsbuild
does not compile gulpfile.js
file properly?
Here is my project.clj
config:
(defproject cljs-selfstudy "0.1.0-SNAPSHOT"
:description "Where I want to learn about clojurescript"
:url "http://example.com"
:dependencies [[org.clojure/clojure "1.7.0-alpha2"]
[org.clojure/clojurescript "0.0-2322"]]
:plugins [[lein-cljsbuild "1.0.4-SNAPSHOT"]]
:source-paths ["src"]
:cljsbuild {
:builds [{:id "gulpjs"
:source-paths ["src/gulpjs"]
:compiler {
:output-to "gulpfile.js"
:optimizations :none
:pretty-print true}}]})
Here is my core.cljs
(ns gulpjs.core
(:require [cljs.nodejs :as node]))
(def gulp (node/require "gulp"))
(def gulp-livereload (node/require "gulp-livereload"))
(def gulp-markdown (node/require "gulp-markdown"))
(def gulp-watch (node/require "gulp-watch"))
(.task gulp "markdown"
#(-> (.source gulp "../markdown-explained")
(.pipe (gulp-markdown))
(.pipe (.dest gulp "build/markdown-explained"))))
Here is command I used to compile
lein cljsbuild once gulpjs
Compiling ClojureScript.
Compiling "gulpfile.js" from ["src/gulpjs"]...
Successfully compiled "gulpfile.js" in 3.316 seconds.
But I have this strange output gulpfile.js
, it doesn't look like node codes at all, why it is so wrong???
goog.addDependency("base.js", ['goog'], []);
goog.addDependency("../cljs/core.js", ['cljs.core'], ['goog.string', 'goog.object', 'goog.string.StringBuffer', 'goog.array']);
goog.addDependency("../cljs/nodejs.js", ['cljs.nodejs'], ['cljs.core']);
goog.addDependency("../gulpjs/core.js", ['gulpjs.core'], ['cljs.core', 'cljs.nodejs']);
Clojure is a functional programming language. The Clojure compiler turns Clojure sources into bytecode and runs it on the JVM. ClojureScript is another compiler for Clojure language that takes source code and compiles it into JavaScript language.
Open a terminal and type lein repl to start a Clojure REPL or start a REPL from your editor. The call to (run) starts the Figwheel server at port 3449, which takes care of live reloading ClojureScript code and CSS.
Since you are targeting nodejs, first thing that you are missing in the compiler options is
:target :nodejs
Second, if you use :optimizations :none
you are missing too the option output-dir
:
:output-dir "out"
Here is a nice briefing on the compiler options and characteristics: http://slides.com/joakino/diving-into-clojurescript/#/5 (Go down in the slides)
Then in your main file, you need to set a main function and it is nice to enable console prints:
(ns cljs-gulp.core
(:require [cljs.nodejs :as nodejs]))
(nodejs/enable-util-print!)
(defn -main [& args] ... )
(set! *main-cli-fn* -main)
Then, you can actually use any mode in nodejs, but the ones that work by default are simple
and advanced
. For none
you need a wrapper file to make node be able to load closure dependencies, so create a file named index.js
for example and put this in:
require('./out/goog/bootstrap/nodejs')
require('./cljs_gulp') // Name of the js ouput file
require('./out/cljs_gulp/core') // Path to compiled core file
cljs_gulp.core._main() // appname.namespace._mainfunction
And after compiling you would node index.js
instead of node cljs_gulp.js
. And that works awesome, and you take advantage of the super fast recompilation times.
This article explains it all pretty well, and it's recent: http://blog.lauripesonen.com/clojurescript-optimizations-on-node-huh/
Here is the code: (my project name was generated as cljs_gulp, so change that to fit yours)
project.clj
(defproject cljs_gulp "0.1.0-SNAPSHOT"
:description "Where I want to learn about clojurescript"
:url "http://example.com"
:dependencies [[org.clojure/clojure "1.7.0-alpha2"]
[org.clojure/clojurescript "0.0-2322"]]
:plugins [[lein-cljsbuild "1.0.4-SNAPSHOT"]]
:source-paths ["src"]
:cljsbuild {
:builds [{:id "gulpjs"
:source-paths ["src/cljs_gulp/"]
:compiler {
:target :nodejs
:output-to "cljs_gulp.js"
:output-dir "out"
:optimizations :none
:pretty-print true}}]})
src/cljs_gulp/core.cljs
(ns cljs-gulp.core
(:require [cljs.nodejs :as nodejs]))
(nodejs/enable-util-print!)
(def gulp (nodejs/require "gulp"))
(def gulp-livereload (nodejs/require "gulp-livereload"))
(def gulp-markdown (nodejs/require "gulp-markdown"))
(def gulp-watch (nodejs/require "gulp-watch"))
(defn -main [& args]
(.task gulp "markdown"
#(-> (.source gulp "../markdown-explained")
(.pipe (gulp-markdown))
(.pipe (.dest gulp "build/markdown-explained")))))
(set! *main-cli-fn* -main)
There are a couple of cljs node templates that are very helpful for getting started on cljs and node, instead of the browser:
This happens because you're using :optimization :none
.
This mode is aimed for active development with a rapid recompilation. That way cljsbuild
could recompile only the file you've changed without touching other stuff.
If you want to get a single js file, you should use either of following:
:optimizations :simple
:optimizations :advanced
This will take much more time but creates a single file with all dependencies included.
:advanced
mode will also clean dead code for you, thus making the target file even smaller.
But you should be careful using it, due to it have some pitfalls by the nature of closure compiler nicely described in this article.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With