Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compile clojurescript to nodejs?

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']);
like image 951
babygau Avatar asked Sep 12 '14 07:09

babygau


People also ask

Is ClojureScript the same as Clojure?

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.

How do I start ClojureScript REPL?

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.


2 Answers

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:

  • https://github.com/swannodette/mies-node-template (most recent and complete one)
  • https://github.com/liwp/nodecljs-template
  • https://github.com/honza/cljs-node
like image 151
Joaquin Avatar answered Oct 13 '22 06:10

Joaquin


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.

like image 44
Aleksei Avatar answered Oct 13 '22 07:10

Aleksei