Fork me on GitHub
#clojurescript
<
2017-08-28
>
gastove02:08:49

O…kay, I feel… like I am losing my mind. I must be doing something derpy. I must. But what?

gastove02:08:54

I have a CLJS project.

gastove02:08:06

For a repl, I’m using figwheel.

gastove02:08:19

Emacs, CIDER. All that jazz.

gastove02:08:28

lein cljsbuild once — works great

gastove02:08:14

But if I jack in a cljs repl and try to eval a namespace, I get Namespace project.foo not found

gastove02:08:19

I can open project.foo

gastove02:08:21

And eval it

gastove02:08:26

It evals without error

dnolen02:08:40

@gastove it’s unclear what you are saying

dnolen02:08:48

the last statement contradicts what you just said

dnolen02:08:09

what are you actually doing differently that works and doesn’t work?

gastove02:08:21

What I’m experiencing seems to contradict itself. Apologies — let me try again.

gastove02:08:57

I have a project, baboon. I have a namespace, baboon.math, and another, baboon.shapes.

gastove02:08:13

baboon.shapes requires baboon.math

gastove02:08:49

If I open baboon.math and evaluate it, it evaluates just fine. No errors. Not a peep. I can change the namespace of my repl to it, call functions. Everything is ducky.

gastove02:08:08

If I open baboon.shapes and evaluate it, I get java.lang.IllegalArgumentException: Namespace baboon.math does not exist

dnolen02:08:25

so the problem is probably that you are not respecting classpath conventions

dnolen02:08:53

what is :source-paths set to?

gastove02:08:12

I’ve got clj and cljs in the same project, set up like so:

$ tree -L 2 src/
src/
├── clj
│   └── baboon
└── cljs
    └── baboon

dnolen02:08:37

that doesn’t look right

dnolen02:08:42

where are the source files?

gastove02:08:53

Oh sorry — just cut off in the output for brevity. Here:

gastove02:08:23

$ tree src/
src/
├── clj
│   └── baboon
│       ├── config.clj
│       └── server.clj
└── cljs
    └── baboon
        ├── core.cljs
        ├── math.cljs
        └── shapes.cljs

dnolen02:08:56

btw I’m not talking about cljsbuild :source-paths but Lein :source-paths

dnolen02:08:01

they are different things

gastove02:08:19

Well then.

gastove02:08:22

:source-paths ["src/clj"]

dnolen02:08:30

right won’t work

gastove02:08:43

Needs to include the cljs path?

dnolen02:08:26

classpath needs to set just like it does for Clojure source code

gastove02:08:11

okay, that does make more sense

gastove02:08:46

I did not apprehend that the two source-paths were different — I assumed the CLJS one was a contextual override of the CLJ one.

gastove02:08:50

Thanks very much!

gastove02:08:00

Aaaaand it works sensibly now

dnolen02:08:01

@gastove it’s definitely confusing since cljsbuild :source-paths doesn’t augment Lein :source-paths

dnolen02:08:35

might be a limitation of how Lein works? not sure

josh_horwitz13:08:57

Are there any articles on how to introduce ClojureScript into an existing React application?

Jon14:08:51

does it help?

josh_horwitz17:08:28

Thanks for the help

dnolen14:08:47

@josh_horwitz not really since introducing ClojureScript into an existing JS application period is not particularly straightforward

josh_horwitz14:08:31

Trying to figure out best way to do this, we use Clojure on our backend but I'm trying to convince our front end team to start using ClojureScript

josh_horwitz14:08:38

but we can not rewrite the entire app

dnolen14:08:01

@josh_horwitz it might become more straightforward in the future when we can build most things out of node_modules

dnolen14:08:22

but if you have a JS ecosystem heavy tooling thing going on you will have to be a bit patient

dnolen14:08:52

there’s just a ton of work to do and the lack of simplicity and standardization in the JS build system isn’t helping much 🙂

josh_horwitz14:08:55

That's for damn sure lol

josh_horwitz14:08:19

Well any help I can be @dnolen let me know how I can help, we are very JS ecosystem heavy currently

dnolen14:08:06

