Fork me on GitHub
#clojurescript
<
2015-06-15
>
dnolen00:06:17

@shaunlebron: cljs.repl APIs are public

shriphani01:06:19

hello everyone a cljsc question. I want to generate a standalone js file from my cljs. Is there a way to do this with lein cljsbuild ?

Slackbot01:06:19

I think you mean friends...

shriphani01:06:01

or is using cljsc a requirement ?

dnolen01:06:31

@shriphani: making standalone files is definitely supported

dnolen01:06:48

ClojureScript has no “runtime” component

shriphani01:06:57

so…. how ?

shriphani01:06:02

my google fu is failing me

dnolen01:06:26

@shriphani: that’s just simply how ClojureScript works if you use any optimization setting other than :none

shaunlebron01:06:50

@dnolen: okay, I thought that was the purpose of the cljs.*.api namespaces, to indicate stable public APIs. which other namespaces are public?

dnolen01:06:23

@shaunlebron: cljs.repl is the only real exception to the rule.

shriphani01:06:46

@dnolen: another question. Can I get a minified js file with only my stuff and everything else that I can throw into a CDN ?

shriphani01:06:06

sorry - unclear. js only with my stuff. dependencies and goog.* in a separate file

dnolen02:06:25

@shriphani: when using any optimization level other than :none you end up with a single JavaScript file.

dnolen02:06:02

@shriphani: if you haven’t gone through the Quick Start I highly recommend it. It covers all the basics.

shriphani02:06:20

@dnolen: going through it right now. thanks.

shaunlebron02:06:43

@dnolen: can you confirm these parsed cljs.repl symbols should be public: https://github.com/cljsinfo/api-refs/tree/catalog#cljscompilerapi

dnolen03:06:35

@shaunlebron: well probably need to go in there and mark some helper things private. A lot of it is public but not everything.

shaunlebron03:06:18

@dnolen: okay, I’ll cherry-pick symbols from cljs.repl for the reference until then

aengelberg03:06:41

@dnolen What is the end goal exactly of being able to compile the cljs compiler to js? Since the Closure compiler is a big part of cljs compilation, I'm curious how that could be used from within cljs.

robert-stuttaford07:06:01

is anyone using cljc and Prismatic Schema together? i’m really struggling with can’t-find-var cljs compilation errors for this library when i use it in a .cljc file

danielcompton08:06:26

@robert-stuttaford what's the error message exactly?

robert-stuttaford09:06:02

"Caused by: java.lang.RuntimeException: No such var: su/NamedError"

robert-stuttaford09:06:11

we reference schema.utils/NamedError directly

danielcompton09:06:49

Does the same code work without cljc?

danielcompton09:06:21

I'd be surprised if it's a cljc issue, that's meant to be pretty transparent

jrychter09:06:02

Does ^:const on defs actually do anything in cljs? Should I bother?

robert-stuttaford10:06:12

its not cljc, you’re right. for some daft reason, i’m getting this: java.lang.RuntimeException: No such var: s/EnumSchema when i try (require ‘[schema.core :as s]) s/EnumSchema EnumSchema itself: https://github.com/Prismatic/schema/blob/27668958099092a17b5c31db68824cda0914d08f/src/cljx/schema/core.cljx#L295

robert-stuttaford10:06:30

i should totally be able to do this but i’m not. clj and cljs both bugging out

robert-stuttaford10:06:24

do i use require or import for defrecord / deftype declarations?

robert-stuttaford10:06:31

fixed! -mutter,mutter-

robert-stuttaford10:06:45

@danielcompton: thanks for your awesome reader conditionals post. helped me switch very easily! http://danielcompton.net/2015/06/10/clojure-reader-conditionals-by-example

mfikes11:06:48

@jrychter: ^:const prevents redefining and also facilitates use in case. See CLJS-806.

dnolen11:06:54

@aengelberg: there a significant number of scenarios where having the compiler compiled to JavaScript benefits.

dnolen11:06:20

for some applications JVM requirement is burden or non-starter - Electron or Raspberry Pi

dnolen11:06:47

for online tutorials it’s nice to drop evaluator service component - just static files

dnolen11:06:01

also for simple scripting, while it’s unclear yet, I suspect a bootstrapped ClojureScript will just start / run, use less memory faster for very short lived processes.

dnolen11:06:05

those are the concrete benefits

dnolen11:06:26

@aengelberg: Closure is an important part but it’s role is primarily to deal with shipping to typical JavaScript clients where network latency dominates. That aspect is less useful in the above scenarios.

mfikes11:06:08

I’d also like an iPad app that has a stand-alone built-in REPL (w/o network access) that runs right in JavaScriptCore. (Maybe a future React Native project.)

dnolen11:06:28

@mfikes: right iOS is another place where getting a JVM is … unlikely simple_smile

