Fork me on GitHub
#clojurescript
<
2017-10-30
>
cmal03:10:35

Hi, how to set pseudo element CSS such as input::placeholder in garden?

rarous08:10:03

maybe ask in #garden

vinai06:10:35

I'm trying to use cljs as part of an existing application. The existing app uses requirejs as the basis for an elaborate frontend system. If I load the main.js via a script tag in the html page head I get

core.cljs?rel=1509349831285:15 Uncaught ReferenceError: ReactDOM is not defined
    at example_demo$core$render_BANG_ (core.cljs?rel=1509349831285:15)
    at core.cljs?rel=1509349831285:24
I believe the issue might be that requirejs loads all dependencies into a non-global scope, so js/React does not work. The file react.inc.js and react-dom.inc.js are being loaded according to the network tab.

cmal09:10:39

@vinai I have a require.js project which runs cljs compiled js files.

cmal09:10:58

I add some compiled files to ejs file and avoid using require.js to compile them.

vinai09:10:54

@cmal Thanks for getting back to me. I've managed to load the code using the requirejs config shims to declare the dependencies between cljs_deps.js, cljs_deps.js and goog/base.js

vinai09:10:10

Still ReactDOM isn't being loaded though.

cmal09:10:20

And another way want to add cljs compiled files as npm modules, but not yet tested now.

vinai09:10:57

I am trying to get a nice development setup running so I don't want to use any optimizations.

cmal09:10:05

what do you use to compile your cljs files?

cmal09:10:40

I don't think figwheel compiled files can do this. Have you tried shadow-cljs?

vinai09:10:42

well, clojurescript compiler -> closure compiler -> triggered and loaded via figwheel

vinai09:10:53

shadow-cljs? never heard of it

vinai09:10:19

Interesing

cmal09:10:15

what ever you use, you should extern the React and ReactDOM if you use cljsjs, otherwise they will get compiled away. I am not sure whether this is your problem.

vinai09:10:06

I'm using react and react-dom deps from cljsjs so I think the externs should be taken care of.

vinai09:10:41

It works fine if I load the main.js as the sole JS application on a page (outside of the existing legacy app)

vinai09:10:05

I'll try shadow-cljs anyway.

cmal09:10:09

Can I see your source code?

thheller09:10:20

require.js is not supported by shadow-cljs

cmal09:10:51

If you can load the advanced compiled main.js, that is not the problem which I refer to.

vinai09:10:30

At the moment I've thrown away all the source to debug another issue I've run into, which I think is related to the rendering system of the existing app. If I execute even one line of Cljs the <body> tag of the page dissapears. Just a namespace is enough to make it happen.

vinai09:10:44

(ns example-demo.core)

(.log js/console "Hi, maybe?")

vinai09:10:05

Hi, maybe? is output and then the page goes blank.

cmal09:10:37

I don't know whether the main.js can be used in require.js, I just avoid using it. The shadow-cljs author @thheller is an expert in this aspect.

vinai09:10:16

@thheller I only need to run my app on a page where other require.js code is present, I don't want to use AMD/require.js modules from within cljs. Is that still a problem with shadow-cljs?

thheller09:10:18

not sure, its been a while since I looked at a require.js project.

vinai09:10:23

@cmal Thank you for your help.

cmal09:10:08

@vinai Do you have a demo project? maybe I have some time right now and I can test for this.

vinai09:10:56

@cmal The app I wat to sneak ClojureScript into is based on http://github.com/magento/magento2/

cmal09:10:00

I also want to know 😄 I am developing in a require.js project using cljs to compile new files, too.

vinai09:10:06

It's a PHP ecommere framework.

vinai09:10:21

I really dislike the frontend rendering system so I would LOVE to get cljs to work in there

vinai09:10:08

@cmal Thanks for you offer, I don't have a small demo project available, because the demo project is this large monster.

vinai09:10:42

@cmal Have you used shadow-cljs to compile cljs in your app successfully?

thheller09:10:50

@vinai if you have the .js file that is loaded on the page I can take a look

thheller09:10:08

then I can tell you if its possible to integrate cljs into that or not 😉

thheller09:10:24

can I look at any magento demo?

vinai09:10:06

I'm loading the cljs with this code into the page:

<script>
    var CLOSURE_UNCOMPILED_DEFINES = {};
    var CLOSURE_NO_DEPS = true;
    require(['/out/compiled/cljs_deps.js'], function () {
        goog.require("devtools.preload");
        goog.require("process.env");
        goog.require("example_demo.core");
    });
