(require '[cljs.build.api :as b])
(b/build "src"
{:output-dir "out"
:output-to "out/main.js"
:optimizations :none
:main 'example.core
:install-deps true
:npm-deps {:react "15.6.1"
:react-dom "15.6.1"}})
2017 年 7 月 12 日
António Nuno Monteiro
2015 年 ClojureScript 的 Google Summer of Code 專案成功地簡化了與外部 JavaScript 模組的互動。依靠Google Closure Compiler當時理解大多數廣為人知的 JavaScript 模組格式並將其轉換為 Closure 相容 JavaScript 的新能力[2],Maria Geller成功地將這些模組功能整合到 ClojureScript 中,同時還有自訂預處理步驟,允許從您的 ClojureScript 專案中舒適地使用諸如流行的 JavaScript 編譯技術Babel等功能[3]。
自那時起,Closure Compiler 團隊在 2016 年增加了模組解析支援,這在其他方面能夠直接從 node_modules
安裝中使用模組,而不必為轉換提供 Closure 手工製作的模組路徑。
我們以 Maria 的模組工作為基礎,考慮到這個新的 Closure 功能,ClojureScript 的下一個版本代表了另一個重要的里程碑,它透過大幅改進 ClojureScript 與 NPM 生態系統的互通方式,使每個 ClojureScript 專案都能存取任意 JavaScript 模組。
自 ClojureScript 版本 1.9.518 以來,從 ClojureScript 命名空間要求 NPM 模組已成為可能。然而,Node.js 支援多種模式來要求 CommonJS 模組,而常見的痛點是人們希望從 ClojureScript 中要求 "react-dom/server"
形式的模組,這對 :require
規格來說不是有效的符號。
在這個版本中,我們在命名空間形式中加入了對基於字串的要求的支援,以解決上述問題。您現在可以從您的 ns
宣告中舒適地要求這些類型的模組。
將它們結合在一起的是 :npm-deps
編譯器旗標。在其中,我們告訴編譯器它應該知道哪些相依性。ClojureScript 將負責安裝這些相依性並將它們通過 Closure Compiler 轉換管道執行,包括我們在下面更詳細描述的優化。
給定一個如下所示的 build.clj
檔案
(require '[cljs.build.api :as b])
(b/build "src"
{:output-dir "out"
:output-to "out/main.js"
:optimizations :none
:main 'example.core
:install-deps true
:npm-deps {:react "15.6.1"
:react-dom "15.6.1"}})
您最簡單的 src/example/core.cljs
檔案可能看起來像下面的程式碼片段
(ns example.core
(:require [react :refer [createElement]]
["react-dom/server" :as ReactDOMServer :refer [renderToString]]))
(js/console.log (renderToString (createElement "div" nil "Hello World!")))
請注意,我們不必在任何地方宣告 "react-dom/server"
。我們可以要求它。ClojureScript 現在足夠聰明,可以找到這些 CommonJS 模組並將它們處理成與 Google Closure Compiler 相容的程式碼。
使用 Google Closure 消費 JavaScript 模組的含義是巨大的:ClojureScript 專案中使用的外部函式庫不再只是被添加到生成的捆綁包的前面,而是現在可以受到所有 Closure Compiler 的優化,包括無效程式碼消除,以及在利用程式碼分割的專案中,跨模組程式碼移動。例如,在我們的測試中,在 Closure 的進階編譯下,React 比使用現有的流行 JavaScript 工具小得多(約 16%)[4]。此外,如果您有一個 ClojureScript 和 JavaScript 的混合程式碼庫,您不僅可以無縫地使用程式碼的那些 JavaScript 部分(包括例如 JSX 轉換!),還可以與您的 ClojureScript 部分使用的那些程式碼共享和捆綁它們的供應商相依性。
經過將近 6 年,ClojureScript 是一個受到全球大量開發人員信賴的平台,我們希望繼續實現與主機的完全互通性。透過確保我們與廣大的 JavaScript 生態系統整合,我們認為即將在下一個 ClojureScript 版本中推出的這些新功能是確保 ClojureScript 長期可持續性的一個墊腳石。
我們希望您像我們一樣喜歡這些新功能。感謝您的閱讀!