jrychter12:06:53

@mfikes: Ok. But it doesn't influence the way the code is compiled — no need to use it for optimization purposes, then.

thheller14:06:43

@dnolen: I'm curious. How come you stick with the separate ns for macros pattern (ie. cljs.env.macros) instead of putting them in cljs.env now that that is a .cljc?

dnolen14:06:25

@thheller: reader conditionals don’t change how macros work in ClojureScript

dnolen14:06:46

you cannot mix macros into ClojureScript source, and a bootstrapped compiler isn’t going to change that

dnolen14:06:51

breaks portability

thheller14:06:27

I'm aware of that. But you can put them behind $?(:clj ...) and (:require-macros [cljs.env :refer ...])?

thheller14:06:33

just saves the extra file?

dnolen14:06:34

hrm just didn’t try that as it wasn’t clear to me that it wouldn’t have issues.

dnolen14:06:05

other than that no real reason

robert-stuttaford14:06:36

be cool if you could

thheller14:06:44

ok, not important really. just was curious if there was a reason other than habit

thheller14:06:22

I don't see why you shouldn't be able to mix macros in as long as they are hidden for cljs

dnolen14:06:35

thheller: hrm actually the problem with that is if the body of the macro is different, which in this case they are slightly different.

dnolen14:06:09

and macros just see :clj there’s no way to communicate that the macros are being loaded into a :cljs context

dnolen14:06:28

not yet anyway

thheller14:06:00

@dnolen not sure I understand what you mean? as long as its behind #?(:clj ...) cljs doesn't see it at all and it would be the same like it is now in cljs/env/macros.clj

thheller14:06:07

same macro rules apply after all

dnolen14:06:44

@thheller: what you showed about shows loading the same ns with :require-macros to get the macros.

dnolen14:06:53

But those macros are not the right macros.

thheller14:06:58

ah, I see it now. There are still macros in cljs.env

dnolen14:06:13

right so your approach works if the macros themselves are portable

thheller14:06:19

ah this is confusing. One macro expands to clojure and one to cljs. Didn't notice that.

thheller15:06:07

well once cljs can compile itself (and do macro expansion) you should be able to put them behind #?(:cljs ...)

aengelberg15:06:02

@dnolen IIRC the closure library is prominent in compiled cljs code. What if the cljs-in-cljs->js target code depends on closure lib code that was compiled away (or had their names minified) by the initial cljs->js compile (using :advanced optimization)? Perhaps you've thought of this and are taking care of it, but that's the part that seems non obvious to me.

dnolen15:06:38

@aengelberg: closure lib is not really all that prominent in cljs.core. goog.base, goog.string, goog.object, goog.array. That’s about it.

dnolen15:06:40

@thheller: right only works if you are already bootstrapped, but really that makes it generally unusable

dnolen15:06:11

@aengelberg: advanced compilation and optional bootstrap are just orthogonal goals

dnolen15:06:02

that is if you’re using bootstrapped compiler you probably don’t care about the size of the generated code

dnolen15:06:07

which you won’t in the use cases I outlined above

dnolen15:06:45

this is why bootstrap will always be optional - it’s a benefit with significant tradeoffs at odds with how ClojureScript is leveraged today.

aengelberg15:06:40

So will goog.string (etc) always be there in the "host environment" without closure compiler obfuscation?

aengelberg15:06:44

Not sure if "host environment" is the right term in this case

dnolen15:06:09

Yes no minification no tree shaking

dnolen15:06:35

Though nothing will preclude applying Closure to the generated source yourself

mfikes15:06:29

Curious about @jrychter ’s earlier question; wrote up some exposition on ^:const for case: http://blog.fikesfarm.com/posts/2015-06-15-clojurescript-case-constants.html Hope it helps!

rauh15:06:42

Can you core.match againts ^:consts? Or do we still need a let binding indirection?

jrychter16:06:25

@mfikes: hey, cool! This is a great explanation. My (uninformed) thinking was more along the lines of "make something ^:const and avoid var lookups when it's used".

mfikes16:06:42

@jrychter: Yeah. Me too, given the Clojure semantics of ^:const.

shaunlebron18:06:52

mfikes just posted an article about seeing emitted js for a cljs expression in the repl: http://blog.fikesfarm.com/posts/2015-06-15-see-js-in-cljs-repl.html

maria20:06:32

Just published a small post for GSoC week 3 : http://mneise.github.io/posts/2015-06-15-week-3.html 😉

bhagany21:06:15

@maria I love reading these. Thanks!

maria21:06:55

@bhagany: glad you find them useful simple_smile

nullptr21:06:03

maria: great stuff!

mfikes21:06:03

