Skip to content

JavaScript Library Preprocessing

Shaun Mahood edited this page Mar 18, 2017 · 2 revisions

DEPRECATION NOTICE: Please do not edit this wiki. Instead submit pull requests to https://github.com/clojure/clojurescript-site

The up to date version of this page can be found at https://clojurescript.org/reference/javascript-library-preprocessing

ClojureScript allows you to add a custom transformation step for JavaScript libraries. This means that you are able to include JavaScript libraries in your project which are written in a dialect or make use of a JavaScript syntax extension. In order to effect the desired code transformation a defmethod which satisfies cljs.closure/js-transforms must be provided to the :preprocess option of the foreign library. For example, you can transform a JavaScript library using JSX into regular React function calls as follows:

(require '[cljs.build.api :as b]
'[clojure.java.io :as io])
(refer 'cljs.closure :only '[js-transforms])
(import 'javax.script.ScriptEngineManager)
(defmethodjs-transforms:jsx [ijs opts]
(let [engine (doto (.getEngineByName (ScriptEngineManager.) "nashorn")
(.eval (io/reader (io/file"babel.min.js")))
(.put"input" (:source ijs)))]
(assoc ijs :source
(.eval engine (str"Babel.transform(input, {presets: ['react']}).code")))))
(b/build"src"
{:main 'my-project.core
:output-to"out/my_project.js":output-dir"out":foreign-libs [{:file"libs/example.js":provides ["my.example"]
:preprocess:jsx}]})

The example above uses Babel to transform the JavaScript code by loading a minified version of babel-standalone using Nashorn. The js-transforms method gets and returns an object which satisfies the IJavaScript protocol. The object can be a plain map or a record with keys like :url, :provides, :requires and :source. The second argument, which is passed to js-transforms, is a map with the compiler options. The JavaScript preprocessing happens before module conversion, however, both steps are independent of each other and can be used in disjunction.

Clone this wiki locally