Can I use arbitrary node modules from clojurescript?
Asked Answered
G

3

11

Is it possible to use arbitrary node.js modules in a clojurescript project? If yes, how do I go about including them? If not, why not?

Gandhi answered 6/6, 2014 at 23:36 Comment(0)
G
10

Yes, you can, there is nothing special about it:

(def fs (js/require "fs"))
(println (.readdirSync fs js/__dirname))

Be careful with the externs if you don't use optimizations none.

Edit: Does leiningen play with the various js package managers?:
Nope. Since the language does not have packages, it cannot know. You have to do js dependency management and lein deps too. There is a lein-npm and a lein-bower to help with integrating these two package managers.

Gait answered 7/6, 2014 at 12:42 Comment(2)
Nope. Since the language does not have packages, it cannot know. You have to do js dependency management and lein deps too. There is a lein-npm and a lein-bower to help with integrating these two package managers.Gait
Is it possible require a node module (i.e. "fs") into a cljs namespace such that you can access its methods directly? In this case, we would want to be able to say (readdirSync js/__dirname)?Stallworth
U
5

Yes, since late 2017. With shadow-cljs or Lumo now it's not problem to import npm modules in ClojureScript code anymore.

(ns app.main
  (:require ["dayjs"   :as dayjs]
            ["shortid" :as shortid]
            ["lodash"  :as lodash]
            ["lodash"  :refer [isString]]))

Read this topic for details: Guide on how to use/import npm modules/packages in ClojureScript?

Unpolite answered 19/6, 2018 at 10:26 Comment(0)
P
1

Since ClojureScript 1.9.854, there's better support to declare npm modules as dependencies and to require them from your namespaces.

In order to declare it as a dependency, you need to use the :npm-deps compiler option (together with the :install-deps one, if you want lein/bootto automatically install it).

:npm-deps is a map from keyword to string, where the keyword is the name of the dependency you would use to install it using npm and the string is the version of the dependency.

An example of what you could add to your project.clj (if you use lein-cljsbuild), in order to use left-pad:

:cljsbuild {:builds [{:id "prod"
                    :source-paths ["src"]
                    :compiler {:main left-pad-demo.core
                               :output-to "package/index.js"
                               :target :nodejs
                               :output-dir "target"
                               :optimizations :simple
                               :install-deps true
                               :npm-deps {:left-pad "1.2.0"}
                               :pretty-print true}}]})

And then, from your namespace, you can require it like so:

(ns left-pad-demo.core
  (:require left-pad))

Or so:

(ns left-pad-demo.core
  (:require ["left-pad" :as lp]))

A full working namespace could look like:

(ns left-pad-demo.core
  (:require left-pad))

(defn -main [s length]
  (console.log (left-pad s length)))

(set! *main-cli-fn* -main)

References:

Parson answered 14/1, 2018 at 5:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.