Fork me on GitHub
#clojurescript
<
2015-12-13
>
mike01:12:10

how to import custom closure javascript code into clojure?

jaredly02:12:16

there seem to be some subtleties to require order — if I order things one way, I get “undefined” for imported identifiers. Does anyone know of a good wiki page or walk-through on this?

mfikes03:12:53

@jaredly: Hmm… perhaps something you are requiring itself doesn’t properly require its own deps.

jaredly03:12:24

ahhh yeah it looks like I had the wrong ns declaration facepalm

mfikes03:12:47

@jaredly: Ahh cool. (As an aside, I don’t believe there is a guarantee of ordering.)

jaredly03:12:21

I’ve definitely had an ordering error (a couple of days ago), where reordering imports fixed it 😞

thheller10:12:51

@jaredly: require order does not matter, if it does it is most likely due to some undeclared deps in your files.

jaen10:12:10

@mfikes: I actually thought require ordering was changed to keep the ordering you used in the ns form, because someone reported a bug that manifested due to them not being order, but I couldn't find the commit afterwards, so I might have imagined that '

thheller10:12:14

candidate #1 for broken ordering are multi-methods since you can call the defmulti without having to require the namespace that contains the defmethod

thheller10:12:30

for most other things the compiler should complain

thheller10:12:50

although cljs.closure still has the issue that warning are only emitted once

thheller10:12:10

and incremental compilation hides them after 😞

thheller10:12:02

so they are hard to track down sometimes

thheller10:12:16

or use shadow-build 😎

mfikes14:12:27

@thheller @jaen @jaredly I created a sample repo that shows that ClojureScript does not preserve order. Interestingly, the repo does not show that this is the case for Clojure.

jaen14:12:29

Then I must have been imagining things, I was almost sure someone brought it up before and a fix was made for that. This has also bit me once or twice in the past.

mfikes14:12:50

@jaen: Hmm. Maybe you are recalling something from the Clojure side. Maybe it came up as an issue in Clojure and was addressed there.

jaen14:12:24

Could be, though I was pretty sure it was Cljs. But well, memory likes playing tricks : V

mfikes14:12:40

@jaen: I’ve also seen something in the ClojureScript AST that appears to be keeping track of the order that symbols have been seen.

jaen14:12:57

Oh, so maybe there was a fix, solved some surface issue, but not the root of it. But no matter, it's irrelevant whether I was imagining things or not in the end ; d

mfikes14:12:19

Nicola Mometto confirmed that Clojure does preserve order, but that this is only an implementation detail.

jaen14:12:25

That's... peculiar. I imagined it would be a conscious choice since require order might matter.

mfikes14:12:47

That raises an interesting question: Are there cases where you need order but can’t establish it by saying ns a depends on ns b via a :require spec in a?

jaen14:12:02

I don't remember what I was doing that I would have needed deterministic ordering, but in general - that's a good question.

jaen15:12:23

Just to make sure - we're talking about ordering of clauses within a single ns declaration, yes? As in

(ns something
  (:require cljs.react my.namespace))
not shuffling cljs.react and my.namespace around?

mfikes15:12:58

Yes, the question has to do with trying to establish order via the textual order in an ns form. Which is the bit that is not guaranteed.

mfikes15:12:40

So, with the example above, if my.namespace uses stuff from cljs.react, the textual order in something is insufficient. (Instead my.namespace needs to have a :require for cljs.react in its own ns form.)

jaen15:12:54

Then I can think up of a simple example. Not sure if that is a kosher way to structure an application, but nonetheless. Imagine there's some namespace called dispatcher and you can register your function with it using (dispatcher/register path handler). The way dispatcher resolves the handlers to call when you do (dispatcher/call path & arguments) depends on the insertion order. There's no other way to guarantee this will work reliably unless :require is ordered.

jaen15:12:18

Otherwise the alternative is to not split up handlers across namespaces (like handlers.common, handlers.authorisation handlers.users-page and so on), but keep them in a single file, but that doesn't sound like a good solution to me.

