Fork me on GitHub
#clojurescript
<
2018-03-24
>
juhoteperi06:03:02

On application projects directories also affects which files are included in uberjar. Cljs files aren't necessary as it is already compiled into JS.

Busy escaping the comfort zone09:03:06

Hey, I'm trying to set up a remote nodejs repl following https://github.com/clojure/clojurescript/wiki/Remote-REPL but it fails with:TypeError: Cannot read property 'nameToPath' of undefined

Busy escaping the comfort zone09:03:40

file sync seems to be working fine but I don't see /tmp/cljs-repl-share/out

dnolen11:03:23

@john I don’t think it’s idiomatic to intermingle @juhoteperi point is right on

dnolen11:03:56

Clojurescript compiler doesn’t really intermingle that much, so not evidence that this is a idiomatic pattern

dnolen11:03:30

And I would probably put .cljc under clj directory

jcr11:03:59

Hey guys, could you comment on this suggestion: https://dev.clojure.org/jira/browse/CLJS-2376?focusedCommentId=48829#comment-48829 What do you think about metadata in ns form? Could it potentially break something?

mikerod12:03:56

I’ve always intermingled clj cljc and cljs. I don’t see the benefit of having separate directories. I just The the confusion of having to search multiple trees. Also sometimes I migrate a cljs to a cljc later (or the other way around) jumping directories with that sort of change just doesn’t make sense. If there is a compelling reason to not intermingle, it’d be great to here it. Perhaps I just haven’t seen it yet.

dnolen12:03:03

@juhoteperi just described a perfectly fine reason

dnolen12:03:11

you don’t want the deploy jar to include anything it doesn’t need

dnolen12:03:29

this is fairly standard practice - web assets end up somewhere else

dnolen12:03:17

anyways it’s a minor point - but to say intermingling is more or less idiomatic than not isn’t a supportable claim

4
jcr12:03:44

lein has an option to exclude specified files from the uberjar, hasn't it? I agree that there's no widely accepted convention, although I don't see any reason not to intermingle, similar to mikerod

mikerod12:03:26

Hmm I see. Thanks for the explanation.

juhoteperi13:03:41

@just_crashed Yes, there are other ways to filter uberjar contents, but in those cases you have to create additional logic yourself, as you have lost the additional information the separate paths provide.

juhoteperi13:03:10

I don't see reason to intermingle as just putting files in separate paths doesn't cost anything. Editor should allow jumping between files in any path and moving files in git is easy anyway. But yes, this is minor thing.

razum2um13:03:26

is there anyone here who came from typescript and finally chose cljs, can you tell a story why?

john14:03:22

If I'm working on a datomic/DB/SQL, pedestal/jetty, om/re-frame/react sort of stack, in a particular project, it's probably going to be most idiomatic to separate src/clj from src/cljs

john14:03:24

But that could just as easily be called src/frontend and src/backend

john14:03:09

I hadn't thought about the jarring scenario. That's an extra factor too

john14:03:41

If I'm able to write 90% of my app in cljc though, I doubt I'd go about making split directories just for the sake of having them.

john14:03:45

But 90% of the clj/cljs work out there is probably going to involve that frontend/backend architecture

john15:03:25

@dnolen if I was writing a cross platform lib or data structure, would you still recommend separating out clj/c from cljs by directory?

orestis15:03:25

@razum2um I am not 100% here or there yet, but I’ll write my thoughts on Typescript vs ClojureScript vs Reason/Bucklescript in a thread...

orestis15:03:09

I started doing proper JS just a bit after ES6 became a little bit more mainstream and Safari had 100% support. My hope was to be able to just write code and being able to reload my browser, at least during dev time. Also, the new ES6 syntax features and data structures like Map and Set made it a bit more sane.

orestis15:03:06

In the end though, I wasn’t comfortable enough creating abstractions in JS. Too many sharp edges and hoops to jump through slowed me down a lot. Also, rather than slowing done until ES6 was widely adopted, it seems everyone in the JS ecosystem wanted to add even more features, muddying things up a lot. It seems nowadays there’s not even a set standard to adhere to, and features are added continuously by committees.

orestis15:03:13

