ClojureScript 1.10.x 新技能 cljs.main 快速開啓

翻譯自 https://github.com/clojure/cl...
遇到問題, 請用英文反饋至 https://clojureverse.org/t/cl...

內容:node

  • ClojureScript 編譯器
  • 生產環境編譯
  • 在 Node.js 環境運行 ClojureScriptreact

    • Node.js REPL
  • 依賴

這個版本基於 macOS 或者 Linux, 須要系統已經依賴 Clojure. Windows 用戶請查看英文版.git

ClojureScript 編譯器

首先建立項目文件:github

mkdir hello_world; cd hello_world
mkdir -p src/hello_world; touch src/hello_world/core.cljs

在項目中建立 deps.edn 文件, 其中添加依賴:npm

{:deps {org.clojure/clojurescript {:mvn/version "1.10.145"}}}

在文件 src/hello_world/core.cljs 中填寫代碼:瀏覽器

(ns hello-world.core)

(println "Hello world!")

新手須要注意一下, 這裏的文件路徑, 跟 src/ 這個默認的資源路徑, 和 hello-world.core 這個命名空間對應. 同時, 連字符在 Java 世界須要在文件名當中改爲 _. 這個對於新手很容易形成誤會.bash

而後能夠啓動 ClojureScript 環境了:服務器

clj -m cljs.main -c hello-world.core -r

這個命令將會啓動一個瀏覽器, 同時在命令行打印 "Hello World!", 以及啓動一個 REPL. 接下來能夠在 REPL 當中嘗試運行一些代碼:app

(inc 1)
(map inc [1 2 3])
(.getElementById js/document "app")

回來看下命令參數, -m 全稱是 --main, 調用 Clojure 函數, 這裏是 cljs.main 當中的默認的 -main 函數. cljs.main/-main 支持一些其餘的參數對應具體的任務, 好比這裏 -c 全稱 --compile 表示編譯. 後面的 -r 全稱是 --repl 表示同時啓動一個 REPL:dom

而後試一下更新代碼, 剛纔那個文件更新成:

(ns hello-world.core)

(println "Hello world!")

;; ADDED
(defn foo [a b]
  (+ a b))
(require '[hello-world.core :as hello] :reload)
(hello/foo 2 3)

正常的話你會看到結果 5. (注: 然而看上去這裏是有 bug 的. 實際運行代碼並無更新成功. 並且報錯也沒有預期的 .cljs 文件.)

clj -m cljs.main -h

生產環境編譯

你注意到生成的 out/ 目錄的話, 會發現其中有好幾個 M 的文件內容. 這就須要 Google Closure Compiler 來幫助編譯優化, 從而獲得適合瀏覽器環境使用的代碼. 主要依賴代碼壓縮和 Dead Code Elimination.

咱們先把文件代碼恢復到 src/hello_world/core.cljs 以前的:

(ns hello-world.core)

(println "Hello world!")

-O 全稱 --optimizations 參數來構建. 默認的構建 level 是 none, 這裏咱們須要 Google Closure Compiler 所有的優化, 就制定 advanced. 此外 -O 還有兩個 level 分別是 whitespacesimple.

clj -m cljs.main -O advanced -c hello-world.core

這個編譯過程會有點費時間.

最後生成的 out/main.js 文件應該是 90k 左右, zip 以後還回到 20k. 這已經比 jQuery 要小了. ClojureScript 依賴的標準庫大約 10kloc, 依賴的 Google Closure Library 大約(200kloc), 能夠看到 Dead Code Elimination 是起做用了的.

你能夠經過 -s 全稱 --sever 參數啓動一個服務器來確認文件正常工做:

clj -m cljs.main -s

這個命令僅僅啓動服務器, 你須要自動打開 http://localhost:9000 的網頁來看運行結果, 包括在 Console 裏看 Hello World! 的內容. 這個服務器開啓了 gzip, 在調試工具當中應該看到 js 文件體積大約應該是 20k.

在 Node.js 環境運行 ClojureScript

Node.js 安裝過程就不說了, 版本號總之別過低. SourceMaps 須要本身安裝一下依賴:

npm install source-map-support

生成 Node 項目的話, 須要經過 -t 全稱 --target 來指定目標. 默認的目標是瀏覽器, 其餘目標還有 nashornrhino 這類的 JavaScript 運行環境. 這裏還用到了 -o 全稱 --output-to 來指定輸出文件:

clj -m cljs.main -t node -o main.js -c hello-world.core

而後能夠運行生成的文件:

node main.js
注意: 對於 Node 環境來講, 優化代碼的意義就不太大了, 引擎能力就很強大了, 通常用 simple 或者 none 做爲 level 已經夠了.
Node.js REPL

跟前面瀏覽器的例子同樣, 能夠啓動一個 Node.js 的 REPL. 指定 REPL 的環境用 -re 全稱 --repl-env. 默認狀況下是瀏覽器, 因此這裏須要指定是 node:

clj -m cljs.main -re node

而後應該就啓動了一個運行在 Node.js 上的 ClojureScript REPL.

依賴

ClojureScript 支持多種加載依賴的方式... 須要參考一下其餘文檔.

慣例 React 能夠再 CLJSJS 項目當中找到一個處理過的能夠直接引用的版本(注: 直接從 npm 引用更簡單, 這個教程不涉及到). 總之這個例子從 CLJSJS 引用 React.

{:deps {org.clojure/clojurescript {:mvn/version "1.10.126"}
        cljsjs/react-dom {:mvn/version "16.2.0-3"}}}

咱們來使用調用一下 react-dom 模塊的代碼

(ns hello-world.core
  (:require react-dom))

(.render js/ReactDOM
  (.createElement js/React "h2" nil "Hello, React!")
  (.getElementById js/document "app"))

運行一下瀏覽器環境:

clj -m cljs.main -c hello-world.core -r

而後你應該能看到一個頁面渲染很大的 Hello react! 的文字了.

相關文章
相關標籤/搜索