cljs-dev

ClojureScript compiler & std lib dev, https://clojurescript.org/community/dev
dnolen 2020-04-12T00:37:16.323200Z

looks like things haven't changed so much w/ React, 5 dynamically referred to plugins still need to be in externs when advanced compiling

dnolen 2020-04-12T00:39:22.324400Z

still same codebase as the above the following funnels everything through Closure instead

dnolen 2020-04-12T00:39:46.324600Z

{:main cljs-bundle.core
 :output-to "out/main.js"
 :output-dir "out"
 :language-out :es6
 :npm-deps true
 :externs ["externs.js"]}

dnolen 2020-04-12T01:57:04.325800Z

browser REPL quick start works like a charm with the bundle changes

orestis 2020-04-12T06:44:20.328300Z

Not sure if that’s us - we use shadow for npm stuff and it also handles code-splitting. Kind of a necessity when eg we use Vega which is 1mb of JS.

orestis 2020-04-12T06:45:53.329400Z

Is optimal code-splitting different than ordinary code splitting? Is this the thing that shadow-cljs does?

orestis 2020-04-12T06:46:28.330400Z

Excuse my ignorance, I am only exposed to the way shadow-cljs does things :)

dnolen 2020-04-12T11:13:16.332400Z

hey let's not use threads, it's really annoying to see backlog

👍 1
dnolen 2020-04-12T11:13:51.332900Z

optimal code splitting is a Google Closure thing - not a CLJS or shadow-cljs thing

dnolen 2020-04-12T11:14:04.333400Z

neither tool can do what Closure does for Closure-aware code

dnolen 2020-04-12T11:15:16.334Z

all you can do for npm stuff is prepend it

dnolen 2020-04-12T11:17:12.335Z

but now that I think about it, the existing code-splitting feature probably already works or can be made to work trivially

dnolen 2020-04-12T11:17:57.335900Z

that said if we can't - not a big deal IMO, if shadow-cljs can offer this feature and we can't it doesn't really have any bearing on the bigger goal

dnolen 2020-04-12T11:18:25.336700Z

code-splitting is a great feature - but it doesn't have anything to do really w/ the ecosystem effects I'm interested in

thheller 2020-04-12T11:26:35.337500Z

the issue with code-splitting is getting that to work in webpack

thheller 2020-04-12T11:26:51.338Z

because that has a fundamentally different view on how to do that then the closure-compiler does

thheller 2020-04-12T11:28:45.339Z

FWIW in shadow-cljs I have a :external js-provider which looks pretty similar to the new bundle stuff (ie. generate a .js file that other tools can process to load npm deps)

thheller 2020-04-12T11:29:54.340200Z

I only did that as an experiment though so nobody uses it

thheller 2020-04-12T11:30:05.340400Z

> the ecosystem effects I'm interested in

thheller 2020-04-12T11:30:08.340600Z

what would that be?

dnolen 2020-04-12T11:35:54.341400Z

you don't need CLJSJS like solutions to distribute ClojureScript libraries that depend on the JS ecosystem

dnolen 2020-04-12T11:36:09.341800Z

that's the whole point of doing the bundle thing - not convenience

dnolen 2020-04-12T11:37:05.342500Z

nor is it about tool X vs. X do CLJS builds - just don't care about that at all

dnolen 2020-04-12T11:37:42.343200Z

the important thing is that any tool X can handle a CLJS dep that uses :npm-deps to rely on something

dnolen 2020-04-12T11:44:07.344600Z

@thheller re: code-splitting, how do you handle requires that you can't process i.e. React components w/ image / CSS requires?

thheller 2020-04-12T11:50:44.345200Z

just ignore them. they aren't too common in actual published libs (for the browser)

dnolen 2020-04-12T11:51:12.345800Z

so users run another tool to handle them?

thheller 2020-04-12T11:51:17.346100Z

they are common in react-native but shadow-cljs doesn't process that at all

dnolen 2020-04-12T11:51:39.346600Z

so you can't for example use shadow code splitting to partition assets based on what components load on a page?

thheller 2020-04-12T11:52:26.347Z

it can in theory but it doesn't no

thheller 2020-04-12T11:53:13.347700Z

but most libraries actually do not have css requires so not a big deal

dnolen 2020-04-12T11:54:13.348500Z

re: webpack yeah not interested in trying to combine w/ their code splitting - it can't work

dnolen 2020-04-12T11:54:49.349200Z

however the module grouping algorithm doesn't work on source, it only works on dependencies - so I think it can probably be made to work pretty easily

dnolen 2020-04-12T11:55:08.349700Z

while processing node stuff through Closure is a hit or miss - our ability to compute the dep graph is pretty good

dnolen 2020-04-12T11:55:36.350400Z

so we can just add these to the module grouping algorithm and mark them as coming from elsewhere

