This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-16
Channels
- # atlanta-clojurians (8)
- # beginners (103)
- # boot (22)
- # boot-dev (1)
- # cider (36)
- # cljs-dev (55)
- # cljsrn (3)
- # clojars (25)
- # clojure (104)
- # clojure-brasil (1)
- # clojure-dusseldorf (2)
- # clojure-italy (8)
- # clojure-norway (9)
- # clojure-russia (15)
- # clojure-spec (6)
- # clojure-uk (26)
- # clojurescript (246)
- # cursive (26)
- # data-science (1)
- # datomic (22)
- # dirac (11)
- # editors (1)
- # emacs (8)
- # fulcro (50)
- # graphql (11)
- # hoplon (1)
- # jobs-discuss (27)
- # leiningen (44)
- # luminus (33)
- # lumo (2)
- # mount (1)
- # off-topic (8)
- # onyx (5)
- # parinfer (4)
- # reagent (94)
- # ring-swagger (14)
- # shadow-cljs (37)
- # spacemacs (10)
- # specter (3)
- # tools-deps (4)
- # unrepl (14)
- # yada (5)
Hey All, coming back to ClojureScript. What is the best way to get started now? Looking for good book/videos
When trying to use cljs.loader
, the compiler knows the namespace exists, but then it starts trying to look for it in my main.out
directory. Any ideas?
Compiling ClojureScript...
• main.js
java.lang.Thread.run Thread.java: 748
java.util.concurrent.ThreadPoolExecutor$Worker.run ThreadPoolExecutor.java: 624
java.util.concurrent.ThreadPoolExecutor.runWorker ThreadPoolExecutor.java: 1149
java.util.concurrent.FutureTask.run FutureTask.java: 266
...
clojure.core/binding-conveyor-fn/fn core.clj: 2022
adzerk.boot-cljs/compile-1/fn boot_cljs.clj: 160
adzerk.boot-cljs/compile boot_cljs.clj: 72
boot.pod/call-in* pod.clj: 413
...
org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke ClojureRuntimeShimImpl.java: 102
org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke ClojureRuntimeShimImpl.java: 109
...
boot.pod/call-in* pod.clj: 410
boot.pod/eval-fn-call pod.clj: 359
clojure.core/apply core.clj: 657
...
adzerk.boot-cljs.impl/compile-cljs impl.clj: 154
cljs.build.api/build api.clj: 205
cljs.closure/build closure.clj: 2775
cljs.closure/compile-sources closure.clj: 979
clojure.core/doall core.clj: 3140
clojure.core/dorun core.clj: 3134
clojure.core/next core.clj: 64
...
cljs.closure/compile-sources/iter/fn closure.clj: 983
cljs.closure/fn/G closure.clj: 511
cljs.closure/fn closure.clj: 648
cljs.closure/compile-from-jar closure.clj: 624
cljs.closure/compile-file closure.clj: 558
cljs.compiler/compile-file compiler.cljc: 1523
cljs.compiler/compile-file/fn compiler.cljc: 1563
java.io.FileNotFoundException: The file /data/prs/boot/cache/tmp/data/prs/dev/amazon/2x0/-tgmalg/main.out/cljs/loader.cljs does not exist.
clojure.lang.ExceptionInfo: The file /data/prs/boot/cache/tmp/data/prs/dev/amazon/2x0/-tgmalg/main.out/cljs/loader.cljs does not exist.
from: :boot-cljs
clojure.lang.ExceptionInfo: The file /data/prs/boot/cache/tmp/data/prs/dev/amazon/2x0/-tgmalg/main.out/cljs/loader.cljs does not exist.
line: 287
Hmm, it seems like it was the clojurescript version I was on (`1.10.126`). I'm back on 1.9.946
now, and that isn't the problem, though I'm running into a possible google closure bug now?
Uncaught TypeError: Cannot read property 'EvaluateCodeEvent' of undefined
at goog.module.ModuleLoader.evaluateCode_ (:3000/main.out/goog/module/moduleloader.js:228)
at goog.module.ModuleLoader.handleSuccess_ (:3000/main.out/goog/module/moduleloader.js:256)
at goog.net.BulkLoader.goog.events.EventTarget.fireListeners (eventtarget.js:284)
at Function.goog.events.EventTarget.dispatchEventInternal_ (eventtarget.js:381)
at goog.net.BulkLoader.goog.events.EventTarget.dispatchEvent (eventtarget.js:196)
at goog.net.BulkLoader.finishLoad_ (:3000/main.out/goog/net/bulkloader.js:168)
at goog.net.BulkLoader.handleSuccess_ (:3000/main.out/goog/net/bulkloader.js:138)
at goog.net.BulkLoader.handleEvent_ (:3000/main.out/goog/net/bulkloader.js:118)
at goog.net.XhrIo.goog.events.EventTarget.fireListeners (eventtarget.js:284)
at Function.goog.events.EventTarget.dispatchEventInternal_ (eventtarget.js:381)
I need a way to turn Hiccup into HTML Dom nodes. Is reagent the way to go, or is there a separate library?
reagent will do it just fine
@qqq you can also use the html function, and use Google closure turning a string into a Dom element. No need to use reagent just for that I think.
I did it like this, using functions from goog.dom
(defn node-from-data
[data]
(gdom/safeHtmlToNode (legacy/safeHtmlFromString (html data))))
(defn set-html
([data] (set-html data nil))
([data parent-id] (set-html data parent-id true))
([data parent-id remove-childs] (set-html data parent-id remove-childs nil))
([data parent-id remove-childs place-at]
(let [new-node (node-from-data data)
node-id (.-id new-node)
current-node (if (nil? node-id) nil (ensure-element node-id))]
(if current-node
(gdom/replaceNode new-node current-node)
(if-let [parent (ensure-element parent-id)]
(do
(if remove-childs (gdom/removeChildren parent))
(if place-at
(gdom/insertChildAt parent new-node place-at)
(gdom/append parent new-node)))
(log (str "could not place html: " data " on parent: " parent-id)))))))
first implementation of cljs (411 lines), and Rich's org-mode document rambling about motivations, state of the project, and its future https://github.com/clojure/clojurescript/tree/515900f9762102987bda7d53b919dafc0b6c0580
all the original devnotes are still in the repo https://github.com/clojure/clojurescript/tree/master/devnotes
Anyone have a snippet in cljs for detecting ios version?
@danielstockton Is your code running in Safari on iOS, or is it in a React Native app?
Safari @mfikes. I've loosely translated from JavaScript in the end:
(def ios-version
(if (.test #"iP(hone|od|ad)" js/navigator.platform)
(let [[_ ma mi pa] (.match js/navigator.appVersion #"OS (\d+)_(\d+)_?(\d+)?")]
[(js/parseInt ma) (js/parseInt mi) (js/parseInt (or pa 0))])))
I was reading through the cljs.analyzer
ns some recently and I noticed there are 2 similar parse
mutlimethod implementations to parse an ns
form, one for ns
and one for ns*
.
* https://github.com/clojure/clojurescript/blob/v1.10/src/main/clojure/cljs/analyzer.cljc#L2564
* https://github.com/clojure/clojurescript/blob/v1.10/src/main/clojure/cljs/analyzer.cljc#L2688
This implementation is rather lengthy and I was surprised to see it duplicated (or close?). Is one still around for historic reasons or are they both used and both have a reason to be maintained separately?
@mikerod If I understand correctly, the ns*
variant was added to cater to the slightly different needs of top level (require ...)
being in a ClojureScript file.
@mfikes interesting, I haven’t looked at them close enough to see the difference I guess. I was getting a bit confused doing a search earlier because I kept searching in the 2 different impl’s and the code all looked the same, but line numbers were diff (of course). hah
Hi guys; I’m on a mission to convince some engineers to consider clojurescript as their front-end mainstay for complex apps. I’ve been using it for >2 years and have most certainly sipped the coolaid. I’m having a hard time looking back at the Triassic period and making reasonable, non-arrogant-sounding arguments against other solutions. Has anyone successfully convinced an org to consider the cljs ecosystem? If so, how? Could you link to any discussions, blogs, presentations, etc. that proved helpful? I’ve done about a week of digging and have found a few good pieces that really help prove my point, but the more the merrier.
JS/ES6/ES20** and some framework like meteor/angular/ember/vue feels so archaic. If you move up to a react/mithril approach, you get slightly better with something like flux/redux, except now you also want an immutable js implementation, which in my own head is basically writing in a new language that kind of looks like js. perhaps the most valid counterpoint is something like typescript, but even here you’re only introducing types… which (without getting into a huge type debate) isn’t really solving the real problem in client-side js (immutability/state management).
@lwhorton yeah, clojurescript is like immutablejs with lodash and much more but in a more consistent and idiomatic package
i’ve considered re-implementing the excellent re-frame library in js, which is a very well thought out flavor of redux-- minus the boilerplate, explosion of nouns, performance problems, and constant churn. but that comes with a whole lot of baggage as well… like the fact that you still need immutability in a language that doesn’t support immutability.
@devicesfor good point. at one point I was looking at modi, which is an exposed js API to cljs’s immutable structures… it more or less exactly matches the cljs api wrt conj
assoc
merge
map/filter/reduce
etc. But if you’re going so far as to commit 100% to an api that is non native JS, why not just use a proper transpiled language?
My main arguments would be: 1) Google Closure - code splitting and dead code elimination are still ahead of webpack (don't know about typescript) 2) I get a lot done with just the core language (rich functional primitives, immutable data structures, core.async...). I'd have to pull in a load of dependencies in js land.
it seems silly in the end to say: lets use babel, webpack, some es6 transpilation, es2017 future-feature transpilation, plugins for live reloading, tree-shaking, n-number of necessary libraries (promises, async/await, collection mutators), an immutability library, maybe a reactive programming plug like rxjs/cyclejs, and a cumbersome/heavy rendering framework, some boilerplate-ridden state management framework, etc. all of that just to get to “the state of usable javascript”
where as @danielstockton mentions; lein, fig, google closure, an http client library, maybe re-frame, and everything else is native to the language.
Exactly. lein new figwheel myproject
and you're done with live reloading
^ this is the problem I’m bumping into over and over when trying to argue against the latest and greatest in the JS world: none of it makes any sense compared to cljs (at least in my head).
I wonder- does anyone have a real-world example where the cljs runtime is meaningfully harmful to performance?
in my experience, when you’re in the browser the only place performance matters is touching the dom while rendering… everything else is an order of magnitude faster
I think the code size argument only works for non-complex, tiny apps. Code size is likely smaller for complex apps, where you can take advantage of dead code elimination and minimal dependencies.
I also consider om/fulcro/qlkit to be state of the art frameworks for complex apps. I wouldn't know how to easily recreate that in js. Graphql/relay isn't really it.
I agree with @danielstockton wrt code size: jquery alone is 29k gzipped, and a minimal cljs app is 23k.. but once you start adding libraries cljs scales much better than linearly, while a js impl scales at-least linearly.
for example, immutable js is 16k… so just to have a bare-bones usable environment with native JS + immutable, you’re only 7k more than the fully feature cljs language
that being said, you can completely avoid the issue of externs or cljsjs by using this macro library… (looking for it on gh)
If you want to convince a javascript team to use clojurescript, you really should set up a shadow-cljs project and forget about cljsjs and externs and all that.
i only cursorily looked into shadow-cljs, given my preference to boot/lein. do you have experience with it?
It’s what I use. I don’t like lein because it is too magic and when something goes wrong it is hard to fix. shadow-cljs is more explicit. But if you need to use a lein plugin--and you probably will--shadow-cljs plays nice with lein too. The biggest thing for me is that shadow-cljs lets you resolve npm modules exactly like you would if you were writing javascript, including modular libraries like material-ui that allow you to include parts of the library independently. It also has a bunch of fixes to externs inference and just seems to work most of the time. https://shadow-cljs.github.io/docs/UsersGuide.html#js-deps
I’ve seen reports of teams switching to shadow and seeing significantly smaller code size, though it wasn’t clear why.
or questions for that matter. @U05224H0W can probably do a more comprehensive job of explaining all the optimizations he’s put in and he’s very interested and responsive in understanding how and why people use it. my biggest point is that shadow feels much more sane and much lower friction for the javascript->clojurescript transition
When I first started, I used boot. I stopped because people were basically like, “use figwheel” and it was easier to get going with lein. Boot is a little confusing because it’s not only a replacement for lein, but it is also a replacement for certain lein plugins. I didn’t really give it a fair shot. I highly suspect that if you have complex builds and need to do a bunch of custom stuff, boot is more robust and easier to understand.
they wrote an immutable abstraction layer on top of a mutable file system, which in practice is great for a single self contained jvm… but in reality there is a very high cognitive overhead. while you are allowed to “write your build system as a program, not a config file”, doing so is a struggle
if i haven’t touched the build process for a couple weeks, then need to go make a change, it takes me a good while to jump back into how the whole immutable system works
from a client-side perspective, the whole ecosystem is what’s wrong with old build systems. transpile *-> javascript, transpile style->css, template->html, assets->optimized
externs is going to scare the crap out of javascript people. “I mean have to mess with this janky poorly documented header file to import a js library?”
I wonder why no one has created something to convert typescript externs to for clojurescript, they have a big active community
Is anyone using Fulcro at all? The documentation is one of the best I have ever seen, but I don't know much more than that
I looked at fulcro from a distance a little while ago. the problem for me is that I don’t want a full-stack front client and server solution
i think it’s much more reasonable to have a consistent cljs client from project to project, but server side requirements change too frequently for me to buy into a whole ecosystem like that.
I can see that, I wasn't aware it was full stack
yea.. for example if I wanted to write a fault tolerant distributed system in elixir… i’m no longer in the safe-confines of fulcro but have to come up with two new systems to use
what would you use for the frontend?
by far the most well-thought out front end “framework”: extremely performant, declarative via data, extensible, middleware layer, single source of truth, easily coordinate complex workflows
I couldn't find any good walkthrough tutorials for reframe
honestly the best resource is the README, and if you use github’s history I think the original readme’s were even better (but more opinionated and “sassy”, so they changed them)
but eric normand has a whole series on learning it: https://purelyfunctional.tv/guide/re-frame-building-blocks/ (paid and unpaid stuff in there)
Great, thanks alot
like a way to get leverage all those ts externs, that way cljs would get all that work for free
I've created quite a few cljsjs packages, and i found it pretty easy. That being said, there are only a handful of libs i use regularly (charts, google maps). I find it doesn't take too long to write my own libraries for other things (e.g. datepickers) in cljs, and I end up with something better than combining 100 badly written js libraries and trying to customize them to my needs.
having worked on a 2+ year project in cljs with quite a few cljsjs dependencies… it just stinks all around
kotlin has these https://github.com/ntrrgc/ts-generator
Just use shadow-cljs, you can use any NPM dep with it, no externs necessary. And thheller is super responsive
^ exactly that @danielstockton… give me a day to rewrite some half-working js library in cljs, and in the end it will save time and integration pain
There’s just no reason to use them. With shadow-cljs you just install stuff with npm and maintain a package.json. Externs inference works well or you can use cljs-oops.
I feel like shadow-cljs doesn’t get enough credit so I’m happy when other people recommend it.
FWIW, I moved to a new position and talked about CLJS, Dead Code Elimination, sane tooling etc. to my CTO — but before that, I shared a few Rich’s talks, and he caught the bug from those — he justs wants a system that is easy to reason about, and the current Node codebase is a huge ball of mud. So if we end up picking up CLJS, it is going to be for the systemic effects it has, rather than the syntax/libraries etc.
^ which talks did you show her? most definitely “simple made easy”, but was there anything else in particular that got you buy-in?
He also finds Lisp beautiful, which is not a common think — we will have to do a lot of pursuading within the team about this 🙂
It’s hard to describe how messy can a “simple” web app written in Node/Express/Mongo can be.
i’m in a similar situation-- not a product company but a consulting service that is looking for help standardizing on an effective, useful front-end stack
I’m mostly talking about back-end so far — which is quite easier to sell as you have a lot of ways to gradually convert, whereas frontend will have to be a major rewrite.
true.. client side apps are quite painful to split and bridge because they’re essentially one system not separated by network boundaries or queues
A problem I've seen against adoption is getting people to change their editing habits. They instinctively want to open a file in their usual editor and start editing in their normal way. It can really pay off to introduce the advantages of structural editing, CIDER, etc..
When they're inserting parens by hand and spacing to indent things, it's harder to get them to see the real benefits.
Wait, I’m inserting parens by hand, and correct indentation by spaces a lot of times — I don’t find it that cumbersome…
I've seen people really struggle with the editing, and I'm watching them get frustrated before I've had chance to show them anything.
Perhaps that's an overstatement, but I've definitely had cases where I can totally see why they don't consider the syntax an advantage, rather than just different - and i think it is.
To convince people to learn an unfamiliar sytax, convincing them of the advantages of said syntax can be important.
and the intricacies of lisp-1 vs lisp-2, macros, structural editing, etc. are really only things you appreciate after quite some familiarity.
I think those are the two main fears: 1) less widespread adoption (hiring, help, libraries) and 2) weird syntax and editing experience
In my opinion, using words like homoiconic and talking about macros misses the point. The uniform syntax of lisp means that you can always refactor code in a way that is not really possible in a language like javascript.
I don't have a really convincing argument to 1), other than that I think most libraries are overated and clojure hires are smarter 😛
It's easy to dismiss though
For me, that’s why I like clojurescript. When you start to have hundreds of lines of ugly repetitive crap, you know that you can fix it in any lisp-based langauge.
Hello everyone, quick question, does anybody have any recommendation as to how to use the 'fs' phantomjs module in a cljsfile? I have been looking into the :foreign-libs option in cljsbuild but to no avail
Meta: perhaps there should be an “evangelism” channel? I’m sure a lot of people would like to bounce around ideas on this…
Who must we ping? @seancorfield?
@orestis You rang, sir? 🙂
We have #community-development which is probably appropriate for that.
(it was originally created to discuss what we should all do in the case of the Slack shutting down large communities but it really is broader than that)
OK, your call — I’d think that #evangelism would be a more apt title for this discussion FWIW 🙂 It might help with discoverability a bit more.
As in, you might want to sell Clojure to your company but it will take some time until your coworkers become a proper member of the community.
The "channel details" for #community-development say "community growth & support" and evangelism fits into that...
One interesting datapoint is that I believe that the second most popular language that people are coming from is JavaScript
If including jQuery + a JS file in your page was 1x, using CLJS was 2x. But these days, even with helpers like create-react-app, yarn, etc, using JS is about 4x, while CLJS has remained at 2x.
All those JS state-management strategies are reduced to just using an atom (for example).
And immutable by default erases all that confusion between normal JS and Immutable JS (etc).
With CLJS, you learn about four things, and then you watch the JS world re-invent them every other month.
@lee.justin.m Maybe so, but my use is so lightweight I just don’t have the issue anymore.
@devicesfor I use it as an event loop. Components take a channel, send events on it. The events are processed, returning a new state.
@devicesfor No “wrapping” if I understand you correctly.
Oh. I don’t know. I use a single atom for state and a multi-method to process events. Rum (and Quiescent before that).
A long time ago I didn’t like the fact that you could have State all over the place in reagent and never looked back. I’m sure I don’t have a fair view of it.
maybe you mean something else, but it is really nice to be able to download high quality react libraries and have them work. given that there are about 6 flavors of javascript in the wild, it is kind of incredible that it does work. i’d say that’s a big gain
Regardless, for me, anyway, the more I can get away with just the base language, the better. (Well, + core.async.)
what promise complexity were you talking about @zentrope? callback-hell?
we're erasing that with a promise-monad which works out very nicely... and is another argument in support of a lisp - the "do" transformation used to give a clean syntax is a macro
I think I know what he means, promise rejections do not compose well because they are not data. IMHO that is the main reason for using channels for async (sorry if I misunderstood, just wanted to vent this out 😄)
@mccraigmccraig I’ve not spent enough time with them, but I’ve used “fetch”, say, and it’s hard to just get a value out of it in a synchronous way. Hard to debug.
@lee.justin.m pluggability is different from writing a la carte useful things
React just demonstrates that functional programming is a good idea - but we already know that
@mccraigmccraig I also get the impression that promises are just an attempt to paste-over the need for actual threads. do.this().then().then().then().
@zentrope if you were using a thread for that then you would be blocking, which would be rather a waste
if you are actually using the .then() methods on promises though then that's certainly not a very nice way to program with them
promises are an attempt to paste over the need for callbacks. callbacks are an attempt to paste over the need for threads
well, it's true promises paste over callbacks, but they also give you a value to pass around, which is very powerful - it enables promise composition
and once you realise that promises form a monad then you are laughing
All that aside, a pattern I’ve noticed over the years, esp. in Java Culture, is that practically every new thing is an antidote to the previous poison: but it’s rare that folks think about maybe not taking poison in the first place.
you can have your async code, with error handling, short-circuit evaluation and composition in a sync-link syntax
@mccraigmccraig It might be I’ve just never had the need for it in my super-simple get-data-put-in-database apps.
on the backend that's true (although my current app is all async on the backend too and it's working out very nicely)... but in js you are forced to do everything async, so it's worth figuring out reasonable ways to deal with it
clojure and clojurescript have the tools for it though
This may give you a hints as to why: https://brendaneich.com/2007/02/threads-suck/ It sure is nice never to have to think about concurrency in javascript.
have a look at this for an example of a nice way of programming with promises in clojure/script http://funcool.github.io/cats/latest/#manifold-deferred
I’d love to try to use that library but man the docs are dense. I don’t give a s** about category theory and I suspect most working programmers don’t either.
That article confirms that it’s shared, mutable state that’s the issue, not threads, no?
But I do think there’s a bit of religion about “async all the things” that is kinda fundamentalist.
maybe i miss the point: browsers implement the model and it’s not going to change anytime soon so how do i write code today to deal with that
Wouldn’t it be cool if you could just write your code with one step after another, then let the runtime figure out how to execute it in chunks?
So, to summarize, for the browser apps I write, just about every action (coming from the server or initiated by the user) results in an update to “State”, which then causes a re-render. With core.async, there is no callback issue (all callbacks just drop an event in a channel), so the need for promises isn’t there for me. Thus, to me, promises seem complex in the amount of ceremony.
(when-let [event (<! ch)] (try (process event) (catch :default e (process {:event :error :e e})))
Throw in some more data in the error case (such as the original message), and … praps I’m naive. :)
i'm an "async all the blocking things" fundamentalist @zentrope 🙉
@richiardiandrea That’s interesting: I’d love to understand what you mean. The one thing I miss about javascript is a language-level promises because they have a clearly defined error channel and work as expected with uncaught exceptions.
then-chaining can be annoying but async/await is the same syntax as go blocks, but with the caveat that exception have better behavior in js
I personally prefer to compose data and identify errors with functions, like passing back error maps like:
{:error {:msg "message"}}
It gives me more flexibility and I am not tied to a mechanism that may or may not suit me. Also promises can pass back any data for errors but it is not considered good practice.
Having said it is always case by case and I try to understand first if it's worth adding the channel complication or not to my code path. Sometimes it does sometimes I use promises. It depends.Okay I think I understand your point. I think mine is slightly different: I’m coming at this from a debugging and tooling perspective. If you or a library writer screw something up and fail to catch an exception or miss an error condition, you are likely at least get something with promises. Not necessarily so with channels, which require careful error handling on the “put” side and an ad hoc convention (e.g. dnolan’s <? operator) for error channels.
or maybe the go macro could catch exceptions and the <? semantics are the default take behavior. i know this isn’t going to happen but it seems to me that it would make channels behave more congruently with exceptions
My point is exactly the opposite of that, I rarely want to throw exceptions except at the very boundaries
so I try to avoid Promises as much as possible in the "business logic" part, if complicated enough to justify channels
“want” isn’t the point. if you fail to realize that, say, json.parse throws an exception, the resulting behavior is bad. see e.g. https://github.com/r0man/cljs-http/issues/110
and to be clear: I LOVE channels, I’m just annoyed that the way to use them seems to be “just always write correct code or else you’ll get a severed stacktrace in the middle of a blizzard of gensyms”. i want them to be great and also easy for dumb programmers like me to use
I’m bolting a cljs project onto a javascript codebase. Can I setup the cljs compiler to access the npm dependencies in the javascript project? would symlinking their package.json and copying the deps i need (and versions ) into the :npm-deps key be a good way to go?
@escherize if I understand the problem correctly, you'd just need to duplicate the :npm-deps
from the ones in package.json
and add :install-deps false
@escherize my opinion is that shadow-cljs will be better for this. it already uses the package.json to do npm resolution
@richiardiandrea thanks for a quick response — but will those deps be loaded twice? (the js app loads the cljs code from the index.html, so i’m afraid would they both package their own (identical) deps?
@escherize isn't require idempotent?
@lee.justin.m thanks for responding too! I’ll take a closer look at shadow-cljs.
sorry for answering with a question 😄 I think you should not have that problem
@escherize I think the way to do what you want is to use the :npm-module target with shadow and then just use it as a library. https://shadow-cljs.github.io/docs/UsersGuide.html#target-npm-module You should hop into #shadow-cljs if you have issues.
Does it make sense to use code-splits with html5 async script tags? I'm not sure if it provides any benefit, and it doesn't work without :optimizations :advanced
, since document.write
can't be used in async scripts.
Yeah, it doesn't work wirhout :advanced
.
Which is fine. I suppose I could have separate dev and prod index pages.
shadow-cljs has an option for makes <script async ..>
work in :none
but default CLJS does not
I'll have to look into that. Thanks
:async-require
wasn't properly documented but I just added a section in case you are interested. https://shadow-cljs.github.io/docs/UsersGuide.html#_async_loading
@lee.justin.m I have a project I used a lot of core-async, I agree the vanila things miss important stuff (important in the sense that I see to always require then to use it effectively, but I do it mostly on cljs, so maybe it's something about that). well, adding the <?
is very good, but not enough, another one that seals the deal is the (go-catch
), that's a go block that will re-throw exceptions, this way you can work very much like in a promises world
if you like here is the code, it's pretty trivial: https://github.com/daveconservatoire/dcsite-cljs/blob/master/src/cljs/common/async.clj#L17-L21
@wilkerlucio yea and i’ve seen this too: https://github.com/fullcontact/full.async/blob/master/src/full/async.cljc#L65-#L72
so, had you tried using that?