planck

Planck ClojureScript REPL
derpocious 2017-11-27T04:50:48.000068Z

Hey all! I'm having trouble using planck to load a file with dependencies. I want to use moment.js form the clsjs repository

derpocious 2017-11-27T04:51:09.000078Z

Here's my main file:

(ns jims-bas-ic-cljs-cron.derp
  (:require [cljsjs.moment :as m])
  )

(defn hola [hey]
  (apply max [1 4 5 8 12 1.3]))

derpocious 2017-11-27T04:51:15.000018Z

And my project.clj

derpocious 2017-11-27T04:51:35.000121Z

(defproject jims-bas-ic-cljs-cron "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure       "1.8.0"]
                 [org.clojure/clojurescript "1.8.51"]
                 [io.nervous/cljs-lambda    "0.3.5"]
                 [cljsjs/moment "2.17.1-1"]]
  :plugins [[lein-npm                    "0.6.2"]
            [io.nervous/lein-cljs-lambda "0.6.6"]
            [org.bodil/lein-noderepl "0.1.11"]]
  :npm {:dependencies [[serverless-cljs-plugin "0.1.2"]]}
  :repl-options {:init-ns jims-bas-ic-cljs-cron.core}  ; *** note: dashes in namespaces ***

  :cljs-lambda {:compiler
                 {:inputs  ["src"]
                  :options {:output-to     "target/jims-bas-ic-cljs-cron/jims_bas_ic_cljs_cron.js"
                            :output-dir    "target/jims-bas-ic-cljs-cron"
                            :target        :nodejs
                            :language-in   :ecmascript5
                            :optimizations :none
                            }}})

derpocious 2017-11-27T04:51:56.000194Z

I load up planck with planck -c src/

derpocious 2017-11-27T04:52:37.000004Z