@josh_horwitz experiment with :npm-deps and give feedback about that

shaunlebron14:08:45

@josh_horwitz you can look at this example that @thheller put together for using cljs code in create-react-app https://github.com/thheller/shadow-cljs-examples/tree/master/cljs-react-app

dnolen14:08:17

@shaunlebron the caveat about shadow-cljs is that it doesn’t intend to support advanced compilation right?

dnolen14:08:41

in case of integrating with existing JS tooling I mean

shaunlebron14:08:02

I don’t know enough about it to say

dnolen14:08:31

pretty sure it doesn’t if you’re going to generate stuff that JS tooling can understand

dnolen14:08:13

@josh_horwitz worth playing around with shadow-cljs but know that a lot of ClojureScript libs do get written in mind that DCE and very sophisticated minimization is at play

shaunlebron14:08:20

I know it was a problem that he faced, and I’m pretty sure he said he got it working, i’d have to dig around or wait for his answer

josh_horwitz14:08:32

Thanks guys for the help, I'll dig into

:npm-deps
@dnolen and see how it goes

josh_horwitz14:08:37

I'm also wondering if I could build out a new feature and ship it along side the current JS app as perhaps a first entry to show the team cljs

dnolen14:08:36

@shaunlebron ah ok, looks like it got sorted with the expected caveats (externs yada yada) - thanks haven’t been following shadow-cljs very closely

roman01la14:08:20

@josh_horwitz yes you can, we have both JS and CLJS apps running together. CLJS app is using React and many other libs bundled within JS bundle.

dnolen14:08:15

@josh_horwitz the other options is to make your existing app a foreign lib and write some bits in ClojureScript - that’s probably the most popular way to go

roman01la14:08:19

Just don’t forget to alias cljsjs React namespaces to use React from JS bundle (it should be exposed globally, the easy way)

dnolen14:08:21

@josh_horwitz still to be very clear to set expectations - supporting JS tooling is just not a priority and that will never ever really be a goal

dnolen14:08:54

existing projects with very, very complex Webpack, Babel setups are just way outside our interest

dnolen14:08:19

we’re primarily interested in node_modules ingestion and that’s about it

josh_horwitz14:08:56

@dnolen Thanks , I agree, I have no interest in that either lol, just the current state of affairs

josh_horwitz14:08:57

Almost used more as a convincing piece of evidence once some ClojureScript can be shown and how great it is

dnolen14:08:36

@josh_horwitz another route might be using ClojureScript for UI testing?

dnolen14:08:01

you could easily integrate devcards, Figwheel hotloading without affecting the rest of your app

josh_horwitz15:08:12

That's a great idea

thheller15:08:26

@josh_horwitz part of the goals for shadow-cljs was integration into existing JS tooling (eg. webpack). if you already have a JS setup then shadow-cljs should be easy to integrate

thheller15:08:54

you can use it standalone of course as well

josh_horwitz15:08:32

thatnks @thheller , I'll take a look at that later today!

thheller15:08:53

:advanced works so the overhead is minimal, :npm-deps is the other path which should be better in theory. in practice however there are many speedbumps when importing JS code through closure so YMMV. it also requires rebuilding your entire toolchain.

josh_horwitz15:08:49

I know for me and my experience, when trying to introduce something new to an exisiting JS team, the least amount of speedbumps the better it is received, and the least work they have to do

thheller15:08:28

I made this teaser a while back. zero config integration with create-react-app (which includes webpack), so it is pretty smooth

thheller15:08:59

well you need some basic config nowadays but shadow-cljs init creates that

josh_horwitz15:08:51

That looks great @thheller , I'll have a chance later tonight to take a look at it

thheller15:08:05

cool, just ping me if you have questions. documentation is still a bit sparse

Jon15:08:56

I would suggest posting questions to the issues list or even http://clojureverse.org/, to make sure people following the same path may found results with Google, rather than asking again on Slack

Jon15:08:50

....then we can go even without a finished docs, like some projects in js world

richiardiandrea15:08:23

@jiyinyiyong this is a wonderful idea, I did not know we had an old-style forum available

Jon15:08:56