dnolen 2020-04-12T11:55:42.350800Z

then webpack is just used to prepend that stuff

dnolen 2020-04-12T11:55:46.351Z

just as in the single file case

thheller 2020-04-12T11:56:27.351800Z

for the :external case in shadow-cljs I intended that file to be loaded completely separately which effectively is sort of code-splitting out the npm code and the cljs code

thheller 2020-04-12T11:57:02.352700Z

can't actually split npm deps but its usually good enough if you can separate out the npm parts and have that cacheable

dnolen 2020-04-12T11:57:26.353200Z

yeah that's probably what we'll ship w/ now

dnolen 2020-04-12T11:57:35.353500Z

and add the code splitting part as a separate step

dnolen 2020-04-12T13:01:06.355300Z

it would be nice if all Clojure dep tools could fetch npm deps rather than ClojureScript caring about it, but I don't see that happening quickly in a synchronized fashion, @alexmiller thoughts?

dnolen 2020-04-12T13:06:10.356500Z

unlike git deps it's not meaningful if only tools-deps can do it - every tool needs to be able to do it a la Maven

thheller 2020-04-12T13:06:42.356900Z

if you intend to use webpack you'll have npm so just using npm seems fine to me

thheller 2020-04-12T13:06:55.357300Z

I played with the idea of replacing it myself but its just not worth

thheller 2020-04-12T13:07:28.357900Z

there are already alternatives like yarn anyways

dnolen 2020-04-12T13:07:35.358100Z

@thheller of course it has to bottom out in npm

dnolen 2020-04-12T13:08:00.358700Z

I'm just pointing there's no a universal Clojure way to have a node dep - curious if Alex has thoughts is all

dnolen 2020-04-12T13:08:32.359300Z

ClojureScript being able to handle is a acceptable workaround for now - just looking at the much longer picture too

alexmiller 2020-04-12T13:36:18.359800Z

I have actually thought about this a bit

alexmiller 2020-04-12T13:37:40.361700Z

tools.deps is designed to procure and expand transitive deps through an abstraction (a few multimethods) and npm has everything needed to fulfill that

dnolen 2020-04-12T13:38:17.363Z

@alexmiller yeah that's why I was asking, you mentioned it before

alexmiller 2020-04-12T13:38:19.363300Z

The question then is - what do you do with that? How does that relate to the classpath?

dnolen 2020-04-12T13:38:30.363500Z

it doesn't need to relate to classpath

dnolen 2020-04-12T13:38:45.363900Z

all that stuff just ends up in node_modules

dnolen 2020-04-12T13:38:49.364200Z

something else will deal with it

dnolen 2020-04-12T13:39:42.365300Z

my question is really more about whether you thought other tooling

dnolen 2020-04-12T13:39:51.365900Z

since if it works w/ tool-deps not much of a win

dnolen 2020-04-12T13:40:04.366600Z

not useful for Lein / Boot etc. w/o a lot more steps

alexmiller 2020-04-12T13:40:29.367300Z

So how would you get at this behavior though? Programmatically by calling into tools.deps or do you want it to work via clj?

dnolen 2020-04-12T13:41:05.368Z

my expectation would be that just installs that stuff

dnolen 2020-04-12T13:41:39.369100Z

to clarify we don't need classpath because node is just relative requires starting at node_modules

dnolen 2020-04-12T13:41:51.369500Z

any build tool that is going to use that stuff understands that already

alexmiller 2020-04-12T13:42:08.370100Z

Only in the project or in a shared place like m2?

dnolen 2020-04-12T13:42:39.370400Z

I don't think we want to go there

dnolen 2020-04-12T13:42:52.371100Z

yarn and npm have slightly different semantics

dnolen 2020-04-12T13:43:06.371700Z

so local only

alexmiller 2020-04-12T13:43:08.371800Z

I’m not suggesting anything, I just don’t know how any of this stuff works :)

alexmiller 2020-04-12T13:45:50.374600Z

This is a major deviation from a model Rich and I have worked pretty hard to nail down so would need some real thought about whether this is the best place to do this (I’m a little worried to back into it by “this things looks kinda like that thing”)

alexmiller 2020-04-12T13:48:53.376700Z

We have also been working on this tools.build stuff for artifact building and that may be a better fit, but we are still trying to figure out the shape of it

dnolen 2020-04-12T13:50:08.377500Z

right, ok, just wanted to your thoughts

dnolen 2020-04-12T13:51:20.378600Z

there's no issue IMO w/ us handling it - but wanted to get your initial thoughts before we release

dnolen 2020-04-12T16:14:44.379Z

@alexmiller are site builds automatic again?

alexmiller 2020-04-12T16:29:36.379500Z

@dnolen no, ping me when needed

dnolen 2020-04-12T17:04:22.380100Z

@mfikes hrm, I guess because of spec.alpha and reader stuff we actually need Clojure 1.9? Or am I misremembering?

