Fork me on GitHub
#shadow-cljs
<
2018-11-25
>
wilkerlucio05:11:09

is there a way to write portable libraries that include plain js files? I'm asking because by cljs standards they say to use :foreign-libs (https://github.com/clojure/clojurescript-site/blob/master/content/reference/packaging-foreign-deps.adoc), but shadow on the other side can import js files directly, but no :foreign-libs, I'm working in the Workspaces project and I have a dependency on a simple js file, is there a way to write it so users of the library get correct behavior with both standard cljs and shadow?

thheller10:11:13

@dspiteself looks like you are using a browser build in a non browser environment? something that doesn't have access to document

thheller10:11:59

@wilkerlucio the support for JS files in standard CLJS is absolutely terrible. they can't talk to CLJS code or import other code themselves

thheller10:11:08

but if you don't need that you can emulate the inclusion just like cljsjs

thheller10:11:54

hmm maybe not actually. I'm not sure if :foreign-libs are used before the classpath or after

wilkerlucio14:11:09

@thheller so the best option seems to be create a npm package a cljsjs package and a shadow-cljsjs to get it compatible?

thheller15:11:34

I'm not sure to be honest. what kind of JS file do you have?

wilkerlucio17:11:55

@thheller this is the file in question, its a fuzzy search algorithm: https://gist.github.com/wilkerlucio/221cda4bc18184ea827cbf1e545aa4a2

wilkerlucio17:11:32

I even started trying to convert, but its a very stateful procedural algorithm, that's actually better as is then trying to port it to functional I think

dspiteself18:11:09

Yea I am targeting a serviceworker which is like a webworker. https://developers.google.com/web/fundamentals/primers/service-workers/ It does not have document. It uses self.importScripts()

dspiteself18:11:46

It seems like it would need to be a different target

thheller20:11:17

@dspiteself try setting :modules {:main {... :web-worker true}}}

thheller20:11:47

@wilkerlucio I don't even know how you'd use that file with standard CLJS? did you get that working already?

wilkerlucio20:11:28

if I want to target a single compiler (regular cljs OR shadow) its easy

wilkerlucio20:11:33

using the foreign libs thing

wilkerlucio20:11:19

@thheller the problem is making something that works in both cases, I can't find a way to make those compatible

thheller20:11:58

how do you actually use that file with CLJS though?

thheller20:11:09

I mean how do you require it and access the code?

wilkerlucio20:11:33

you add something like this to deps.cljs:

wilkerlucio20:11:35

{:foreign-libs
  [{:file "react/react.js"
    :file-min "react/react.min.js"
    :provides ["com.facebook.React"]}]
 :externs ["react/externs.js"]}

wilkerlucio20:11:55

then you required the name said in the :provides, so, in this case: (:require [com.facebook.React])

wilkerlucio20:11:31

then the code is just injected

wilkerlucio20:11:19

and the file is expected to set globals, so very much like adding a new <script> tag, but goes in the same bundle

thheller20:11:46

yeah thats what I mean

thheller20:11:56

the file doesn't export any globals so you rewrite the file to make it work with CLJS?

wilkerlucio20:11:07

yeah, I would do that

wilkerlucio20:11:22

in this case is just 3 functions that are terrible to write in cljs 😛

thheller20:11:25

can't think of anything besides the usual cljsjs and shadow-cljsjs trick

wilkerlucio20:11:39

it sucks so bad, for such a small thing -.-

thheller20:11:15

I'm not sure if you maybe can write it in Closure JS and just import it directly

thheller20:11:27

shadow-cljs understands that but I'm not sure if CLJS does

thheller20:11:57

ie. you add a goog.provide("some.ns.fuzzy") some.ns.fuzzy.fn = function ...

thheller20:11:17

it might work

thheller20:11:18

yeah I think that should work

thheller20:11:30

transit-cljs is importing transit-js that way

thheller21:11:04

probably don't need the goog.scope stuff for your file since its so short

wilkerlucio21:11:34

interesting, so if I make it like a google closure module I can import it directly in regular cljs?

thheller21:11:59

I'd suggest using the "older" model the closure lib uses

thheller21:11:03

but yes you can import those directly

thheller21:11:42

just one goog.provide("some.ns")

thheller21:11:59

and then everything prefixed with some.ns.foo = function() ...

thheller21:11:20

or the way transit does it with goog.scope if you want local vars

wilkerlucio21:11:45

cool, I'll try the first

wilkerlucio21:11:52

@thheller this works, awesome! thanks for saving me on this one 🙂

wilkerlucio21:11:08

a new workspaces version will be out soon, I think you might like it, some fixes and improvements, including a better spotlight (using the new fuzzy search)

thheller21:11:52

sweet. I need to get back actually coding a bit .. too busy with other stuff the past few weeks

souenzzo21:11:22

$ shadow-cljs server
shadow-cljs - config: /home/souenzzo/src/my-next-stack/shadow-cljs.edn  cli version: 2.7.6  node: v11.2.0
shadow-cljs - running: lein with-profile client,webdev run -m shadow.cljs.devtools.cli --npm server
Executable '' not found on system path.
'' should be lein 🙂

thheller21:11:05

indeed. the error message is wrong

thheller21:11:09

but it is looking for lein

thheller21:11:59

is lein found via which lein?

souenzzo22:11:03

yep. already installed lein. Just reporting the wrong error message

thheller22:11:39

thx. just fixed it.

souenzzo22:11:56

http-root in devtools can be a array?

thheller22:11:07

no only one dir

thheller22:11:23

could add support for multiple if you need

souenzzo22:11:41

With figwheel, I use output-dir on target/public/js/out then serve target/public and resources/public (my index.html is on resources/public/index.html )

thheller22:11:19

you can set :http-resource-root "public"

thheller22:11:30

(in addition to :http-root)

souenzzo22:11:27

What is the difference between http-resource-root and http-root ???

thheller22:11:39

resources are served from the classpath

thheller22:11:45

http-root from the filesystem

thheller22:11:50

(this assumes that resources is on the classpath, which is is by default in lein but not shadow-cljs.edn)

souenzzo22:11:18

It's already working nice 🙂

souenzzo22:11:18

when I try to start shadow from repl I get

(shadow/watch :main :cards)
Execution error (ExceptionInfo) at shadow.cljs.devtools.server.runtime/get-instance! (runtime.clj:11).
missing instance

thheller22:11:06

the server needs to be running when you run in embedded mode

thheller22:11:22

the server/start!

thheller22:11:43

and (shadow/watch :main) (shadow/watch :cards)

thheller22:11:50

it only takes one build arg from the REPL

souenzzo23:11:55

In shadow-cljs how I handle things like [fulcrologic/fulcro "2.6.15" :exclusions [cljsjs/react]] ?? Should I exclude in project.clj and just add in package.json?