为什么cljsbuild
无法正确编译gulpfile.js
文件?
这是我的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}}]})
这是我的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"))))
这是我用来编译的命令
lein cljsbuild once gulpjs
Compiling ClojureScript.
Compiling "gulpfile.js" from ["src/gulpjs"]...
Successfully compiled "gulpfile.js" in 3.316 seconds.
但是我有这个奇怪的输出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']);
答案 0 :(得分:11)
由于您的目标是nodejs,因此编译器选项中缺少的第一件事是
:target :nodejs
其次,如果你使用:optimizations :none
,你也会错过选项output-dir
:
:output-dir "out"
以下是关于编译器选项和特征的精彩简报:http://slides.com/joakino/diving-into-clojurescript/#/5(在幻灯片中下载)
然后在你的主文件中,你需要设置一个main函数,启用控制台打印很好:
(ns cljs-gulp.core
(:require [cljs.nodejs :as nodejs]))
(nodejs/enable-util-print!)
(defn -main [& args] ... )
(set! *main-cli-fn* -main)
然后,您实际上可以在nodejs中使用任何模式,但默认使用的模式是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
编译完成后,node index.js
代替node cljs_gulp.js
。这很棒,你可以利用超快的重新编译时间。
这篇文章很好地解释了这一点,它是最近的:http://blog.lauripesonen.com/clojurescript-optimizations-on-node-huh/
以下是代码:(我的项目名称生成为cljs_gulp,因此请更改以适合您的项目)
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)
有几个cljs节点模板非常有助于开始使用cljs和节点,而不是浏览器:
答案 1 :(得分:3)
这是因为您使用的是:optimization :none
。
此模式旨在通过快速重新编译进行主动开发。这样cljsbuild
只能重新编译你改变的文件,而不会触及其他东西。
如果您想获得单个js文件,则应使用以下任一方法:
:optimizations :simple
:optimizations :advanced
这将花费更多时间,但会创建一个包含所有依赖项的单个文件。
:advanced
模式也将为您清除死代码,从而使目标文件更小。
但你应该小心使用它,因为它有一些陷阱,因为闭包编译器的性质很好地描述了in this article。
答案 2 :(得分:0)
如前面的答案中所述,ClojureScript默认情况下会编译为浏览器并处于开发模式。为了确保将其编译为Node.js,您需要在配置中的某处指定:target :nodejs
。
我想补充一点,lein-cljs
不是ClojureScript的唯一编译器工具。如果您尝试https://github.com/minimal-xyz/minimal-shadow-cljs-nodejs,shadow-cljs可能是更好的解决方案。
此外,从ClojureScript编译的代码是用Closure JS编写的,它使用goog.x.y.z
创建其模块系统。因此,您必须裸露一个事实,即代码看起来远不像CommonJS。但是,如果您坚持使用,可以使用shadow-cljs并指定:target :commonjs
。