Fork me on GitHub
#clojurescript
<
2018-08-04
>
sjol02:08:00

is there a complete example on how to use imported npm modules with a clojurescript app? I used lein new macchiato and am trying to use the google compute module that installs as npm install --save @google-cloud/compute and imports as const Compute = require('@google-cloud/compute');. I tried adding :npm-deps {"@google-cloud/compute" "0.10.0"} but I am getting:

No such namespace: @google-cloud/compute, could not locate _CIRCA_google_cloud_SLASH_compute.cljs, _CIRCA_google_cloud_SLASH_compute.cljc, or JavaScript source providing "@google-cloud/compute" (Please check that namespaces with dashes use underscores in the ClojureScript file name)
any tips, my searches are not turning up this use case for some reason...

sjol02:08:42

I also tried:

:foreign-libs [{:file "node_modules/@google-cloud/compute/src/index.js"
                                              :provides ["gcp"]} ]

b-paul02:08:59

@sjol I’m here with questions about npm-modules as well.

b-paul02:08:59

For yours, have you specified :install-deps true as well?

sjol02:08:42

Hmmm no, do I specify that in the compiler section? But I did install it manually with npm

b-paul02:08:59

Well, then that might not be it. I’m inferring that it might be required from https://anmonteiro.com/2017/03/requiring-node-js-modules-from-clojurescript-namespaces/

b-paul02:08:11

For anybody able to help, I’ll post mine as well. I’m trying to integrate https://emotion.sh/ using :npm-deps. It gets past the compiler, but fails to render and sends Undefined nameToPath for module$create_emotion to the JS console from inside goog/base.js

b-paul02:08:12

I suspect that means I need to write some externs (?) but haven’t figured out how to do that or how to tell the compiler about it in this scenario

sjol03:08:17

@b-paul it seems to have gotten me further but getting weird errors $module$_CIRCA_google_cloud$compute.Compute is not a constructor and can require it from the repl

(ns gcp-bot.routes
  (:require
    [bidi.bidi :as bidi]
    [hiccups.runtime]
    [macchiato.util.response :as r]
    ["@google-cloud/compute" :as gcp]
)
  (:require-macros
    [hiccups.core :refer [html]]))

(defn home [req res raise]
 (let [
   compute (gcp/Compute.)
   zone (.zone compute "us-central1-a")
   name "ubuntu-http"
   vm (.createVM zone name (clj->js {:os "ubuntu"}))
])
  (-> (html
        [:html
         [:head
          [:link {:rel "stylesheet" :href "/css/site.css"}]
          ]
         [:body
          [:h2 "Hello World! v3"]
          [:p
           "Your user-agent is: "
           (str (get-in req [:headers "user-agent"]))]]])
      (r/ok)
      (r/content-type "text/html")
      (res)))

sjol03:08:06

dev:cljs.user=> (:require ["@google-cloud/compute" :as gcp])
----  Compiler Warning on   <cljs form>   line:1  column:40  ----

  Use of undeclared Var cljs.user/gcp

  1  (:require ["@google-cloud/compute" :as gcp])
                                            ^---

----  Compiler Warning  ----

vigilancetech05:08:32

how would one make something like this compile w/o warnings against 1.9.660+ (Warn on variadic signatures in protocol method implementation)?:

IFn
  (-invoke [this & args]
    (apply assoc this args))
 

vigilancetech07:08:33

I'd like to use a library that depends on at least v1.10 of cljs but my program depends on a library that depends on something that depends on a library that depends on a function that's been deleted since 1.9.874. I tried recompiling against that library with every of its dependencies upgraded to "LATEST" but I'm still getting the error. Has anyone developed a tool to walk the dependencies of your application to find such things?

henrik07:08:13

What a rat’s nest! Try clojure -Stree, it should give you a tree of the deps.

mfikes12:08:26

@U2BL1A092 You could turn off that particular warning

mfikes12:08:36

Also, if you use the :aot-cache feature, a consequence is that once code is compiled and cached, you don’t see the same warning over and over again

vigilancetech14:08:00

@mfikes its not a warning. Its a fatal error due to a missing function.

vigilancetech14:08:48

Thanks @U06B8J0AJ. Yes, my problems rarely seem simple 😕 (or at least those are the only memorable ones). I'll check it out

mfikes14:08:50

@U2BL1A092 This is just a warning, if it is the same thing you are seeing.

