How to compile clojurescript to nodejs?
How to compile clojurescript to nodejs?
Why cljsbuild does not compile gulpfile.js file properly?
cljsbuild
gulpfile.js
Here is my project.clj config:
project.clj
(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
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???
gulpfile.js
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']);
3 Answers
3
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:
:optimizations :none
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:
simple
advanced
none
index.js
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.
node index.js
node cljs_gulp.js
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.
: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.
cljsbuild
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.
:advanced
As mentioned in previous answers, ClojureScript is compiled to browser and in development mode by default. To make sure it's compiled to Node.js , you need to specify :target :nodejs somewhere in the configurations.
:target :nodejs
I want to added that lein-cljs is not the only compiler tool for ClojureScript. shadow-cljs can be a better solution if you try https://github.com/minimal-xyz/minimal-shadow-cljs-nodejs .
lein-cljs
Besides, the code compiled from ClojureScript is written in Closure JS, which is using goog.x.y.z for creating its module system. So you have to bare the fact that the code looks far less like CommonJS. However you can use shadow-cljs and specify :target :commonjs if you insist.
goog.x.y.z
:target :commonjs
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
tks bro, your answer is correct but @Joaquin answer is more thoughtful and great either :)
– babygau
Sep 12 '14 at 9:46