actually there's quite something in https://github.com/thheller/shadow-cljs/issues back in the past months thheller was adding features to shadow-cljs. some features are not documented well, but can be found inside issues list.

jamitter16:08:14

I'm using the cljs-ajax library in my project - and when I build with :target :nodejs and try to use it in my node app I get "Cannot find module: "@pupeno/xmlhttprequest". According to their change log I need to just npm install it but that doesn't seem to be working. Not sure what I might be doing wrong

genekim17:08:53

Hello! I’m a new member here, but I’ve been dabbling with Clojure for a year (thank you @mtnygard!), and after months of lurking, I tried my first ClojureScript project two weeks ago (because of the @ajpierce article on “up and running in 60 seconds”). Holy cow, I’ve been having more fun programming the last several weeks than I’ve had in years! I’ve been absolutely dazzled by it. For fun, I rewrote an app I did in JavaScript/TypeScript, and am dazzled by how quickly pieces of it are coming together. I want to write a blog post on my experiences, and I will have some thoughts on how to improve developer first experiences (e.g., better error messages when using out-of-date node.js version). But I’m now at total standstill trying to deal with my first “cljsbuild min” so I can push to Heroku. I’m using the node.js module twitter.text (https://github.com/twitter/twitter-text), which does things like character counting, tweet rewriting to insert links on hashtags/URLs, etc.. In project.clj, I have:

:npm-deps {:twitter-text "1.14.7"}
Everything works on dev builds, but when I do a “min build” that uses Closure Compiler, I get this run-time error in the browser.
app.js:993 Uncaught SyntaxError: Invalid regular expression: /()()(?!\uFE0F|\u20E3)(**)/: Nothing to repeat
      at RegExp (<anonymous>)
      at Y0 (app.js:993)
      at app.js:998
      at app.js:3164  
It looks like Closure Compiler is mangling the regular expression, making it invalid. Here’s what I’m pretty sure is the relevant line of code in the twitter-text node_modules: (i.e., I tried modifying this code to remove “(?!\uFE0F|\u20E3)“, and it did change the error message...)
vi node_modules/twitter-text/twitter-text.js:88
  twttr.txt.regexen.validHashtag = regexSupplant(/(#{hashtagBoundary})(#{hashSigns})(?!\uFE0F|\u20E3)(#{hashtagAlphaNumeric}*#{hashtagAlpha}#{hashtagAlphaNumeric}*)/gi);
Does anyone have any advice on what I can do, or a work-around so that my code can run? I.e., is there a way to have Closure Compiler not touch “twitter-text” npm module? Thank you so much in advance!!!

josh_horwitz17:08:33

@genekim Do you have a link to that article up and running in 60 seconds?

genekim17:08:19

Thanks @mfikes! (and Planck is amazing! :) I will try it out in a couple of hours — stoked that there may be a way to make this work! @josh_horwitz The @ajpierce article is here: https://ajpierce.github.io/posts/react-figwheel-npm-2/

mfikes18:08:27

@genekim Another alternative to try (presuming that the twitter-text code is indeed Closure-compatible, but just not using ES3) is to set the :language-in option to something appropriate https://clojurescript.org/reference/compiler-options#language-in-and-language-out

mfikes18:08:31

^ I think the docs there are incorrect in referring to the closure library; it should be referring to the compiler.

qqq19:08:47

for debugging cljs, are firefox/chrome on equal footing, or is one superior ?

dnolen19:08:49

Chrome has the best debugging experience by far

dnolen19:08:23

but source maps are reasonably supported in Firefox & Safari

genekim19:08:37

@mfikes Thx for tip, but giving up trying to make node-js or foreign-libs work.. Just included it in the html source, which turned out to be surprisingly easy to do! (Now grinding away, trying to get the externs right. :) I’ll revisit this “later”. 🙂

dnolen19:08:17

@genekim fwiw, it’s probably worth trying @mfikes suggestion as it might just work - one line change to your compiler options - figuring externs on your own is pretty tricky if you haven’t done that before

genekim19:08:28

@dnolen I tried @mfikes suggestion, but I couldn’t get it running in figwheel — I got an error like “couldn’t find ‘twitter-text’ namespace… I had in project.clj:

:foreign-libs [{:file "./resources/public/js/twitter-text.js"
                                    :provides ["twitter-text"]}]
and in events.cljs (or whatever), I had:
(:require [reagent.core :as reagent]
            [re-frame.core :as re-frame]
            [cljsclient.db :as db]
            [twitter-text :as twitter-text]
I suspect I got something wrong? And thank you!

mfikes19:08:31

@genekim There should be no need to alias a namespace to itself, but that’s probably unrelated

genekim19:08:49

(PS @dnolen : I was watching your video from 2013 on core.async when you were at NYTimes [an amazing org, by the way!] Was absolutely dazzled by how lovely core.async is… Thx for all your amazing work and outreach. I’m sure you get that all the time, but wanted to mention it here. :)

genekim20:08:29

@mfikes :provides is optional?

mfikes20:08:04

@genekim Nah… (:require [twitter-text :as twitter-text]) can be (:require [twitter-text])

genekim20:08:57

Ah! @mfikes got it… I’ve got a meeting I need to run to, but trying to find quickly regenerate the error so I can post it here. 🙂

genekim20:08:30

@mfikes @dnolen Thanks for preventing me from going down extern hole. 🙂 Here’s screenshot of the error I got with foreign-lib approach.

dnolen20:08:46

@genekim need more information - are you saying this is only under :advanced?

genekim20:08:02

This is actually in figwheel in “dev mode”…

dnolen20:08:05

the error message doesn’t seem like that’s the case to me

dnolen20:08:28

right so it just looks like a bug perhaps in your code? You didn’t get a compiler warning?

dnolen20:08:55

how are you referring to twitter-text in your source?

genekim20:08:14

“twitter-text” is defined in project.clj, and is “required” in a cljs.source file…

(defn compute-tweet-chars-remaining
  " given a string, compute the number of chars remaining allowed"
  [text]
  ; (let [remaining     (- 140 (js/twttr.txt.getTweetLength text))]
  (let [remaining     (- 140 (twitter-text/getTweetLength text))]
    remaining))

dnolen20:08:26

twitter-text isn’t going to work

dnolen20:08:42

not without specifying :global-exports

dnolen20:08:01

change your your :foreign-libs entry for that lib to include

genekim20:08:15

(sorry, I need to step out for a couple of hours. Thx in advance for any help, all!!!) I’ll be so happy when I can get this to work! 🙂

dnolen20:08:26

:global-exports {twitter-text twttr.txt}

dimovich20:08:54

he has that line commented out

dimovich20:08:23

so he's using (twitter-text/getTweetLength text)

dnolen20:08:40

@dimovich which won’t work w/o :global-exports

dimovich20:08:56

isn't :provides enough?

dimovich20:08:43

I'm having a similar issue, now trying with global-exports

dimovich20:08:12

so :provides makes synthetic names, while :global-exports links this name to the actual exported vars?

dimovich20:08:43

for example, I have this file

dimovich20:08:20

keep getting clojure.lang.ExceptionInfo: No such namespace: jsutils

anmonteiro20:08:01

@dimovich you don’t need to use global-exports in this case

anmonteiro20:08:26

your foreign lib doesn’t declare any variables in the global scope

dimovich20:08:09

maybe i've got wrong the :module-type

anmonteiro20:08:17

that shouldn’t matter

anmonteiro20:08:22

I’m trying locally

anmonteiro20:08:29

works for me

dimovich20:08:12

hmm... strange...

anmonteiro20:08:17

(ns foo.core
  (:require jsutils))

anmonteiro20:08:28

:foreign-libs [{:file "esrc/lib/utils.js"
                   :module-type :es6
                   :provides ["jsutils"]}]

anmonteiro20:08:53

which version of ClojureScript are you on?

dimovich20:08:50

will try again and report back

anmonteiro21:08:14

happy to look at a minimal repro

dimovich21:08:48

ok, will try to make one. thanks for the help

dimovich21:08:15

yeah, it's working

dimovich21:08:39

but I keep getting the error when trying to require it in the repl