lumo 2018-05-29

I do (:require [moment]) and sometimes I get the error:

No such namespace: moment, could not locate moment.cljs, moment.cljc, or JavaScript source providing “moment”

but not always

This is the classpath I feed into lumo:

src:/home/borkdude/.m2/repository/org/clojure/clojure/1.9.0/clojure-1.9.0.jar:/home/borkdude/.m2/repository/org/clojure/tools.cli/0.3.7/tools.cli-0.3.7.jar:/home/borkdude/.m2/repository/org/webjars/npm/moment/2.22.1/moment-2.22.1.jar:/home/borkdude/.m2/repository/org/webjars/npm/nodemailer/4.6.5/nodemailer-4.6.5.jar:/home/borkdude/.m2/repository/org/clojure/spec.alpha/0.1.143/spec.alpha-0.1.143.jar:/home/borkdude/.m2/repository/org/clojure/core.specs.alpha/0.1.24/core.specs.alpha-0.1.24.jar

@genekim has joined the channel

It’s this script that I’m using. Locally it works fine, on my server no. I’m using a newer lumo version on my server. https://github.com/borkdude/balcony/blob/master/lumo/scripts/balcony.cljs

Execute by ./balcony.cljs

I removed the -K option as well. I installed lumo 1.8.0 on my server and get:

No such namespace: moment, could not locate moment.cljs, moment.cljc, or JavaScript source providing “moment” in file cljs/tools/cli.cljs

When I try:

(def moment (node/require "moment"))
I get:
Cannot find module ‘moment’

I’m so close…

ah wait, locally it was still using my node_modules folder probably…

so I need to find a way how to get these webjars working, probably using foreign libs or something

To summarize: can I load javascript from a jar file in lumo, preferably inside the script and not in some external file

@borkdude you are not compiling down with browserify anymore? Because I though it would just concatenate all the js deps with that so no need for carrying it with you

@richiardiandrea I’m trying a different approach now, the one that I also took with clj. Using webjars it might be possible to avoid the build step.

If not then the customary method is to carry the node_modules folder with you

so I’m not loading any deps via npm anymore

But I don't think the folder is read from inside the jar

Well you can load .cljs files from a jar, why not .js files?

Uhm maybe :foreign-libs

Not sure at this point, I never really used :foreign-libs. It should maybe be possible given the cljsjs project is doing exactly that

now the thing I have to know is, can I load foreign libs from the repl

Never explored that path, let's wait for @anmonteiro. I would say you should be able to

maybe I should use cljsjs instead, I didn’t even think of that…

repro:

#!/usr/bin/env bash

":";momentjs='cljsjs/moment {:mvn/version "2.22.0-0"}'
":";src=$(clojure -Spath -Sdeps "{:deps {$momentjs}}")

"echo" "$src"

"exec" "lumo" "-c" "$src" "$0" "$@"

(ns balcony.core
  (:require
   [moment]))

(println (moment))

doesn’t work btw

I think the approach of bundling up to a single file is already cool, just seeing if I can get this approach to work

Yep I think it is nice to explore for sure

:foreign-libs are declared as compiler options so I was definitely wrong there

can I read files from the classpath from the REPL in lumo? if so, I think it’s a small step to loading the file?

there is no classpath of course

but you know what I mean

Read in what way?

Ah, and to just give it a filename of something that exists on the classpath. Hmm...

yeah and then eval it in node

That's a good question; I've never tried, but presumably there's a way to find files inside the classpath...?

Yes you can I think, the facilities are all there because this is what -D does

Ah, then eval it. I'm missing something I'm sure, but wouldn't require fit the bill there?

yeah, definitely

The only thing I don't know is if require can read from jars at the moment in the REPL

maybe read back a little 🙂

I am exploring

But you need to declare them somehow

Not sure how

Ok found

There should be a deps.cljs in the jar

@borkdude node/require only looks in node_modules

if you have the moment cljsjs thingy, you have to require it by its name

(require 'cljsjs.moment) or something

then use js/Moment or whatever global it exposes

Cool Antonio saves me from rabbit holing ;)

let me reiterate that none of this is specific to Lumo at all

👍 2

this is how it works in JVM CLJS too..

Can I load js from an npm webjar from the REPL though?

I think it needs to have the deps.cljs file?

ah:

cljs.user=> (require ’[lumo.classpath :as cp])
nil
cljs.user=> (cp/classpath-jarfiles)
(“/Users/Borkdude/.m2/repository/org/clojure/clojure/1.9.0/clojure-1.9.0.jar”
 “/Users/Borkdude/.m2/repository/org/clojure/tools.cli/0.3.7/tools.cli-0.3.7.jar”
 “/Users/Borkdude/.m2/repository/org/webjars/npm/moment/2.22.1/moment-2.22.1.jar”
 “/Users/Borkdude/.m2/repository/org/webjars/npm/nodemailer/4.6.5/nodemailer-4.6.5.jar”
 “/Users/Borkdude/.m2/repository/org/clojure/spec.alpha/0.1.143/spec.alpha-0.1.143.jar”
 “/Users/Borkdude/.m2/repository/org/clojure/core.specs.alpha/0.1.24/core.specs.alpha-0.1.24.jar”)

(cp/filenames-in-jar “/Users/Borkdude/.m2/repository/org/webjars/npm/nodemailer/4.6.5/nodemailer-4.6.5.jar”)
...

it’s a start… if the jar would have the minified version, it would probably work:

(.runInThisContext vm (.-source (js/$$LUMO_GLOBALS.readSource “META-INF/resources/webjars/nodemailer/4.6.5/lib/nodemailer.js”)))

I’m beginning to see why people just install yarn on their servers, because this is quite involved. In theory, we could make module loading work with npm webjars as well

Yes I think we actually could, maybe open an issue @borkdude?

Maybe first discuss if this is a good idea. The benefit would be avoiding npm and still being able to write a script with deps, like above, without polluting the script dir with node_modules, package.json etc

Personally I am specifically trying to port all the maven deps I use to npm

and there is one caveat. if you do something like

(.runInThisContext vm (.-source (js/$$LUMO_GLOBALS.readSource "META-INF/resources/webjars/nodemailer/4.6.5/lib/nodemailer.js")))
that file will do require(./mailer), I don’t know if we could trick node into reading the right file from the jar there

Right

I found that my company is more js oriented so we are trying not to use JVM stuff

for popular things we could always write a cljsjs, but then the repo already should have a minified version: e.g. https://github.com/moment/moment/tree/develop/min

and if it already has a minified version, it’s very easy to load it in node via webjars

Yeah, that has always been the deal breaker for me, why do I need another package

Yeah cljs could be greatly simplified if its only target is node

I think cljsjs was mainly built with browser in mind

maybe it’s not so hard to automate though, the minification step, so cljsjs could also be purposed for node

Given also that lumo does not know maven, I am not so convinced it is a good idea tbh ... You never know of course ;)

CLJSJS should include minified files

or rather, I know for a fact they do

Oh that's good to know, I actually thought they could be there already

@anmonteiro yes, but the examples I’ve looked at so far just get the minified file from e.g. http://registry.npmjs.org/moment/-/moment-2.22.0.tgz but for example http://registry.npmjs.org/nodemailer/-/nodemailer-4.6.5.tgz has no minified file

they just sift/move the files

Node.js packages are not minified

(sift :move {#“package/firebase-([a-z\-]*).js” “cljsjs/development/firebase-$1.inc.js”
                #“package/firebase=([a-z\-]*).js.map” “cljsjs/development/firebase-$1.inc.js.map”
                #“package/externs/” “cljsjs/common/“}
         :include #{#“^cljsjs”
                    #“^deps.cljs”})

I think this firebase thing is used from node as well

The community effort is smaller if the community is small. I guess.

anyway, I see why people say things like: yarn install on the server. because another way is quite complicated

Yeah, I am quite happy with it. JS tooling is smooth imho

what’s the benefit of yarn again though? it keeps a repo from which it copies deps, instead of downloading them all the time?

I don’t know enough about JS tooling. I hear mixed stories about it. Some people do everything to avoid it.

why doesn’t yarn make symbolic links to the cache dir though?

comes with it’s own set of problems

They say yarn has reproducible dep management

Dunno if it's true still though

Npm usually catches up quickly

because of the lock file right?

I think not because of that, probably the algo is different or something, not sure though

btw, the npm webjar idea might still be feasible with a tool like this: https://unix.stackexchange.com/questions/168807/mount-zip-file-as-a-read-only-filesystem mount the jar/zip into node_modules…