So I turned to Typescript as a saner target that: a) doesn’t get in my way, b) provides a stable platform to build against and c) helps me navigate the intricacies of JS by giving me a type system on top.

orestis15:03:01

After using it in anger for a few months and successfully creating my own little in-house library for a simple CMS app, I was quite satisfied regarding those targets. However, I realized that TS (at least at that point in time, not sure about what’s going on now) did not have any runtime or libraries. You even had to provide your own polyfills to target older browsers.

orestis15:03:55

Fast forward a few months, and I had a look again at it, and it seems that MS has adopted the “continuous change” mindset. Lots and lots and lots of changes happening over the course of months, hidden behind compiler flags, etc etc. That did not give me confidence to continue using it for new projects.

orestis16:03:40

So I then turned to evaluate other languages that compile to JS. Top contenders were ReasonML and CLJS.

orestis16:03:41

I really wanted to like ReasonML, but I chanced upon it just as the Reason team decided to tweak a whole lot of the syntax. Also, it seems again that there was no aim to provide a runtime/standard library. However, Bucklescript/Ocaml have the advantage of being around for some time and quite proven languages. Still, it is still very new and under active change so I didn’t want that.

orestis16:03:10

The main attraction to CLJS for me was that a) it was old, 7 years out now, b) was building on an even older language, c) it was based on a robust standard library and tooling, d) it came from a community that values backwards compatibility

orestis16:03:26

I have to say that I had evaluated Clojure a few years back and the syntax scared me away. For some reason this time round I stuck my teeth into it and I got over it, I even like it now :)

orestis16:03:00

Do you have a look at a talk called “ClojureScript for skeptics”. It did score a lot of points for me.

orestis16:03:52

I should write this down in a blog post :)

👍 8
johnj16:03:51

I don't know, Bucklescript is a pretty stable solid compiler, it produces readable JS and the reason it doesn't have a library like the closure library (although you can use lots of ocaml stuff that makes sense in the browser) is because it was designed to embrace the npm ecosystem from the start (unlike cljs which was reinventing its own npm world with stuff like cljjs), the interop with JS ecosystem from BS is way superior, also BS is the fastest compile to JS compiler.

👍 4
orestis16:03:19

You are definitely right on all of those points. I had the misfortune of happening across Reason first and that might have tinted my perspective at the time a bit.

orestis16:03:16

I definitely respect OCaml and Bucklescript from an engineering point of view.

orestis16:03:34

I can’t say the same for npm — I wonder what % of packages would be missing from there if JS had a better standard library, and if the drive to publish everything as a npm module wasn’t that strong in the JS community.

johnj16:03:37

I think cljs made the mistake of not embracing the node/npm tooling from the start, but new tools like shadow (I haven't use it) seem to be improving things for some

orestis16:03:53

I’m not sure there was much to embrace when CLJS was released though. But yes, there are efforts underway, and for compatible libraries you can even get full DCE which sounds quite compelling.

dnolen16:03:45

yes, there wasn’t anything to embrace in 2011

dnolen16:03:24

and I don’t really consider Node.js a high-value world of deps

orestis16:03:39

I am wondering how large is the Bucklescript/Reason community compared to CLJS. I certainly haven’t seen frameworks like om/reframe that aim to tackle harder problems than virtual dom. There’s some activity in Bucklescript-tea (elm architecture) but I haven’t tried it.

dnolen16:03:42

in truth we pursued it mostly because we wanted to adjust for where React was going

dnolen16:03:04

most anything else you can get from Closure

orestis16:03:59

Is React now DCE compliant?

johnj16:03:41

well maybe not exactly from the start, but by 2013 npm was pretty big

orestis16:03:54

IDK, there’s certainly useful libraries there — but also a ginormous amount of crap. Also, all the transitive dependencies that you get plus the node_modules explosion make it for a really shitty experience.

johnj16:03:27

sure, closure provides you with a base to build stuff but there are is so many cool JS stuff out there.

dnolen16:03:32

@U4R5K5M0A it wasn’t there yet

dnolen16:03:41

even in 2013, Bower will still to be contended with

dnolen16:03:49

an the JS build pipeline continues to be mostly a joke

dnolen16:03:03

I continue to fail to see why people want to adopt that stuff blindly

orestis16:03:14

I tried rollup some time ago, and it had most of the issues CLJS is having with the npm integration, because it tries to work through all the ways JS code is published on npm. ES6 modules are sane, but still to this day it’s not widely used.

dnolen16:03:17

:npm-deps exists for precision dependency choices IMO

dnolen16:03:04

exactly rollup is fighting the same problems

dnolen16:03:14

eventually people will realize Closure figured it out 9 years ago

orestis16:03:45

I had to basically “extern” things like jquery.

dnolen16:03:12

anyways we intend to play the long game, and I firmly believe our long game is superior

orestis16:03:33

And on the subject of Typescript, not only you have to figure out how to bring in dependencies, but you also have to hunt down or write your own typespecs or find an outdated version online that mostly works, otherwise your program doesn’t even compile.

jcr16:03:57

@orestis mind if I repost it to discord? :) https://notehub.org/8hngn