cljs.user=> (deftype Foo []
       #_=>  IFn
       #_=>    (-invoke [this & args]
       #_=>      (apply assoc this args)))
            ^
WARNING: Protocol IFn implements method -invoke with variadic signature (&) at line 1
cljs.user/Foo

mfikes14:08:31

I suppose I’m conflating your two posts. Sorry.

vigilancetech14:08:36

yeah, no its

adzerk.boot_cljs.util.proxy$clojure.lang.ExceptionInfo$ff19274a: Invalid :refer, var cljs.reader/reader-error does not exist in file /home/kevin/.boot/cache/tmp/home/kevin/0work/newtest/kqe/n5ob01/index.html.out/tailrecursion/priority_map.cljs
    tag: :cljs/analysis-error

vigilancetech14:08:26

reader-error's been deleted but the version of priority-map that my library depends on is too old and still tries to call it

vigilancetech14:08:12

@U06B8J0AJ I see nothing in google for clojure-stree nor clojure stree

vigilancetech14:08:20

oh, I see it. Its an option to clj. Yeah, it was returning a bunch of results for clojure "street"

vigilancetech14:08:26

the problem is its not my code that calls it, nor the library I'm using, but something that library's calling

vigilancetech14:08:08

like I said, I changed all the dependencies of the library I'm calling to LATEST and the bug still showed up

mfikes14:08:09

It is failing when compiling tailrecursion/priority_map.cljs, right?

mfikes14:08:25

Are you using lein or clj?

mfikes14:08:22

In either case, check to ensure you are using 1.2.0 or 1.2.1 and that 1.1.0 isn’t on your classpath

mfikes14:08:53

lein deps :tree or clj -Stree

mfikes14:08:22

lein classpath or clj -Spath will show you the classpath you are getting

vigilancetech14:08:20

I'm using boot

mfikes14:08:03

I don’t have experience with boot, but I suspect it would amount to putting [tailrecursion/cljs-priority-map "1.2.1"] in your dependencies specification

vigilancetech14:08:14

its the hoplon/ui library that's pulling in cljs-priority-map

vigilancetech14:08:38

well, actually its pulling in something that's pulling that in

vigilancetech14:08:44

and its pulling in like 1.0.3

mfikes14:08:57

Right, you should be able to override it at your top level n your project

vigilancetech14:08:06

ok, I'll try that

mfikes14:08:08

(Or use exclusions if you really have to.)

vigilancetech15:08:43

hey, that seems to have worked! I put that dep in the hoplon/ui build.boot. Thanks!

vigilancetech15:08:57

for future such issues, you have any idea how to use -Stree from within boot to list cljs deps?

mfikes15:08:39

IIRC boot has a way to display the calculated classpath and I suspect it has a way to display the full dependency tree.

mfikes15:08:16

You can’t use -Stree — that’s an option to clj

mfikes15:08:32

It appears to be boot show --classpath and boot show --deps

👍 4
Karol Wójcik10:08:02

Hello all! Is there an option with the newest clojurescript to require build-in nodejs module like fs inside the ns?

henrik10:08:12

Sure! Just…

(:require [child_process :refer [execSync]]))
… for example.

henrik10:08:58

Doesn’t have to be built in either, I’m using…

["@material-ui/core" :refer [Menu MenuItem]]
… to access Material UI components in a #reagent based app, for example.

Karol Wójcik10:08:53

I am using the figwheel. Here is how my ns looks like:

(ns streams-vs-channels.seeder
  (:require [cljs.nodejs :as nodejs]
            [goog.string.format]
            [goog.string :as gstring]
            [clojure.core.async :as async]
            [fs :as fs]))
And I am receiving the following error: Figwheel: message from client couldn't be read! As I can see the cljs is unable to detect the node build-in modules

henrik11:08:35

Ah! Right. This all being said, I’ve never figured out how to get it to work in vanilla CLJS tools, only in #shadow-cljs .

henrik11:08:46

In shadow, it just works.

Karol Wójcik11:08:26

Thank you @U06B8J0AJ. I think that in vanilla CLJS it's not possible 🙂

Karol Wójcik11:08:32

I will use goog.provide then 🙂

henrik11:08:16

Really? I thought it was supposed to be possible.

henrik11:08:24

Either way, I’d recommend giving shadow-cljs a go. It’s a 5 minute set up or so, and it removes quite a few headaches.

henrik11:08:35

