前言
書接上一回,在瞭解cljs基本語法後並在clojurescript.net的奇特錯誤提示後,我們必須痛定思痛地搭建一個本地的開發環境,以便後續深入地學習cljs。
現有的構建工具
由於瀏覽器僅能執行JS,而無法直接執行cljs,因此我們需要搭建一個預編譯環境將cljs編譯成JS後再在瀏覽器中執行。預編譯無非就是JVM和Nodejs兩個環境,但具體使用時有如下幾種構建工具。
- 直接JVM編譯
- Lein方案
- Boot方案
- Lumo方案
- Shadow-cljs方案
- cljs/tool方案
其中Lein和Boot都是基於JVM編譯環境,只是上層的構建方式有所不同,而Lein除了用於構建cljs外還用於構建clj;而Boot則專注於構建cljs。
Lumo則是基於Nodejs編譯環境。
Shadow-cljs則是node-jre,就是用node模組管理的jvm。
由於我們只需搭建一個剛好可用的開發環境即可,因此下面只介紹方案1。
搭建一個最基礎的——直接JVM編譯
下載依賴
- Jdk8.0+
-
建立工程
# 在家目錄下建立工程目錄
$ mkdir -p ~/hello_world/src/hello_world/
# 複製cljs.jar檔案到工程目錄下
$ cp ~/cljs.jar ~/hello_world/
# 建立專案配置檔案
$ touch ~/hello_world/build.clj
# 建立原始碼檔案
$ touch ~/hello_world/src/hello_world/core.cljs
# 建立HTML檔案
$ touch ~/hello_world/index.html
在build.clj
檔案中輸入
(require '[cljs.build.api :refer [build]])
(build "src"
{:main 'hello-world.core ; 指定程式入口名稱空間
:output-to "main.js"}) ; 指定目的碼入口所在檔案
;; 注意:其餘依賴模組的目的碼預設會生成在out/下
在src/hello_world/core.cljs
檔案中輸入
(ns hello-world.core)
; 標準輸出重定向到js/console.log
(enable-console-print!)
(println "Hello world!")
在index.html
檔案中輸入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<!--必須放在body中,否則搭建Browser REPL時會報
Uncaught TypeError: Cannot read property 'appendChild' of null
at goog.net.xpc.CrossPageChannel.<anonymous> (crosspagechannel.js:482)
-->
<script src="main.js"></script>
</body>
</html>
現在到了最激動人心的一刻了!編譯君!在shell中執行
$ java -cp cljs.jar:src clojure.main project.clj
然後開啟瀏覽器訪問index.html就可以在console中看到那句熟悉的Hello world!了。
現在每次修改程式碼後均要編譯一下,要知道啟動Clojure是那麼的漫長,所以我新增watch.clj的配置,讓它監控src檔案的變化來實現自動編譯吧!
(require '[cljs.build.api :refer [watch]])
(watch "src"
{:main 'hello-world.core ; 指定程式入口名稱空間
:output-to "main.js"}) ; 指定目的碼所在檔案
然後執行
$ java -cp cljs.jar:src clojure.main watch.clj
就會自動編譯了,是不是舒心多了!等等,還不夠。對於快速開發而言,我們還需要一個REPL!
搭建Browser REPL
首先安裝個rlwrap,後面會用到!
新增repl.clj檔案
(require '[cljs.build.api :refer [build]]
'[cljs.repl :refer [repl]]
'[cljs.repl.browser :refer [repl-env]])
(build "src"
{:main 'hello-world.core
:output-to "main.js"})
;; 配置REPL
(repl (repl-env)
:watch "src" ; REPL自動監控src目錄下的cljs檔案
:output-dir "out") ; REPL重用build函式已編譯的檔案
修改src/hello_world/core.cljs
檔案
(ns hello-world.core
(:require [clojure.browser.repl :as repl]))
;; 啟動Browser REPL
(defonce conn
(repl/connect "http://localhost:9000/repl"))
(enable-console-print!)
(println "Hello world!")
然後執行
$ rlwrap java -cp cljs.jar:src clojure.main repl.clj
然後開啟瀏覽器訪問http://localhost:9000/
,這時瀏覽器訪問的是index.html頁面,然後我們按F12
開啟瀏覽器的console,那麼shell中就會有我們心儀已久的REPL了!
這時我們在core.cljs中追加下面程式碼
(defn add [& more]
(reduce + 0 more))
然後在REPL中載入這個名稱空間
(require '[hello-word.core :refer [add]])
(add 1 2 3) ; -> 6
然後再將add改成multi
(defn multi [& more]
(reduce * 0 more))
然後在REPL中重新載入這個名稱空間
(require '[hello-word.core :refer [multi]] :reload)
(multi 2 2 3) ; -> 12
現在我們可以繼續深入cljs的學習咯!!!
總結
開發環境搭建好了,那接下來要從哪裡入手呢?大家是不是對(require '[cljs.repl :refer [repl]])
和(require '[cljs.repl :as repl])
等有些疑惑呢?後面我們就從名稱空間開始吧!(cljs/run-at (JSVM. :browser) "名稱空間就這麼簡單")
尊重原創,轉載請註明來自:http://www.cnblogs.com/fsjohnhuang/p/7087902.html ^_^肥仔John