👍 4
orestis16:03:32

@just_crashed no problem :) feel free to pick some of the rest though — the bit about having to write your own .d.ts files is a huge pain, on par or even worse than figuring out closure externs.

orestis16:03:18

When I finally sit down to use CLJS in anger, I will have a more rounded opinion about it. So far I’m just thinking about it :)

dnolen16:03:37

Another thing is that comparing ClojureScript to Elm / BuckleScript is really half-baked

dnolen16:03:47

ClojureScript is Clojure

dnolen16:03:26

when Elm / BuckleScript can do what Clojure can do then maybe you do a real comparision

dnolen16:03:34

the only real contender here is Scala.js

orestis16:03:13

In a sense, Bucklescript is OCaml though, right?

dnolen16:03:57

except people aren’t using OCaml + BuckleScript together widely

dnolen16:03:18

because OCaml as a backend technology is not really taken seriously outside a miniscule number of companies

orestis16:03:47

Again, my biggest gripe with Elm/Bucklescript is the lack of standard lib for the web. Rarely are the problems of web dev so “pure” as to be solved by just a nice type system.

dnolen16:03:39

slightly cases here

dnolen16:03:47

Elm legitimately has to reinvent the world

dnolen16:03:08

BuckleScript thinks it’s OK to just reuse Node.js world whole-sale

dnolen16:03:18

our stance is that neither of these options are great

dnolen16:03:10

and why not write in a language that transports cleanly to a reasonably successful multithreaded backend language

orestis16:03:20

I know that BS can just drop down to JS code, even embeddable in the same source file, but I’ve no idea how this plays out regarding the type system.

orestis16:03:46

I take it you wouldn’t advocate for using the Node.js runtime in some cases?

dnolen16:03:14

If you’re targeting Node.js directly there are already zero problems today

dnolen16:03:25

if you want to leverage NPM to get client stuff - then there are challenges

dnolen16:03:37

but these challenges are shared by sensible build pipelines like Rollup

dnolen16:03:51

and we’re light years ahead because Closure is light years ahead

orestis16:03:23

I’m trying to think of escape hatches for a company that is invested in Node right now, but have created a ball of mud. I’m thinking of slowly introducing CLJS into the system, perhaps at crucial points. I’d have to train 2-3 developers in order to get full buy-in, so I’m thinking hard about how best to sell this whole approach.

orestis16:03:44

To be 100% honest, I’d have to train myself first :)

orestis16:03:30

Client is much much harder as you say, because I can’t even think how to slowly introduce CLJS in there. Doing a major rewrite of the client is much much costlier.

dnolen16:03:45

well we’re not going anywhere and 1.10.X release will be a good time to tell people to give CLJS a try again

orestis16:03:48

Yeah, the new QuickStart guide is a huge improvement — thanks for that!

johnj17:03:24

@orestis re: your TS comment, in cljs you also need typespecs for external none closure lbs

dnolen17:03:44

you don’t need typespecs

johnj17:03:52

errm externs

dnolen17:03:52

externs inference covers this problem

johnj17:03:09

externs inference is still alpha tech no?

dnolen17:03:20

if alpha tech is 2+ years old OK

dnolen17:03:37

people use it - it works

johnj17:03:28

Ok, I may be wrong, I just hear about various edge cases people run into

dnolen17:03:47

bugs can be fixed