@maria: Awesome! One question brewing in my mind: How do we reference symbols in the resulting generated Closure libs from ClojureScript? I succeeded by using a “fully qualified” munged symbol that bakes in the file path, but was wondering if shorter names can be used. If this hasn’t been sorted yet—cool—am just curious.

mfikes21:06:12

Here is the “munged” example: (module$libs$german.hello)

maria21:06:42

@mfikes: You can refer to the module as if it would be a regular Google Closure module, e.g.:

(ns hello-world.core
  (:require [greeting :as g]
            [goog.string :as string]))

(enable-console-print!)

(println (string/startsWith "Hello" "H"))
(println (g/hello "Welt!"))

mfikes21:06:42

@maria: That’s awesome!

maria21:06:28

or you can even use refer:

(ns hello-world.core
  (:require [greeting :refer [hello]]))

(enable-console-print!)

(println (hello "Welt!"))

danielcompton21:06:34

@maria: does this mean that we’ll need to recursively reference all dependencies of a lib we want to use?

maria21:06:56

not sure yet, if we can change anything about that.

mfikes21:06:00

Hmm. Perhaps Closure would handle loading transitive dependencies?

mfikes21:06:59

One example, greeting refers to german, which doesn’t have to be explicitly loaded.

maria21:06:03

maybe…there are still some things we need to figure out 😉

danielcompton21:06:18

Also, what will happen if you depend on a library which has two versions of the same package somewhere in its dependency tree?

danielcompton21:06:35

Just questions, I’m sure you can work them out, I’m looking forward to this

maria21:06:16

@danielcompton: not quite sure how this could happen. Do you mean in case the user specifies two different versions of the library in the compiler options?

dnolen21:06:40

@danielcompton: that's not really a problem as we just rely on Maven to prevent stuff like that.

dnolen21:06:09

that is we're not going to suddenly adopt NPM semantics

danielcompton21:06:36

Sorry, I’ll rephrase my question. I don’t fully understand everything that’s going on so maybe this isn’t an issue. If we have a commonjs JS library query which relies on liba and libb, and liba and libb both depend on different versions of promise-lib, will this cause any issues?

dnolen21:06:28

No new issues than those that already exist under Maven

danielcompton21:06:35

but if we’re interoperating with common JS, won’t we have two :foreign-libs entries with the same :provides but from different versions?

dnolen21:06:15

Not possible under Maven as I said :)

danielcompton21:06:10

That seems like a fairly common case for JS libraries though no?

dnolen21:06:46

I’m not sure what you mean

dnolen21:06:59

JS has no native notion of packages or dependencies

danielcompton21:06:15

Hmm, I think I may be getting things confused with how NPM does it

dnolen21:06:43

yeah NPM isn’t JavaScript simple_smile Also the NPM way doesn’t work for clients. Which is why Bower exists.

dnolen21:06:57

And more or less why we don’t use either for the most part and the quick rise of CLJSJS to popularity

danielcompton21:06:15

So does that mean you won’t be able to just use arbitrary NPM packages in CLJS with this patch?

dnolen21:06:55

NPM integration doesn’t really have that much to do with generic CommonJS support.

dnolen21:06:23

the work doesn’t preclude someone else leveraging it for NPM but it’s orthogonal

danielcompton21:06:39

gotcha. I think that’s where I was getting confused

meow21:06:02

Q? for OM users: is it a bad idea to do

:target js/document.body
for an om/root?

danielcompton21:06:30

Thanks for patiently clarifying simple_smile

dnolen21:06:19

@meow: only insofar as that’s a bit weird as Google Closure encourages inlining scripts into body for latency reasons

meow22:06:39

@dnolen: okay, thanks

nullptr22:06:09

dnolen: that guidance was pre async loading, i wonder if it's changed since

dnolen22:06:39

@nullptr: nothing has changed to my knowledge

dnolen22:06:26

oh if you mean async loading in head perhaps

dnolen22:06:54

but the really you still want to insert the script tag exactly when enough of the page has loaded

nullptr22:06:27

right, i mean the former not the latter -- they definitely are still doing that

nullptr22:06:04

early days of closure they were loading script in iframes and controlling the dom of the parent -- not sure that's still common ...

markstang22:06:16

@dnolen: defmacro, way cool, some serious fu...

mfikes22:06:51

Everybody: Don't bother David for the next four hours and a self-hosting ClojureScript will pop out the other end. :)

markstang22:06:25

Wait, he is building ClojureScript in ClojureScript - head explodes...

mfikes22:06:58

Yeah, let him work on it ;)

aengelberg22:06:37

Exciting stuff.

meow23:06:13

@shaunlebron: Just ran across this, very nice. Some really good links at the end, too. (One has a minor typo - the "ClojureScript Style Guide" is the "Clojure Style Guide") Thanks for putting it together! https://github.com/shaunlebron/ClojureScript-Syntax-in-15-minutes