mfikes15:12:58

Ahh, interesting. So this is a runtime execution order dependency.

jaen15:12:25

The problem goes away if you structure your application using components for example, but I don't think it's as common in the Clojurescript land as it is in Clojure.

jaen15:12:55

And again, this might not be a structure to enourage, but nonetheless a valid one.

triss15:12:51

hey all. I'm using reagent + core.async to make some slider widgets...

triss15:12:33

If I want react mouse events to work well with async channels I need to call .persist on the events before shoving them down them don't I?

triss15:12:52

Is there another approach?

triss15:12:29

Having mutable events in React kind of makes core.async interaction a touch awkward doesn't it?

jaen15:12:22

Why not extract what you need and shove that over the channel only?

puppybits16:12:51

Has anyone used Mori w/ CLJS? I use CLJS for my data layer w/ vanilla JS/React. I would love to have my CLJS export functions return a Mori wrapped EDN objects. I could do clj->js then mori.toClj. I couldn’t find anything better in the docs.

jaen16:12:11

I might be wrong, but aren't mori's datastructures just Clojurescript structures, so no translation is necessary?

puppybits16:12:04

it’s a javascript-like interface on top of cljs data structures.

puppybits16:12:48

i can’t call .get() on a pure EDN object that I return to Javascript land.

puppybits16:12:16

no i think maybe your right. It seems like all the functions to interact with EDN is calling mori.get instead of myEdnObject.get

jaen16:12:03

I'd imagine basing on what I understand mori is for mori.first(your_cljs_function_returning_a_collection()) to work

jaen16:12:16

But I might be wrong

triss16:12:45

thanks jaen. I guess that'll do it... in this instance it kind of feels like I'm splitting the slider logic between the callback and the async stuff.

jaen16:12:32

@triss: some of that is inevitable, if you have some logic on the other side of the channel, I guess.

puppybits16:12:24

@jaen now that I look at it closer I think you’re right. thanks.

mfikes16:12:25

[Random] A quick way to see if you’re in a bootstrapped REPL: Evaluate #{1 2 3} and see if it prints the same back (bootstrapped) or #{1 3 2} (not).

thheller16:12:47

@mfikes I doubt that is documented official behavior

thheller16:12:46