dnolen17:03:51

but lots of people use it w/o issue

orestis17:03:29

I thought that even worst cases, writing your own externs is simpler than writing a typespec, since externs just deal with names while externs deal also with return types and arguments? I could be wrong.

dnolen17:03:49

@orestis your analysis is correct way easier

johnj17:03:54

that's why I mentioned is alpha tech, maybe that page needs a revision?

dnolen17:03:00

this is why externs inference is even possible

dnolen17:03:26

PR welcome, just submit your CA

👍 4
orestis17:03:25

Meaning we can just remove the “alpha” from that page? ;)

dnolen17:03:39

we have no intention of changing the high level at this point

dnolen17:03:43

it’s sound

dnolen17:03:50

only making inference more robust

orestis17:03:11

I’ve already submitted a CA agreement for Clojure

orestis17:03:46

Awesome 🙂

justinlee16:03:11

@razum2um I went through a similar path as @orestis except flow type then reason the cljs. My basic issue with flow is that it added a lot of work but still wasn’t complete or reliable enough to be worth it. Hard to know if something was actually typed. Reason is still basically an internal tool that is available for the public to play with. I’m looking for something that has power in rapid prototyping and is deployable. cljs so far fits that bill now that I can reliably use the npm ecosystem

dnolen16:03:36

@john no issues with cljc in clj dir

orestis16:03:22

Breaking this out of that huge thread — does anyone have experience/ideas about how to introduce CLJS gradually into an existing system without having to do a big rewrite? Browser or Node.js perspectives are welcome.

dnolen16:03:23

@orestis again Google Closure is the answer

dnolen16:03:27

but it’s WIP

dnolen16:03:46

but as far as we can tell Google itself wants to leverage node_modules

dnolen16:03:29

the whole point of our deeper integration with Closure’s support for node_modules deps is that you could just replace your JS pipeline

dnolen16:03:43

that’s the long term goal

orestis16:03:44

Ah, I was more asking about systemic approaches, like e.g. create a small self-contained CLJS library that exposes somehow a JS API... (first thing that comes to mind). There’s a technical perspective which I think CLJS easily wins, and there’s a social perspective because it’s an “alien” technology. My hope is that as people experience it up close and see it working, they’ll be more amenable to using it in other parts of the system.

dnolen16:03:11

you cannot incrementally adopt CLJS because you cannot incrementally adopt Closure

dnolen16:03:19

whole program optimization is an all or nothing thing

orestis17:03:04

Surely though you can export a CLJS library as an opaque .js dump with some public API? I’ve used this approach with Typescript with good results.

jcr17:03:09

@orestis if you have "world in an atom"-type architecture, maybe have a look at datascript, it has a js api

dnolen17:03:23

@orestis yes but it’s uninteresting outside of Node.js only

jcr17:03:31

also dnolen's mori maybe?

dnolen17:03:33

every JS mapping you make will dupe CLJS runtime

dnolen17:03:08

but this just isn’t real problem

dnolen17:03:12

Rollup is the wakeup call

orestis17:03:24

@dnolen Can you explain a bit “every JS mapping you make will dupe CLJS runtime” ?

dnolen17:03:49

in order to give JS users something you need to compile to JS

dnolen17:03:59

which means you dump the standard lib into your lib

dnolen17:03:14

but every CLJS exposure lib must do this

orestis17:03:40

Ah, you mean that if say I export a “form validation” CLJS library and then a “data transformation” CLJS library, they will duplicate parts of the CLJS runtime because they wouldn’t be DCE’d together?

dnolen17:03:18

that’s exactly right

dnolen17:03:24

whole program optimization is all or nothing

dnolen17:03:31

separate compilation isn’t a thing

orestis17:03:29

Gotcha — but still, you can plant a seed and keep adding functionality to that seed. It’s no worse than adding an npm dependency of similar scope.

dnolen17:03:12

but you can’t share anything across separate compilation artifacts

dnolen17:03:17

so it’s impractical in the general case

dnolen17:03:27

(i.e. browser)

orestis17:03:55

Gotcha. Perhaps numbers will show how many X kb of npm dependencies are removed vs Y kb of CLJS/Closure dependencies gained.

dnolen17:03:56