yarn add shadow-cljs, ./node_modules/.bin/shadow-cljs init

henrik11:08:26

Doesn’t affect your deps.edn or project.clj, so you can safely try it out in parallel.

mfikes11:08:00

@U9ARBCP5K Yes, you can do this in vanilla ClojureScript. We recently fixed https://dev.clojure.org/jira/browse/CLJS-2724 so perhaps you are missing that fix.

mfikes11:08:29

(That should be in 1.10.339)

mfikes11:08:48

Reading the backlog, CLJS-2724 shouldn’t affect you.

Karol Wójcik11:08:21

I am using the newest CLJS [org.clojure/clojurescript "1.10.339"]

mfikes11:08:38

Do you have node set up as :target?

Karol Wójcik11:08:11

Yes I do have:

:cljsbuild
  {:builds
   {:dev {:source-paths ["src"]
          :figwheel     true
          :compiler     {:output-to     "bundle/bundle.js"
                         :main          streams-vs-channels.core
                         :libs          ["src/foreign"]
                         :target        :nodejs
                         :optimizations :none}}}})

Karol Wójcik11:08:35

Ok it works with

(require 'fs)
(.log js/console fs)

Karol Wójcik11:08:44

But does not work in (ns)

mfikes11:08:50

I have a figwheel-main-based projects and I can require fs in an ns form.

Karol Wójcik11:08:11

Ok so maybe it's a problem with a regular figwheel

mfikes11:08:31

Let me see if I can repro with regular figwheel… I think this project used to be based on regular figwheel…

Karol Wójcik11:08:54

@mfikes I really appreciate your help.

mfikes11:08:37

@U9ARBCP5K Yeah, a :require of fs works for me in an older version of that project that uses regular figwheel

Karol Wójcik12:08:51

@mfikes could you please share your project.clj and the part of code in which you’re requiring the fs module?

mfikes12:08:31

With that setup I got No such namespace: fs, but now trying newer deps…

mfikes12:08:53

@U9ARBCP5K ^ that works (updating to latest deps

Karol Wójcik12:08:58

Could you please share the project clj? I think that this causes the problem ;(

Karol Wójcik13:08:45

@mfikes It's a problem with the cider itself I think. With the latest cider when I try to evaluate the ns with cider-eval-last-sexp then I got that error but in the figwheel console the module is correctly imported 🙂 Error occurs only in the repl.

Karol Wójcik13:08:06

Could you please confirm whether you experiencing the same issue? If so I will create the issue on cider's github and I will try to fix it.

mfikes14:08:20

@U9ARBCP5K I don’t use emacs

Karol Wójcik14:08:44

@mfikes Thank you for all your help I will try to debug that error in the emacs 🙂

jsa-aerial16:08:29

@U9ARBCP5K I don't know if this will help, but I've noticed that just loading a file (with namespace and resources) via figwheel typically does not make it 'really' available via repl in cider. You need to (cljs-repl) and then go to buffer and do a C-c C-k (compile buffer) to get everything workable from cider as well as figwheel. Or for this you would need to at least eval the namespace. I have no idea why this is true, but it is. Caveat: I'm on Cider and cider-nrepl 0.17.0

mfikes13:08:20

@sjol This seems to be working

$ clj -m cljs.main -co '{:npm-deps {"@google-cloud/compute" "0.10.0"} :install-deps true}' -re node -r
ClojureScript 1.10.339
cljs.user=> (require '["@google-cloud/compute" :as Compute])
nil
cljs.user=> (def compute (Compute.))
#'cljs.user/compute
cljs.user=> (.zone compute "us-centrall-a")
#object[Zone [object Object]]

fabrao15:08:08

Hello all, if I use in react import { something } from 'something-else'; -> (def Something (js/require "something-else")), what would be use for import something from 'something-else'; ?

fabrao15:08:00

(.-default something) ?

mfikes15:08:57

You can also always either evaluate things at the REPL to see what is in the object

mfikes15:08:44

or use js-keys

mfikes15:08:58

(js-keys Something)

fabrao15:08:22

@mfikes worked with (.-default ... , thanks

mfikes16:08:02

@fabrao cool. I suspect this ticket is about the same https://dev.clojure.org/jira/browse/CLJS-2376

bhauman18:08:21

still lots of work to do but the docs are coming along

jaihindhreddy-duplicate21:08:52

@bhauman Thank you sir for Figwheel and Devcards!