</script>
I'm triggering the loading the goog dependencies with this shim config:
var config = {
    shim: {
        '/out/compiled/goog/deps.js': {
            deps: ['/out/compiled/goog/base.js']
        },
        '/out/compiled/cljs_deps.js': {
            deps: ['/out/compiled/goog/deps.js']
        }
    }
};

vinai09:10:59

If I add a :require [cljsjs.react] to the ns then react gets loaded but js/React isn't defined.

cmal09:10:59

@thheller I am working on a project in which I want to compile some cljs to npm mobule and include in require.js . Can this work? I can give you my code later if you have time to look.

thheller09:10:17

that doesn’t work since goog.require is async and does not coordinate with require

thheller09:10:45

@cmal sure, just ping me in #shadow-cljs. can’t really say if it can work without seeing the js

cmal09:10:15

OK. I will work on that today.

vinai09:10:17

@thheller Was that a reply to me or to cmal?

thheller09:10:37

require(['/out/compiled/cljs_deps.js'], function () {
        goog.require("devtools.preload");
        goog.require("process.env");
        goog.require("example_demo.core");
    });

vinai09:10:48

That works thanks to the requirejs-config shims.

thheller09:10:03

ah wait there is a build step involved?

vinai09:10:12

only figwheel so far.

vinai09:10:33

Would happily try shadow-cljs if you think it might help.

thheller09:10:34

ah the shim config is used at runtime?

vinai09:10:43

Yes, it is used at runtime.

thheller09:10:06

safe to assume that your setup looks similar?

vinai09:10:59

I'm actually trying this on a stock magento installation with that sample data in it to first tackle Magento integration, and then integration with all the custom code in a second step.

thheller09:10:19

geez that setup is horrible 🙂

thheller09:10:43

is there no built-in “optimize js” thing?

vinai09:10:04

yes, there is a development mode and a production mode where the JS is precompiled.

thheller09:10:08

downloading a bajillion separate files is so ten years ago

vinai09:10:26

That compilation bundles and minifies the JS.

vinai09:10:59

That demo instance is running in dev mode.

vinai09:10:10

(ns example-demo.core
  (:require [sablono.core :as sab]
            [cljsjs.react]
            [cljsjs.react.dom]))

(.log js/console "CLJS init")

(defn render! []
  (.render js/ReactDOM
           (sab/html [:div
                      [:h1 "Magento integration done"]])
           (.getElementById js/document "demo")))

(render!)
This is what I'm trying to get to work.

thheller09:10:02

I don’t quite understand how everything fits togehter

thheller09:10:18

do they support using commonjs files?

thheller09:10:27

its not gonna be easy to integrate cljs into this mess to be honest 🙂

thheller09:10:40

you can however treat it completely independent

thheller09:10:51

just skip the entire commonjs thing

thheller09:10:34

include the main.js generated by CLJS in a separate script tag BEFORE any other

thheller09:10:55

then just use it directly

vinai09:10:33

That would require modifying the core code of the existing app which really wants to load requirejs first. Still, might fall back to that.

vinai09:10:43

I agree it is a horrible mess.

cmal09:10:04

@thheller That is a good idea. I just don't know how to create npm modules from shadow-cljs. I will just try to include the compiled js file into a separate script tag.

vinai09:10:55

If I have to modify the platform code to load the cljs main.js first I think I might not get my code into the sytem 🙂

vinai09:10:07

The policy is to avoid what they call "core hacks"

vinai09:10:22

I'll spend another hour or two to find a workaround.

vinai09:10:38

A million thanks for looking into it @thheller

vinai09:10:45

I much appreciate it.

thheller09:10:35

@cmal do you mean create npm package you can publish to npm?

thheller09:10:15

IF the require.js stuff can include any commonjs you can use

cmal09:10:16

Yes, I am trying to include the .js file compiled by shadow-cljs into require.js , too.

thheller09:10:35

{:target :npm-module :output-dir "lib/web/cljs"} or so

cmal09:10:11

So I will try both. :npm-module and a separate script tag.

thheller09:10:35

magento is too huge to even figure out what is going on

thheller09:10:41

a minimal example would be good 🙂

cmal09:10:55

BTW, @thheller will goog-compiler compile out all the non-related code other than those related to the ^:export function?

thheller09:10:07

depends but ideally it should yes

thheller09:10:02