dnolen 2020-04-12T17:04:38.380600Z

if that's true I'm not sure why we didn't bump this in the pom.template.xml?

mfikes 2020-04-12T17:05:20.380800Z

Hmm... I can't recall

dnolen 2020-04-12T17:07:17.381100Z

trying with Clojure 1.8

dnolen 2020-04-12T17:15:09.381400Z

Clojure 1.8 works fine

dnolen 2020-04-12T18:15:23.382200Z

@alexmiller kick it off whenever you have a chance

dnolen 2020-04-12T18:15:56.382900Z

I removed a lot of stuff and modernized everything - clj and cljs.main only in the guides

dnolen 2020-04-12T18:17:05.383600Z

@mfikes no rush but if you want to put together release notes that would be cool - I'm going to work on a post about :target bundle + updated Webpack guide

👍 1
🎉 3
alexmiller 2020-04-12T18:20:07.383900Z

site is updated

dnolen 2020-04-12T18:36:49.384100Z

thanks!

dnolen 2020-04-12T19:00:30.385Z

if people want to try it out

dnolen 2020-04-12T19:00:51.385600Z

for the ClojureScript dependency you'll either want to ./script/build and note the version that gets install locally

dnolen 2020-04-12T19:01:15.386200Z

or git deps

dnolen 2020-04-12T19:02:16.386800Z

{:deps {org.clojure/clojurescript {:git/url "<https://github.com/clojure/clojurescript.git>" :sha "7792adf10e8961cbd5b0267a30a7d9655c770086"}}}

dpsutton 2020-04-12T19:59:08.389200Z

