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
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
For reference: https://github.com/borkdude/balcony/blob/master/balcony.clj
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
right
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?
like slurp
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 🙂
Ha, my bad.
🙂
https://github.com/anmonteiro/lumo/blob/master/src/cljs/snapshot/lumo/repl.cljs#L292
I am exploring
Seems like it should be doing it: https://github.com/anmonteiro/lumo/blob/master/src/cljs/snapshot/lumo/repl.cljs#L233
But you need to declare them somehow
Not sure how
Ok found
https://github.com/anmonteiro/lumo/blob/master/src/js/lumo.js#L251
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
this is how it works in JVM CLJS too..
Cool!
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 thereRight
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
e.g. this one: https://github.com/cljsjs/packages/blob/master/firebase/build.boot
ah well
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…