since nothing works if you just (require 'dep.z)

thheller16:12:49

might be worth to add a warning if a namespace tries to use a fully qualified name without a :require for it

mfikes16:12:32

@thheller: Please expand on what you are saying. I’m not understanding.

thheller16:12:01

your example repo, in both cases it assumes that (require 'top) is called first

thheller16:12:16

that makes it look like unordered works

thheller16:12:02

although it doesnt have requires for b -> a etc

thheller16:12:28

so if you do not (require 'top) first and just require (require 'dep.z)

thheller16:12:35

unordered does not compile

thheller16:12:51

well actually it compiles

mfikes16:12:59

Ahh… perhaps this helps clarify: In the unordered repo, I expect the call to evaluate dep.z/z to fail.

mfikes16:12:29

(If that’s causing the issue I’ll revise the readme.)

thheller16:12:47

the issue is that (require 'top) sort of makes it look like it should work

thheller16:12:53

while it shouldn't

mfikes16:12:11

In fact, I should say that (require ‘dep.top) will fail in the unordered repo.

thheller16:12:27

hmm it is hard to make it fail, but yes

mfikes16:12:40

Right? I think this is just poor wording on my part in the readme, unless there is something more subtle you are saying.

thheller16:12:56

no it appears as though the ordering matters

thheller16:12:11

since the topo sort cannot work when b doesn't declare the require on a

thheller16:12:15

c -> b, etc

thheller16:12:37

since they don't have any deps the compiler thinks it is fair game to sort them in any way it likes

thheller16:12:03

so even though the unordered stuff might work in clojure

thheller16:12:14

I doubt that this is official dependable behavior

thheller16:12:10

ie. if you just (require 'dep.z) in unordered it won't work

thheller16:12:16

while it will work in ordered

jaen16:12:19

But isn't that's what the issue is about (if I understand it right)? That is whether the topological sort should only take namespace requirements into consideration or the order the namespaces appear in in the require clause as well.

thheller16:12:53

I'm saying that the order should not matter .. ever ... period.

mfikes16:12:14

The unordered tree is an example of an incorrect setup. It is there to illustrate how things fail.

thheller16:12:15

if it matters it is due do undeclared dependencies

jaen16:12:40

Why? If loading namespaces can be sideffectful, reordering can cause a working program to stop working.

thheller16:12:50

no it cannot

mfikes16:12:42

The fundamental issue is that you cannot use the textual order in an ns form to control the order.

jaen16:12:46

Why? Would you then care to scroll up to my example and point out where my assumptions are wrong?

thheller16:12:48

only in case of undeclared dependencies

thheller16:12:02

(ns something
  (:require cljs.react my.namespace))

mfikes16:12:10

Right, @jaen you cannot use the textual order in :require to make that situation work.

thheller16:12:36

ah well if you care about insertion order

thheller16:12:42

you should make that explicit in the code

thheller16:12:45

and not work with global variables 😉

jaen16:12:48

This is a point, like I said I used it to illustrate what I understand the problem is, not said it's a kosher way to structure a Clojurescript application, but that's sort of a thing allowing side effects in top level forms lets you do nonetheless.

mfikes16:12:49

This is semantically the same as

(ns something
  (:require my.namespace cljs.react))

jaen16:12:06

If that's a bad thing to do, then there should probably be a warning for that at the very least.

jaen16:12:21

@mfikes: well yes, but I understood that the issue is about whether the textual order in the ns form should matter or not. Or did I misunderstand something?

thheller16:12:10

you are relying on the hash ordering of a set in this case

mfikes16:12:18

Just to be clear, the textual order in the ns form does not guarantee anything.

thheller16:12:18

so yes it is not something you should ever rely on

jaen16:12:14

@mfikes: in Clojure as well?

mfikes16:12:47

@jaen: In Clojure it is evidently not guaranteed either. But it does occur by accident of an implementation detail.

jaen16:12:32

So it's not meant to work, but just so it happens it does?

mfikes16:12:54

It could change in the future, and break code that relies on it.

mfikes16:12:18

(I think one thing that may have spawned this conversation is that there perhaps additional subtle issues surrounding this subject that come to play if you turn on the new parallel compilation feature. In other words, code that is skating on thin ice breaks when you turn on this feature.)

jaen16:12:40

It may be a failing on my part, but I've never read that ordering in the :require clause doesn't guarantee anything. Moreover it's a vector not a hash map (by which I mean the surface syntax), which implies that ordering is significant.

mfikes16:12:24

@jaen I’ll show you the line of code… just a sec.

thheller16:12:49

:requires are kept in a map

jaen17:12:42

Yeah, I've seen that earlier in a thread somewhere.

jaen17:12:56

But what I mean is - that is an implementation detail that's not evident from the outside.

mfikes17:12:15

Right. So, the ns docs say nothing on the subject. simple_smile

thheller17:12:36

given the dynamic nature of clojure and the REPL

thheller17:12:04

and the presence of (require 'something :reload)

thheller17:12:34

I think relying on ordering would only be harmful to your program

jaen17:12:32

Well, in Clojure I wouldn't, I use component which makes that irrelevent, since ordering is implicit from the system map shape.

mfikes17:12:37

A couple of other things that exacerbate things, IMHO, is that you can require a and then gain access to the things that a itself requires. And (for some of us at least), Cursive will resolve a symbol even though you haven’t properly :required it.

jaen17:12:54

But this approach is not as popular in the Clojurescript world

thheller17:12:33

well it should be, the same rules apply

jaen17:12:12

Sideffects at top-level.

mfikes17:12:21

Perhaps two solutions in ClojureScript are (1) Explicitly do the registering in code that registers things in the required order. (2) Make one of the namespaces artificially depend on the other, to force the order.

jaen17:12:53

And it seems it's a more popular style in Clojurescript than in Clojure.

thheller17:12:05

@jaen yeah that is bad, globals for everyone

thheller17:12:48

@mfikes I think we should emit a warning if a namespaces requires a fully qualified var without having a :require for it (or :use)

jaen17:12:11

I'm not saying it's good, but nonetheless it's popular, especially with libraries like Reagent making it simple to write that way.

jaen17:12:20

If the ordering of requires is not guaranteed

mfikes17:12:22

@thheller: Yeah, something like that would probably be very useful.

jaen17:12:39

Then shouldn't side-effecting in a top level form warn then?

jaen17:12:48

So people don't learn wrong habits?

thheller17:12:07

well side effects at the top level aren't all bad

mfikes17:12:15

Well, Clojure is imperative in that sense. defn makes a def, etc.

thheller17:12:21

but far from best practice

mfikes17:12:47

You can intern vars, register handlers, it is all side effects in a sense.

jaen17:12:13

Yeah, but then no ordering makes it implicitly non-deterministic.

jaen17:12:25

Across namespaces that is.

thheller17:12:32

how do you even handle reloads in that setup?

thheller17:12:55

ah I guess :logout and stuff are the names of things

mfikes17:12:05

The way I look at it, any namespace can declare a dependency on another. Thus you have a partial order.

jaen17:12:19

I guess, but that makes you have to do artificial requires to ensure that order.

jaen17:12:30

Not sure if that's ideal.

mfikes17:12:50

If fractalify.users.handlers expects other things to be registered prior to it, it can (artificially) require the namespace that registers those things. (But this seems less than ideal and perhaps an abuse of :require)

jaen17:12:06

Yeah, eaxctly.

jaen17:12:27

That's non-essential to what the file needs or does.

jaen17:12:40

Sort of an incidental complexity caused by how require works.

thheller17:12:15

> If fractalify.users.handlers expects other things to be registered prior to it

thheller17:12:36

you expect something, so declare it

mfikes17:12:45

Yeah, I think this is just a code smell associated with global initialization order.

jaen17:12:12

Now, I'm not saying requires should be changed to have the order of clauses in it be significant, but if that's bad then I think user should be made aware of that by the compiler if possible.

mfikes17:12:44

Put all of those top level forms into a side-effecting function, and then call that function from some other namespace at the right time during inti.

thheller17:12:51

agreed, a warning would probably be best

thheller17:12:49

but not sure how that would be possible since the compiler is not that smart 😉

thheller17:12:15

warnings for fully-qualified vars without require should be pretty straightforward though

thheller17:12:39

might just make the compiler slower though

jaen17:12:01

> you expect something, so declare it But I'd agree that's abuse of require, it's there for you to require code you need, not sequence sideffects in top level forms. The init function for namespace sounds sensible, but it's a cultural thing. C++ is a great language if you have the right culture, experience and discipline. Enforcing things is better, I think.

mfikes17:12:09

@thheller: Perhaps it is even legal for code in ns a to make use of transitive deps of a ns it explicitly requires. But this seems fragile.

thheller17:12:39

> If fractalify.users.handlers expects other things to be registered prior to it

jaen17:12:28

@mfikes: If I understand what you are saying then I'm pretty sure it works like that in Clojurescript. When I require a namespaces in the browser REPL, I can then use things it required with fully qualified symbols no problem.

thheller17:12:55

@mfikes not sure what you mean?

mfikes17:12:48

@thheller: yep, what @jaen said. Let’s say (ns a.core (:require b.core)) then the code in a.core can reliably use things that b.core requires. But, this seems fragile to rely on transitivity. I’m arguing it is better for a.core to actually :require the things it uses.

thheller17:12:24

well yes you can do that but not something you should ever rely on

thheller17:12:01

again .. if you want to use something :require it.

mfikes17:12:02

@thheller: I like your idea of having the compiler emit a warning in that case.

jaen17:12:02

I'm just wondering how feasible would it be for compiler to warn on any top-level function call that reaches outside the current namespace?

mfikes17:12:08

(ns a.core
  (:require b.core))

(c.core/foo 1)  ;; This should cause a warning to be emitted

jaen17:12:09

Since if that's not what people should be doing

jaen17:12:14

A warning would be prudent.

mfikes17:12:14

I guess the same arguments and concerns apply to Clojure.

jaen17:12:32

Yeah, though it's a bit different for Clojure

thheller17:12:36

I don't think anything should be done in that regard

thheller17:12:45

since some things are just global and must be global

thheller17:12:55

ie. schema.core/defn

jaen17:12:09

But that's a macro, not a function call.

dnolen17:12:10

@jaen that’s already done

thheller17:12:11

it emits a defn and something global

dnolen17:12:23

if you reach to a namespace the analyzer hasn’t seen - warning

jaen17:12:32

So it's entirely not the issue.

jaen17:12:16

@dnolen: maybe I'm not clear enough - I'm not talking about using undefined symbols, I'm talking about calling sideffecting functions from other namespaces at the top level.

jaen17:12:08

@mfikes: but Cljs being different I mean you can't eval in Clojurescript so you can guarantee that during compilation. Not so in Clojure.

jaen17:12:09

@thheller: I'm not saying there should be a warning about using symbols from other namespaces at the top level for any and all cases. Macros emitting code into current namespace are totally okay, since this does not depend on require ordering at all.

mfikes17:12:19

@jaen: Hah. I’ve been living in bootstrapped world too long simple_smile

jaen17:12:00

On the other hand if that macro emits a function that sideffects it should be a warning.

jaen17:12:10

But then again

jaen17:12:16

It may be impossible to implement for all I know

jaen17:12:39

@mfikes: right. It's a different world that side of eval ; d

jaen17:12:13

Hah, I noticed over at the dev channel, that I didn't make up the issue being reported at the very least. Just the fix part.

mfikes17:12:26

@jaen: You have been redeemed. Your memory is accurate. simple_smile

jaen17:12:50

Half-accurate, but that's still better than not at all ; d

jaen17:12:30

Don't want to barge in #C07UQ678E so I'll leave this here: The way I look at this the options are either to: a) have the ordering of require/use/etc. clauses in the ns macro be a part of the language semantics, which makes sense since loading a namespace is an imperative process of creating vars and calling functions at the top level, where inter-namespace ordering can be significant, b) have no ordering of require/use/etc. clauses in the ns macro be a part of the language semantics, which in turn should make doing cross-namespace sideffects either outright forbidden or at the very least - warn. Doing anything else would be inconsistent IMO. One behaviour would be declarative while the other - imperative, which would result in not-so-obvious behaviours when namespace require order gets well... reordered.

ul18:12:36

I know that explicit is better than implicit, but... Do anybody know robust way to pass some value inside lexical scope? Like binding, but working with lazy sequences?

mfikes18:12:33

@ul: FWIW, that reminds me of this thread where Brandon Bloom ends up creating bound-fn for ClojureScript. https://groups.google.com/forum/#!topic/clojure/6cmnkHmHBNw

ul18:12:13

very interesting thread, thank you!

richiardiandrea19:12:35

@mfikes: so the branch patch in the thread is not in ClojureScript yet I assume?

mfikes19:12:47

@richiardiandrea: Please define “branch patch"

mfikes19:12:02

Right, ClojureScript doesn’t have bound-fn, for example.

richiardiandrea19:12:34

ok thanks, just because the thread is so old I thought of asking 😄

mfikes19:12:19

@richiardiandrea: No problem. I should have said Bloom ended up creating a proposed bound-fn for ClojureScript. simple_smile

richiardiandrea19:12:37

I might actually add some tests on binding to replumb as it can be useful as reference...

jaen19:12:02

That doesn't answer your question, but why not cljs-time?

mfikes19:12:52

I was wondering about the cost of var indirection. For me, this takes about 6.1 seconds

(time (let [a (atom 0)] (doseq [x (range 10000000)] (swap! a inc))))
while pulling the fns into locals
(time (let [local-swap! swap! local-inc inc a (atom 0)] (doseq [x (range 10000000)] (local-swap! a local-inc))))
runs in 4.5 seconds. This is probably a bad micro-benchmark, being a tight loop. Wondering if others have ever felt the need to do anything like this.

gerrit20:12:02

@jaen in fact I used cljs-time but removed it to keep the example minimal

gerrit20:12:06

oh, haven't seen those

gerrit20:12:33

thanks, I'll try that

jaen20:12:25

BTW what are the sets in each case?

gerrit20:12:34

you mean the type of the sets?

mfikes20:12:45

@gerrit: Implement IHash

mfikes20:12:20

Even this is sufficient to make the test work: (extend-type js/goog.date.Date IHash (-hash [o] 1))

jaen20:12:35

I've meant what the sets look, ie. what items they have.

gerrit20:12:41

cljs-time.extend doesn't change the behavior. @mfikes: nice, thanks!

jaen20:12:44

@mfikes: w8, with a constant hash?

mfikes20:12:00

Without that, you get funny answers. (hash (js/goog.date.Date. 2015 11 3)) changes each time you do it.

jaen20:12:23

Ah, I guess it then falls back to equality and uses chaining?

gerrit20:12:34

@mfikes: any guess why it works with 9 items or less? is that just a coincidence?

mfikes20:12:49

@jaen: Yes. (= a b) implies (= (hash a) (hash b))

mfikes20:12:13

@gerrit: Good question. I don’t know. simple_smile

mfikes20:12:02

@jaen: If (= 1 (hash x)) for all x, then you’ve satisfied the contract simple_smile

jaen20:12:26

What I mean is, then why the set doesn't have just one item then.

mfikes20:12:34

@jaen: I didn’t want to work out a good hash code.

mfikes20:12:03

@jaen: Because if the hashes collide then the hash-map and hash-set algorithms typically fall back to a linked list based on =

mfikes20:12:30

@jaen: I don’t know how the HAMT actually does it. But colliding hashes is fine.

jaen20:12:05

Yeah, that's what I've meant by "falls back to equality and uses chaining".

mfikes20:12:06

You generally need to make sure you satisfy the implication

jaen20:12:28

It makes sense to have it work that way, just wanted to be sure.

jaen20:12:18

(though probably persistent data structures don't use linked list chaining, but still)

mfikes20:12:09

In @gerrit ’s original (not= (hash (Date. blah)) (hash (Date. blah)) given whatever funky thing was going on. (Perhaps it was giving the hash of the object address.)

gerrit20:12:39

(-hash [o] (hash (.getTime o))) this should probably suffice as proper hash implementation?

mfikes21:12:10

If the time is in milliseconds, that’s probably cool

gerrit21:12:17

I guess it makes sense to PR that to cljs-time simple_smile

mfikes21:12:30

If IEquiv could be expressed as (= (.getTime a) (.getTime b))

gerrit21:12:20

yeah kind of. this is what cljs-time.extend does:

(-equiv [o other]
    (and (instance? goog.date.Date other)
         (identical? (.getTime o) (.getTime other))
         (identical? (.getTimezoneOffset o) (.getTimezoneOffset other))))

gerrit21:12:32

so I'll add the timezone to the hash

jaen21:12:31

str it maybe?

jaen21:12:37

unless hash needs to be a number?

jaen21:12:51

Duh, of course it needs.

jaen21:12:53

But then you can get the hash of the resulting string, I suppose.

gerrit21:12:43

I guess doing it the java way should work. as timezoneoffset seems to be a number as well

jaen21:12:28

I suppose as long as all datetimes are in the same timeones you shouldn't have too much collisions.

gerrit21:12:39

for reference: I hope this does the trick simple_smile (-hash [o] (+ (.getTime o) (* 37 (.getTimezoneOffset o))))

mfikes21:12:27

@gerrit: whether the TZ is included in the hash could be driven by perf. (Either choice should function correctly.)

jaen21:12:21

Yeah, it's quite interesting how much the conflict resolution strategy affects the performance.

markstang21:12:02

I am running a core.js that was generated by ClojureScript as part of a system running on node and the "system" can't find "goog" goog.provide('pow.core'); ^ ReferenceError: goog is not defined at Object.<anonymous> (/home/mstang/Desktop/projects/codetest-1/out/server/pow/core.js:2:1) at Module._compile (module.js:456:26) at Object.Module._extensions..js (module.js:474:10) at Module.load (module.js:356:32)

markstang21:12:44

I tried to use "require" thinking that nodes require would load it, but no luck. Has anyone else run into this issue?

markstang22:12:02

What I tried was: var goog = require('../out/server/goog/base.js'); var code = require('../out/server/pow/core.js');

markstang22:12:53

Also, I was building with an older version of cljs, I switched to the latest and now I am getting :

markstang22:12:55

Compiling "out/server/pow.js" failed. Exception in thread "main" java.lang.AbstractMethodError: Method cljsbuild/compiler/SourcePaths.findsources(Ljava/lang/Object;)Ljava/lang/Object; is abstract, compiling:(/tmp/form-init6738966304942402426.clj:1:73)

mfikes22:12:10

@markstang: all I can say is Closure and CommonJS / Node are two different module systems, with two different require constructs.

markstang22:12:08

@mfikes Yeah, I read that somewhere someone had written a "require" for google to work within node

mfikes22:12:30

The QuickStart has a bit covering Node

thheller22:12:31

@markstang the second error most likely requires a newer version of lein-cljsbuild

thheller22:12:44

1.1.1 I believe

thheller22:12:41

> var goog = require('../out/server/goog/base.js');

thheller22:12:23

wont work since goog is a required global object, but it should be managed by the build and included in core.js

markstang22:12:47

ah, not seeing it in the core.js

markstang22:12:57

not sure what magic to use for it to be included

thheller22:12:15

did you set :target :nodejs in your build config?

markstang22:12:09

maybe I need the :require for node.js...

thheller22:12:24

sorry that is pretty much all I know about the cljsbuild world, not sure how things are done over there these days

thheller22:12:56

but one thing as well would be that the output of a node.js build

thheller22:12:12

is not really meant as something you can require in node

thheller22:12:17

more like a script you execute

markstang22:12:27

no but maybe in clojurescript

thheller22:12:50

since your example had

thheller22:12:51

>var code = require('../out/server/pow/core.js');

thheller22:12:15

more like node out/server/pow/core.js

thheller22:12:29

it might work then, I do not know

markstang22:12:39

yeah, which works fine, but I can specify the command-line

markstang22:12:26

I don't specify the command-line, I am "requiring" my module in another module

thheller22:12:57

you are not building a module, at least as far as I can tell cljsbuild does not support that

markstang22:12:44

(set! (.-exports js/module) #js {:helloWorld hello-world})

thheller22:12:57

yeah that is broken ... don't do that

markstang22:12:58

clojurescript creates the right output

markstang22:12:40

ok, well back to the drawing board, I am trying to replace an existing source file with a clojurescript generated one

thheller22:12:22

I have done some work on this stuff recently if you are interested

thheller22:12:40

basically a way to create UMD module compatible output

thheller22:12:50

looks somewhat like this (eg. a map for {exported-name fully-qualified-cljs-name})

thheller22:12:38

Universal Module Definition basically a way to combine the various module systems the js world has

thheller22:12:57

ie. what node likes

markstang22:12:11

I will take a look at it

thheller22:12:38

but the solution is far from ideal, still working on some rough edges

markstang22:12:16

Well if I take the generated javascript and rip out the "goog" and the namespaces, it runs and works...

thheller22:12:25

node is just messy in that regard 😞

thheller22:12:19

or our integration with node really, since we are happily abusing the global object

thheller22:12:22

would be another example of a build that generates a node compliant module

markstang22:12:13

I'll take a look at that one next