@dnolen 1. npm --save-dev webpack webpack-cli needs install 2. same for the npm --save react react-dom (isn't --save implied by install?) 3. the clj -m cljs.main -co build.edn -v -c -s assumes a deps.edn file has been created already but that's not in the steps 4. going through these steps i got

Execution error (ExceptionInfo) at cljs.closure/build (closure.clj:3192).
:bundle-cmd :none failed
5. the stdout from the tempfile associated with this error was
:std-out
  18   │      "Hash: 980d631d7dd0f2217840\nVersion: webpack 4.42.1\nTime: 24ms\nBuilt at: 04/12/2020 2:56:09 PM\n\nERROR in Entry m
       │ odule not found: Error: Can't resolve './out/index.js' in '/Users/dan/projects/clojure/scratch/hello-bundler'\n"}
...
   :cause ":bundle-cmd :none failed",
  47   │   :data
  48   │   {:cmd ["npx" "webpack" "--mode=development"],
  49   │    :exit-code 2,
  50   │    :std-out

dnolen 2020-04-12T19:59:26.389500Z

@dpsutton yeah I'm going through it now - updated

dpsutton 2020-04-12T20:05:24.390100Z

in Firefox i'm getting > SyntaxError: import declarations may only appear at top level of a module and no console logging

dnolen 2020-04-12T20:07:10.390200Z

@dpsutton did you try Chrome/Safari?

dpsutton 2020-04-12T20:07:55.391400Z

Safari reported invalid { This machine is only two days old and doesn’t have chrome yet

dpsutton 2020-04-12T20:09:10.392300Z

> import {npmDeps} from "./npm_deps.js"; seems to be the offending line. Is this the correct output of webpack?

dnolen 2020-04-12T20:10:35.392400Z

no

dnolen 2020-04-12T20:10:48.392500Z

@dpsutton I think you missed a step

dnolen 2020-04-12T20:11:24.393400Z

I just copied and pasted everything and it worked (except the final step, advanced compilation + foreign override)

dnolen 2020-04-12T20:12:24.393800Z

your issue not browser related - but something else - make sure you copy and paste unless you really understand the steps, no tweaks (happy to explain)

dpsutton 2020-04-12T20:12:52.394300Z

Yeah tracing through to see which one I may have overlooked

dnolen 2020-04-12T20:14:06.394800Z

:output-to must be out/index.js

dnolen 2020-04-12T20:14:27.395400Z

entry: in webpack config must be out/index.js

dnolen 2020-04-12T20:15:02.396Z

and the final file must be out/main.js to see it in the default webserver

dnolen 2020-04-12T20:15:14.396500Z

all of this can of course be changed - but these things must align

dnolen 2020-04-12T20:16:22.397700Z

@dpsutton you can also drop :build-cmd and run webpack directly - that part is pure convenience

dpsutton 2020-04-12T20:21:42.398200Z

ok i think i had missed installing webpack and webpack-cli when making my list earlier. sorry about that

dpsutton 2020-04-12T20:22:15.398900Z

now everything is working in the browser. however, in the terminal i'm seeing

Exception in thread "Thread-386" java.lang.NullPointerException
	at clojure.core$deref_future.invokeStatic(core.clj:2300)
	at clojure.core$deref.invokeStatic(core.clj:2320)
	at clojure.core$deref.invoke(core.clj:2306)
	at cljs.repl.browser$repl_client_js.invokeStatic(browser.clj:116)
	at cljs.repl.browser$repl_client_js.invoke(browser.clj:115)
	at cljs.repl.browser$send_repl_client_page.invokeStatic(browser.clj:123)
	at cljs.repl.browser$send_repl_client_page.invoke(browser.clj:118)
	at cljs.repl.server$dispatch_request.invokeStatic(server.clj:192)
	at cljs.repl.server$dispatch_request.invoke(server.clj:182)
	at cljs.repl.server$handle_connection.invokeStatic(server.clj:206)
	at cljs.repl.server$handle_connection.invoke(server.clj:202)
	at cljs.repl.server$server_loop$fn__9753.invoke(server.clj:216)
	at clojure.core$binding_conveyor_fn$fn__5754.invoke(core.clj:2030)
	at clojure.lang.AFn.run(AFn.java:22)
	at java.base/java.lang.Thread.run(Thread.java:830)
serves content just fine when i hit refresh in browser though

dpsutton 2020-04-12T20:25:19.399700Z

http://localhost:9000/repl?xpc={"cn":"qMRTfKzE3R","tp":null,"osh":null,"ppu":"http://localhost:9000/robots.txt","lpu":"http://localhost:9000/robots.txt"}

dnolen 2020-04-12T20:29:53.400100Z

@dpsutton yeah that's side detail, will look into that later

👍 1
dnolen 2020-04-12T20:30:11.400600Z

glad it's working!

dpsutton 2020-04-12T20:30:15.400900Z

this is awesome. thanks so much!

dnolen 2020-04-12T20:30:35.401300Z

there's definitely an issue w/ inferred externs, which I need to dig into

dnolen 2020-04-12T20:30:53.401700Z

making sure that Reagent can work is good test case

dnolen 2020-04-12T20:32:59.403200Z

@dpsutton yeah it's pretty cool, to be honest we could have done it a long time ago, now that I really see it, a variant of this had been suggested a few times by folks like @thheller - like just emitting require for CLJS namespaces so you can run JS tools

dnolen 2020-04-12T20:33:34.403800Z

one problem is JS tools can't really handle CLJS well so the impact seemed minor

dnolen 2020-04-12T20:34:18.404600Z

other issues are how to make this work for REPLs w/o being a pain in the butt - re-natal actually gave me the idea here - perhaps shadow does something similar don't know

dnolen 2020-04-12T20:34:35.405Z

anyway I think this is a pretty big win

dnolen 2020-04-12T20:34:45.405300Z

since what this gives you is dead simple

dnolen 2020-04-12T20:34:55.405700Z

we just generate stuff that you can pass onto your favorite JS tool

juhoteperi 2020-04-12T20:35:14.406200Z

I will add this bundle target with webpack as a test environment to Reagent repository

juhoteperi 2020-04-12T20:36:08.407Z

I'll also remove cljsjs dependency in the next version, and update documentation to instruct how to provide React.

dnolen 2020-04-12T20:38:27.407800Z

@juhoteperi cool! I do need to sort out the inferred externs issue first - somehow COMPILED is sneaking in there when trying this w/ Reagent

juhoteperi 2020-04-12T21:03:27.408800Z

Looks like bundle-cmd isn't run for me automatically, but it works when I run webpack myself.

dnolen 2020-04-12T21:11:34.409300Z

@juhoteperi it should work, it might have failed though it's strange there's no error for you

dnolen 2020-04-12T21:11:47.409500Z

(though that could be a bug)

dnolen 2020-04-12T21:12:17.409900Z

could be consolidated too

juhoteperi 2020-04-12T22:34:45.411100Z

Couldn't find out reason. No error, no output and no file being written. Got the test suite running now, I passed the bundle to Karma with Webpack plugin, just needed a small workaround to get Karma to wait untill JS files loaded by Cljs are ready: https://github.com/reagent-project/reagent/pull/486/files

rakyi 2020-04-12T22:53:19.412200Z

@juhoteperi do you have --ignore-scripts set for npm by chance? it’s npm option, but can be stored also in global config

dnolen 2020-04-12T23:24:51.413Z

ok I found the problem with advanced compilation - reagent project with react swapped in via webpack works fine under advanced compilation

dnolen 2020-04-12T23:28:58.413500Z

@juhoteperi you should be able to reproduce on your REPL on your machine

dnolen 2020-04-12T23:29:31.414200Z

(require '[clojure.java.shell :as sh]) (sh/apply ...) whatever your bundle command vector is

dnolen 2020-04-12T23:30:24.414700Z

fwiw, I did get a case where the cmd failed for me and got an expected exception from the bad exit code