gets downloaded 1.2 million times a month

dnolen17:03:14

you only need to convince a fraction of these people we’ve taken the concept to a higher level

dnolen17:03:57

because you don’t need to make your lib work

dnolen17:03:20

many JS libs are boringly written

dnolen17:03:28

and Closure will destroy boringly written code

orestis17:03:03

So your argument is, instead of starting by writing CLJS code, start by replacing all your build pipeline with CLJS?

dnolen17:03:11

absolutely

dnolen17:03:36

the groundwork is already laid

orestis17:03:39

Wow, really? I’d never thought of that. So take an existing JS codebase, keep all the JS in and try to subsume it into a CLJS build pipeline?

dnolen17:03:45

all we need is more people to contribute to make it better

dnolen17:03:53

you can either wait for the current set of contributors to fix your problems

dnolen17:03:10

or you can fix your problems now and let that future arrive quickly

orestis17:03:51

Is there an example somewhere of a project having side-by-side JS and CLJS? This really piques my interest. Getting CLJS in even as a compiler tool would be fantastic, since most projects will see an immediate tangible benefit of reduced bundle size for free.

dnolen17:03:01

@orestis it already works 🙂

dnolen17:03:07

we get bug reports about this stuff right now

dnolen17:03:37

the simplest case is greenfield ES6/Common.js code

dnolen17:03:47

if you’re doing that there’s nothing to do - we support that

dnolen17:03:55

the harder case is random NPM libs - because sometimes people write unnecessarily dynamic stuff - but in many cases those are boring PRs

orestis17:03:36

Sorry, I mean, not pulling in code from npm, but your own “legacy” JS code.

dnolen17:03:55

for your own stuff it might just work yes

dnolen17:03:05

but it really depends on how fancy you got

dnolen17:03:17

people do unreasonably wacky stuff with their build pipelines

dnolen17:03:34

that’s not really in scope for our goals

dnolen17:03:33

stuff like this is why shadow-cljs is reasonable answer

dnolen17:03:43

but unlikely path for ClojureScript itself to pursue

orestis17:03:45

Of course, yes. I see that this team relies on requirejs. I’ll have to see how closure plays with that.

dnolen17:03:21

anyways if you want to DCE the world - the ClojureScript/Closure way is the approach you should contribute to

dnolen17:03:21

and given that you have the Google behemoth behind it - I know where I’m placing my own bets

thheller17:03:23

speaking of ... I took a create-react-app demo app and compiled it with shadow-cljs with basically zero changes. https://github.com/thheller/react-redux-realworld-example-app/tree/this-is-madness

thheller17:03:45

could start using CLJS inside that project seamlessly

dnolen17:03:01

create-react-app is monstrosity, or was

justinlee20:03:16

@dnolen It’s true that downloads a lot of stuff, but the developer experience is not to be underestimated and the gzipped build release is 35kb. I use cra all the time to just do a quick experiment with some react thing. It is so incredibly useful.

dnolen20:03:22

Right because trying to figure out a basic React app is unreasonable now

dnolen20:03:33

So I dunno - not something to be excited about IMO

dnolen17:03:12

it makes ClojureScript looks like a light salad

👻 4
orestis17:03:33

For me it’s not Google per-se, but the history of Google Closure and the proven for year code. Lots of behemoths have produced shiny things that are forgotten now.

dnolen17:03:11

last time I tried create-react-app it took 5 minutes on a 4-core machine and it generated 120mb of JavaScript

orestis17:03:18

Hah, I’m building an Electron app and I can’t put it in Dropbox unzipped because of the million tiny files in node_modules 🙂

orestis17:03:33

(This won’t be distributed to people, so I’m fine doing that)

orestis17:03:47

@thheller The need for Babel there is to convert the JSX into JS?

thheller17:03:53

exactly. I didn't integrate that yet but it could be automated as well

dnolen17:03:52

@orestis Closure isn’t very shiny and to be honest - I don’t think anyone uses it as much as we do

dnolen17:03:04

my point is rather that it’s like JVM - it’s not going anywhere

dnolen17:03:09

and it’s only going to get more robust

orestis17:03:41