then (require 'jims-bas-ic-cljs-cron.derp)

derpocious 2017-11-27T04:52:44.000076Z

But I get an error No such namespace: cljsjs.moment, could not locate cljsjs/moment.cljs, cljsjs/moment.cljc, or JavaScript source providing "cljsjs.moment" in file /Users/jameslynch/Git-Projects/Basic-Cron-Job-Clojurescript-Lambda/jims-bas-ic-cljs-cron/src/jims_bas_ic_cljs_cron/derp.cljs

derpocious 2017-11-27T04:53:32.000117Z

Surely it must be possible to somehow use clsjs libraries in planck?

2017-11-27T04:56:21.000089Z

@derpocious as far as I see planck doesn't use your project.clj https://github.com/mfikes/planck/blob/master/site/src/dependencies.md

derpocious 2017-11-27T05:15:30.000195Z

ah, so then I should explicitly try to load each library when I start planck?

derpocious 2017-11-27T05:17:07.000062Z

when I try to do (require 'cljsjs.moment) I get the error No such namespace: cljsjs.moment, could not locate cljsjs/moment.cljs, cljsjs/moment.cljc, or JavaScript source providing "cljsjs.moment". I don't see where that link addresses this

derpocious 2017-11-27T12:13:11.000343Z

Thanks @noisesmith. Can you please clarify how I can load this library from the repl?

mfikes 2017-11-27T12:29:07.000152Z

Responded in https://github.com/mfikes/planck/issues/553

mfikes 2017-11-27T12:38:03.000168Z

@derpocious I'll take a look today to see what is occuring when it process the internal deps.cljs to load cljsjs/development/moment.inc.js as a foreign lib

derpocious 2017-11-27T13:23:06.000136Z

Tanks @mfikes! I thought that "foreign lib" was referred to when you use straight up javascript library.

derpocious 2017-11-27T13:23:39.000093Z

Ah, I see now on here https://github.com/cljsjs/packages/tree/master/moment that it wants me to use deps.clj

mfikes 2017-11-27T13:23:41.000260Z

Yeah, it is essentially loading it as a JavaScript file.

mfikes 2017-11-27T13:24:18.000194Z

And Planck loads cljsjs/development/moment.inc.js into JavaScript core "straight up". But then the question is what happens when you do that.

derpocious 2017-11-27T13:24:58.000048Z

idk, what happens? 🙂

derpocious 2017-11-27T13:25:02.000525Z

you can use it like a namespace?

mfikes 2017-11-27T13:26:18.000092Z

Well the JavaScript file is written to assume support for certain loading systems. So, I haven't figure it out beyond that yet.

mfikes 2017-11-27T13:27:14.000459Z

It works in Lumo, FWIW, probably because the moment library makes use of Node.js in an interesting way:

$ lumo -qD cljsjs/moment:2.17.1-1
cljs.user=> (require 'cljsjs.moment)
nil
cljs.user=> js/moment
#object[hooks]

mfikes 2017-11-27T13:28:11.000233Z

But, to answer your question, you can't use foreign libs as a namespace (no Vars, nor namespace aliases, for example). After loading a foreign lib, you then use JavaScript interop to work with it.

derpocious 2017-11-27T13:29:17.000282Z

ahhh, ok

mfikes 2017-11-27T13:29:42.000101Z

If you look at cljsjs/development/moment.inc.js, you will see what I'm talking about.

derpocious 2017-11-27T13:31:29.000188Z

interesting. wow, thanks a lot! 🙂

derpocious 2017-11-27T13:32:24.000322Z

but suppose I want to load multiple libs into my project. Can I do that? Do I have to explicitly write all of them in the startup command?

mfikes 2017-11-27T13:35:32.000011Z

@derpocious Yes. Essentially, with regular ClojureScript, Planck, and Lumo, each lib you want to use needs to be on the classpath. With regular ClojureScript, you can use downstream tooling like lein to accomplish this. But with Planck and Lumo, you either hand-craft -c or use -D as sugar to specify libraries in .m2

mfikes 2017-11-27T13:41:04.000073Z

Having said that, there is a general move to have ClojureScript also support loading npm libraries (so from node_modules instead of the classpath)

derpocious 2017-11-27T13:44:11.000025Z

Yeah that would be great to be able to just do npm install - -save and just use it like a namespace. But can't we just use a package.json file?

derpocious 2017-11-27T13:46:12.000168Z

And I've heard that project.clj is only for lein. Is there no "project file" for planck or lumo? Why not hook into a project.clj and automatically require all the namespaces? :)

derpocious 2017-11-27T13:47:40.000166Z

I'm working on serverless nodejs aws lambda functions so everything is little functions, and I just want to be able to call them each from the repl.

mfikes 2017-11-27T13:49:17.000268Z

@derpocious It would probably be relatively easy to have Planck look for project.clj and deduce what the classpath needs to be. But a more difficult problem is ensuring that the libraries in project.clj have been dowloaded from a public repo and placed in your local Maven artifact cache.

mfikes 2017-11-27T13:50:18.000212Z

(The difficulty is that, while a lot of this tooling exists, it is based on the JVM, which Planck doesn't have at its disposal.)

mfikes 2017-11-27T14:17:15.000510Z

@derpocious For now, a workaround in Planck is to use (.. js/planck -repl -moment) in lieu of js/moment.

derpocious 2017-11-27T14:27:52.000047Z

Hmm ok, thanks!

mfikes 2017-11-27T14:28:20.000749Z

I'm going to see if I can fix it https://github.com/mfikes/planck/issues/554

derpocious 2017-11-27T14:28:58.000095Z

Can you suggest how I could use this js library https://github.com/ttezel/twit/blob/master/README.md in a clojurescript function and call it from planck?

derpocious 2017-11-27T14:29:11.000234Z

Ok great :)

mfikes 2017-11-27T14:32:14.000047Z

@derpocious It looks like that library is heavily set up to use Node.js. It has require calls in its source, which don't exist in Planck's JavaScriptCore runtime. You might be able to do something funky like use ClojureScript's new npm support, ultimately having Google Closure converting the stuff to Closure Compatible code. What you really want, though is plain JavaScript

mfikes 2017-11-27T15:41:28.000010Z

Thanks for the report @derpocious. Landed a fix on master.

$ planck -qD cljsjs/moment:2.17.1-1
cljs.user=> (require 'cljsjs.moment)
nil
cljs.user=> js/moment
#object[hooks]
If on macOS, master can be installed via brew install --HEAD planck