if you use :npm-modules you can specify :entries [some.ns ...] so it doesn’t include everything in your source path

thheller09:10:09

only things reached by the given entries

cmal09:10:24

OK. I will have a try.

mindenaaron09:10:31

Hello guys! This is the first time i tried making google closure externs and using them with :advanced compilation. My extern javascript file has a constructor called CrossStorageClient with some prototype functions. My ext.js looks like this: var CrossStorageClient = { "_generateUUID": function () {}, "_getOrigin": function () {}, }; CrossStorageClient.prototype = { "clear": function () {}, "close": function () {}, ... etc I achieved that now closure doesnt rename any functions in my extern js in advanced mode, I can def (def storage (new js/CrossStorageClient "http://...")) but then if i tries to call (.close storage) closure renames storage and .close too Sorry as i said im pretty noob to the closure compiler. What is the point here? any help is appreciated my fellow Clojurians!

thheller10:10:35

/** @constructor */
var CrossStorageClient = function(url) {};
CrossStorageClient.prototype.close;

mindenaaron10:10:54

It works! Thank you! 🎉

thheller10:10:20

should be the minimal for the above

vinai11:10:42

quick follow up from earlier - the only way I managed to get things to work is indeed by loading main.js first, before requirejs is included.

mbjarland12:10:59

considering the following trend graph from google: https://trends.google.com/trends/explore?date=today%205-y&amp;q=vue.js,react.js,angular.js it seems that vue is gaining popularity as compared to react. I'm new to clojurescript, but it seems that most of the buzz in the cljs community is still about react integrations (om (next), reagent, re-frame) and the community seems eerily quiet about vue (or I'm just hanging out in the wrong rooms). Is this just because vue is newer or is there some fundamental reason it doesn't play well with cljs or is otherwise not a good option?

sundarj13:10:54

react works fine, there's no real reason to switch away

sundarj13:10:38

searching for Vue here https://clojurians-log.clojureverse.org returns more stuff

mbjarland13:10:08

@U61HA86AG thank you for the pointers! seems there are mutability concerns with vue...I received some comments from my .Net friends that react bound the ui too tightly to the data model, but I'm not really sure I see that with om.next (admittedly with my limited understanding of om.next)

sundarj13:10:32

no worries 🙂

Nikita A Dudnik12:10:19

it was never about react's popularity first version of om was written before the hype train had started there are technical reasons for using react

mbjarland13:10:20

thanks for the answer, like I said I'm new to clojurescript so I'm not trying to critique the status quo, I think the options in clojurescript land look quite promising from where I stand...but I also feel humbled by the number of frameworks involved and my lack of knowledge. Would you care to elaborate on any of the technical reasons to go with react vs vue?

Matthew Davidson (kingmob)13:10:43

Not @U050C3W27, but the primary reason is that React very nicely maps to functional programming model. For the most part, outputs are just functions of their inputs, which plays well with Clojurescript. Vue offers that, but it also offers things like two-way bindings, which don’t play as well.

Nikita A Dudnik13:10:43

@U4VDXB2TU just give it some time. learn the basics and clojure way of doing things and you'll get it

plexus13:10:08

I'd add that there probably isn't that much to gain from using Vue over React, from a ClojureScript perspective. All that React really gives us is a virtual dom implementation, most of the other stuff like how you do templating and structure components is defined by the ClojureScript libs, React is just a low level API they build on, so a lot of what Vue does different isn't that relevant here. Given that this is a small ecosystem with limited manpower, people probably prefer to focus their efforts instead of going after the hype of the day. React isn't going away, after all.

Nikita A Dudnik13:10:32

@plexus thanks for elaborating. I'd write the same if I had time 🙂

mbjarland15:10:51

@U050C3W27 I don't have an issue with the clojure way, I'm on a fairly friendly basis with clojure, just new to cljs

mbjarland15:10:09

thanks both for the clarification!

Sebastian13:10:18

I have a question regarding figwheel. I have a small example app which clojurescript only consists of a run function printing "Hello world" to the console. I added figwheen and expected, after I changed the "Hello World" string to something else to have it change on the client as well when running the run function through the developer console. It didn't work. Am I missing something? The full repo (as said, very small) can be found here: https://github.com/elevantorg/beta.elevant.org/tree/2c4aa3cc9029e1f0af9a924bbd7cfbb4b2a764be

Sebastian13:10:03

The websocket and everything is working, as changing css is pushed to the client and applied automatically

plexus13:10:18

If you wanted to profile and speed up a Clojurescript (Figwheel) build, where would you start?

plexus13:10:54

We have a dev setup with Figwheel, and it's taking 5 seconds for each change to be compiled and reloaded, which is a lot slower than we expected...

genRaiy13:10:40

hi folks - quick question when using auth0.js lock component

genRaiy13:10:06

there is one oddity (.on lock "authenticated" on-authenticated)

genRaiy13:10:09

the lock object is a def with hard-coded data in the namespace

genRaiy13:10:50

but when I try to code the lock with dynamic data I cannot seem to attach the on listener

genRaiy13:10:47

i.e. does not work when the lock object and the event listener are declared via defn

genRaiy13:10:52

any thoughts?

genRaiy13:10:25

I’m sure I am missing something dumb as I’ve been bashing on it for an hour or so and cannot work it out 😕

plexus13:10:04

@raymcdermott I also don't see it... are you sure these are the only differences?

plexus13:10:37

what error are you getting? do you have a repl to poke at stuff?

metametadata14:10:54

You may try these tweaks in project.clj:

:cljsbuild {:builds [{:id           "dev"
                        :compiler     {

                                       ; speeds up compilation:
                                       :recompile-dependents false ; this makes hot reloads noticably faster! but in very rare cases can cause stale code bugs?
                                       :parallel-build       true ; mostly speeds up initial compilation
...

mfikes14:10:56

@raymcdermott The only thing I can think of (a stretch, and a guess), is that the lock object has nothing preventing it from being GC'd in your second example.

plexus14:10:26

thanks @metametadata, but we already have both of those flags set

genRaiy14:10:57

@mfikes the problem I have is that I don’t want to def the lock - it needs to be created based on some config I obtain from the server side

genRaiy14:10:26

I was thinking about writing a macro but it seems like overkill

genRaiy14:10:33

@plexus yes I’m using figwheel

genRaiy14:10:10

@plexus the problem is that it just doesn’t run so no error

genRaiy14:10:54

FWIW the re-frame loop goes around again after the lock has been completed

genRaiy14:10:22

(it does this when it works too … but in that case some state has been created in the DB from the callback)

genRaiy14:10:27

hmmm - when I add a subscribe to the needed config data, it works second time around

genRaiy14:10:41

this feels like voodoo!

genRaiy14:10:17

obviously having to run the login twice is no good so it’s still essentially a fail

genRaiy14:10:26

but clearly it’s a timing issue

genRaiy14:10:47

scratch that … it works but then open the lock so ordering as well as time

genRaiy15:10:37

ok, I got it working … changed to using the day8.re-frame.async-flow-fx

genRaiy15:10:34

that allows you to declaratively link connected events

genRaiy15:10:25

fwiw this is what it looks like

genRaiy15:10:06

nice solution, if a head scratcher for a newb like me

genRaiy15:10:21

even simpler …

Sebastian18:10:51

I was able to pin my problem (see above) further down: figwheel does not pick up my changes. Do I have to run lein cljsbuild auto in parallel? I was under the impression figwheel does this automatically!

noisesmith18:10:06

in my experience figwheel reloads files when they change, but things like switching git branches or running a clean and compile in another window can get it confused about the file state (it can end up watching a file that was deleted, and not see the new file with the same name for example)

noisesmith18:10:00

but even when that happens, running clean-build then build-once will typically get it back on track without a full restart

Sebastian18:10:31

In my case, nothing seems to work. As said, css watcher works fine but cljs doesn't. Running (build-once) in the repl does change the files in resources/public/js/out but does not push it to the browser

Sebastian18:10:07

I'm wondering if there is an issue with my setup, serving the static assets through compojure handlers. The figwheel docs do say "This will start a server at http://localhost:3449 with your resources being served via the compojure resources ring handler."

kennytilton18:10:37

Any recommendations on how to mock web responses? I see ring.mock suggested but can only find ways to mock requests. So far my search has me leaning to https://github.com/johanhaleby/stub-http.

xiongtx23:10:01

Is it just me, or does cljs.pprint/cl-format behave differently from clojure.pprint/cl-format?

(doseq [x [1 2 3]]
  (cljs.pprint/cl-format true "~A" x))

1
2
3
(doseq [x [1 2 3 4 5]]
  (clojure.pprint/cl-format true "~A" x))

123nil

lincpa09:10:02

cl-format cann't very good support fload, double, datatime