Well @dnolen and @thheller thank you both for your work and energy you are pouring into this, each from their own points. I hope that I will be able to contribute back one day, even by spreading the word.

orestis17:03:01

@dnolen Funnily enough, I am using OpenLayers, which used to be a Closure-based library, but since have switched to ES6 modules. Not sure what the rationale behind it was, but I guess the non-shinyness of Closure played a part.

dnolen17:03:24

Closure can consume ES6 modules

dnolen17:03:40

so probably no difference from Closure perspective

thheller17:03:32

ES6 is basically a modern way of writing ClosureJS. similar rules regarding static imports and such

thheller17:03:00

so it makes more sense to write ES6 these days and get the same benefits either way

dnolen17:03:08

@orestis one problem here is that if you’re not in the ClojureScript community people don’t understand what Closure is doing

dnolen17:03:19

we’re the only ones following along

orestis17:03:33

Hm, I’m curious though — they had a huge codebase full of goog.* stuff and now it’s completely gone.

dnolen17:03:45

it doesn’t matter

dnolen17:03:50

ES6 is just Closure stuff

dnolen17:03:31

by switching to ES6 they’re making it possible for others to consume, but nothing has really changed from their perspective

orestis17:03:51

Oh, sure, it’s just a weird move to make all this effort. Probably yes, it’s easier to just say “use rollup to get tree-shaking”.

dnolen17:03:13

it’s about making it possible for non-Closure build stuff to consume

orestis17:03:53

Well, I have to go. Thanks for the conversation @dnolen — I’ll try to write a blog post exploring this avenue soon.

orestis17:03:13

@dnolen Do you mind if I quote you in a future blog post? I like the “long game” take. Of course I can run it by you before publishing.

dnolen17:03:11

it’s just true, we’ve stuck by our principles over the last seven years to the varied complaints of the JS world who haven’t taken the time to understand the big picture

dnolen17:03:32

in the end I believe such complaints don’t matter - and surveys confirm - JS users are now 2nd behind Java

dnolen17:03:39

even though we refuse to adopt their ways

dnolen18:03:17

this isn’t going to change

dnolen18:03:33

from right after the release of ClojureScript is a good reminder it’s important to give people what they actually need - and ignore what they believe they want

jcr18:03:09

ohh, I remember that thread

jcr18:03:47

interesting to review it now, 7 years later

mfikes19:03:10

To help ensure easier upgrades to future versions of Closure, the ClojureScript compiler test suite is now automatically executed daily using the latest Closure Compiler and Closure Library. (See http://github.com/cljs-oss/canary)

justinlee20:03:16

@dnolen It’s true that downloads a lot of stuff, but the developer experience is not to be underestimated and the gzipped build release is 35kb. I use cra all the time to just do a quick experiment with some react thing. It is so incredibly useful.

jrbrodie7721:03:23

Quick namespacing question. If I create a namespace foo.core, and refer funcs from other namespaces with (:require [bar.core :refer baz]) Should I be able to access baz at the repl with (foo.core/baz) ? Not working in my current repl setup.

mfikes21:03:02

@jrbrodie77 At the REPL you need to do (require '[bar.core :refer [baz]])

mfikes21:03:00

Oh, I see what you are saying. No. Referring doesn't put the var in the namespace you are in.

mfikes21:03:20

You could do (bar.core/baz) or just (baz)

mfikes21:03:25

Also note that the "argument" to :refer is a collection of symbols to be referred.

sarna21:03:39

hey guys, which framework would you recommend for making a simple website? I've searched for a bit, Luminus and fulcro look really good

john21:03:35

I've been wanting to check out qlkit for a next web frontend project

john21:03:33

And precept

john21:03:25

Qlkit may be the simpler of the two though

john22:03:10

Definitely exercise luminus and fulcro too

john22:03:43

I guess they're frameworks in a different sense

john22:03:58

I'm not as familiar with fulcro

sarna22:03:21

I think I'll try out Luminus, as it targets beginners

manutter5122:03:08

You might want to check out re-frame too, as an alternative to fulcro

manutter5122:03:50

they’re both good frameworks (if that’s the right term), just different approaches.

sarna22:03:51

thanks 👍

orestis22:03:15

Also see yada. At least for the web server part, seems to have a lot of batteries included.