cljs-dev

ClojureScript compiler & std lib dev, https://clojurescript.org/community/dev
Oliver George 2020-05-15T00:06:36.453500Z

Hello. I noticed a problem with the REPL resolving aliases in certain situations. Here are my repro notes, tell me if I should raise a JIRA ticket. https://gist.github.com/olivergeorge/37f420d369e3a4d60c5bf5ff2c171664

Oliver George 2020-05-15T00:06:38.453600Z

dnolen 2020-05-15T00:36:54.454300Z

@olivergeorge I would say none of these cases are a problem

dnolen 2020-05-15T00:37:14.454700Z

you have to set :analyze-path

dnolen 2020-05-15T00:38:52.456200Z

also doing anything here by default may effect existing tooling or expectations

dnolen 2020-05-15T00:39:37.456600Z

would need to collect some information

dnolen 2020-05-15T00:39:55.457Z

a safer way would be something new like :analyze-main and only do it for cljs.main

dnolen 2020-05-15T01:04:01.457500Z

@olivergeorge hrm I think restricting this to behavior cljs.main could work

dnolen 2020-05-15T01:05:11.458100Z

give master a try - if it turns out to be problematic might revert - but it seems like it could work

dnolen 2020-05-15T01:05:25.458500Z

if REPL gets :main then we analyze it in a separate thread

dnolen 2020-05-15T01:06:00.459100Z

@mfikes related, I can't remember why we didn't analyze-path off the main thread

mfikes 2020-05-15T01:07:04.459900Z

@dnolen It was to gain more parallelism, IIRC. You can analyze in one thread effectively, while emit in the other.

mfikes 2020-05-15T01:09:33.460300Z

@dnolen Here is what I'm referring to https://clojure.atlassian.net/browse/CLJS-2896

dnolen 2020-05-15T01:14:06.460600Z

@mfikes sorry you're probably missing the context

dnolen 2020-05-15T01:14:24.461100Z

REPL has :analyze-path feature so that you can resolve stuff you know you compiled

dnolen 2020-05-15T01:14:36.461500Z

but this happens on the REPL main thread while starting

dnolen 2020-05-15T01:14:41.461800Z

so it slows down startup

mfikes 2020-05-15T01:15:06.462300Z

Oh, sorry, I read that but I read it as "analyze". Hrm. I don't recall anything around analyze-path off the main thread.

mfikes 2020-05-15T01:16:03.463200Z

Ahh, so you are wondering if it is safe to put it off to the side and re-join with its results after the REPL is live. That sounds like a good tactic to reduce latency-to-first prompt, yes.

dnolen 2020-05-15T01:16:18.463700Z

@mfikes there's actually no need to rejoin πŸ™‚

dnolen 2020-05-15T01:16:26.464200Z

because it runs via bound-fn

mfikes 2020-05-15T01:16:33.464400Z

Ahh, I forgot we are working in a sane language.

mfikes 2020-05-15T01:17:28.465100Z

(I'm often afraid of the unpredictable effects of these concurrent threads, but immutability saves the day.)

dnolen 2020-05-15T01:19:13.465400Z

let's see how this change for :main fares

dnolen 2020-05-15T01:19:38.465800Z

if it seems ok then we could do it for :analyze-path

Oliver George 2020-05-15T01:55:18.466100Z

Looks like that's done the trick. Thanks.

Oliver George 2020-05-15T01:55:39.466400Z

Specifically, my repro now works as expected against 00079768f9

dominicm 2020-05-15T13:46:59.466800Z

pretty minor thing: the webpack config doesn't really need to exist. It can be replaced by the cli entirely, meaning no need for a (complex looking) file.

bhauman 2020-05-15T13:49:31.468Z

yeah ["npx" "webpack" "infile.js" "-o" "outfile.js" "--mode=development"]

bhauman 2020-05-15T13:50:42.469200Z

@dominicm ^

bhauman 2020-05-15T13:51:30.470100Z

it might be better for templates and tutorials to have that

dominicm 2020-05-15T13:53:04.470200Z

@bhauman yeah, I was just digging that out :)

dnolen 2020-05-15T14:26:35.471100Z

@dominicm PR to the guide would be great!

dpsutton 2020-05-15T14:27:44.472600Z

would be nice for both to be listed in the PR rather than just the smaller cli version

dnolen 2020-05-15T14:28:43.473300Z

@bhauman I added reconnect to browser REPL, that said I could't get the browser REPL to disconnect spuriously - probably because we had some nice fixes a while ago that made things more stable.

dnolen 2020-05-15T14:28:58.473600Z

@dpsutton like documenting both ways?

dnolen 2020-05-15T14:29:05.473900Z

in case you need to expand the config easily?

dominicm 2020-05-15T14:29:24.474400Z

@dnolen added to my todo list

dpsutton 2020-05-15T14:29:33.474900Z

right. its nice to have the quick version when just getting a hello world version. and then when you need to expand that for a real world app nice to have the full config that's equivalent in case it needs to be a bit more complex

dnolen 2020-05-15T14:29:48.475300Z

agreed, @dominicm ^

bhauman 2020-05-15T14:30:02.475500Z

agreed as well

bhauman 2020-05-15T14:30:23.475900Z

@dnolen I thought more about the polling repl idea

dominicm 2020-05-15T14:30:24.476Z

What sort of "real world" things need to go in there. I've always just left it alone after creating it (with the old version of the guide).

dnolen 2020-05-15T14:30:33.476200Z

@bhauman all ears

bhauman 2020-05-15T14:30:53.476900Z

the file should be a truncated log

bhauman 2020-05-15T14:31:03.477200Z

of evals

dnolen 2020-05-15T14:31:20.477600Z

@dominicm just that if you have a project and you need to add plugins etc.

dnolen 2020-05-15T14:31:40.478200Z

it took me a surprisingly long time to figure out that "simple" config

dnolen 2020-05-15T14:31:45.478500Z

reading webpack docs is a nightmare

dnolen 2020-05-15T14:31:50.478700Z

or was then I put that together

dominicm 2020-05-15T14:32:05.479Z

Still is πŸ˜‚

dnolen 2020-05-15T14:33:28.481800Z

@bhauman not seeing the rationale bit - elaborate? just to avoid logic, you can just eval it?

dominicm 2020-05-15T14:33:35.482Z

Okay, actually. These 2 things might be related to what I'm currently doing actually. I've got some legacy ESM that I'm integrating into my project. Should I be running that through webpack somehow? Or through the alpha JavaScript modules w/ babel.

dnolen 2020-05-15T14:34:16.483100Z

@dominicm I would avoid the alpha modules feature for now

dnolen 2020-05-15T14:34:51.484300Z

one problem you'll have is if you want to use the modules from CLJS and they're not in node_modules

bhauman 2020-05-15T14:36:08.486Z

@dnolen just to prevent double evals, missed evals

bhauman 2020-05-15T14:36:44.486700Z

this could allow multiple evals

bhauman 2020-05-15T14:36:48.487Z

if needed

bhauman 2020-05-15T14:36:54.487400Z

=> 1 2 3 4

dominicm 2020-05-15T14:37:00.487700Z

I have ESM with jsx in, how should I include that in my project?

bhauman 2020-05-15T14:37:06.487900Z

1 2 3 4

bhauman 2020-05-15T14:37:29.488300Z

its just more robust

bhauman 2020-05-15T14:37:37.488600Z

for little cost

dnolen 2020-05-15T14:38:35.489600Z

@bhauman I'm not following how is this related to hot loading? oh you mean like multiple compiles triggered by N expressions?

dnolen 2020-05-15T14:39:28.491300Z

@dominicm so you need what I said, to require your module into CLJS

bhauman 2020-05-15T14:41:21.493200Z

I was being specific to a REPL that operates over client polling, hot reloading via a changes file is less critical

dnolen 2020-05-15T14:42:00.494300Z

@dominicm the easiest way right would be to get that into your node_modules first - i.e. make it package

dominicm 2020-05-15T14:42:58.494700Z

@dnolen and then it has a build step in making it a package which turns it into cjs or something?

dnolen 2020-05-15T14:43:16.495Z

@dominicm no you don't need to change anything about your code

dnolen 2020-05-15T14:43:35.495500Z

but it needs to be in node_modules we don't support relative paths

dominicm 2020-05-15T14:44:08.495600Z

Then cljs will generate a require() for it, and then webpack will be in charge of that?

dnolen 2020-05-15T14:44:12.495800Z

yep

dnolen 2020-05-15T14:45:49.496600Z

@bhauman I'm not following anymore - sorry more focused now. I don't really see a need to change the REPL more generally?

dnolen 2020-05-15T14:46:16.497500Z

there's nothing about the existing browser REPL strategy that poses problems

bhauman 2020-05-15T14:46:23.497700Z

ok maybe I missunderstood you yesterday

bhauman 2020-05-15T14:46:48.498400Z

cool then I rescind the proposal πŸ™‚

dnolen 2020-05-15T14:47:03.499100Z

browser REPL works fine - automatic reconnect addresses reliability

dnolen 2020-05-15T14:47:21Z

yesterday I was talking about hot-reloading

dnolen 2020-05-15T14:47:34.000600Z

that the changes file is an easy thing to do for anyone

bhauman 2020-05-15T14:47:37.000900Z

gotcha

dnolen 2020-05-15T14:47:40.001100Z

browser REPL can just use it

dnolen 2020-05-15T14:48:21.002200Z

and I like polling for that a lot because - file watching involve a bunch of stuff I don't want to do

bhauman 2020-05-15T14:48:21.002300Z

how specifically are you envisioning it using it ?

bhauman 2020-05-15T14:48:45.003200Z

but once you find the file?

dnolen 2020-05-15T14:49:05.003700Z

cljs.hot-reloader

dnolen 2020-05-15T14:49:25.004300Z

just fetches a file, we know goog.basePath so we know where it is

dnolen 2020-05-15T14:49:38.004800Z

when it gets a new file it calls goog.require that's it

bhauman 2020-05-15T14:49:39.004900Z

oh but you can poll from the client right?

dnolen 2020-05-15T14:49:46.005200Z

yes no server stuff here

bhauman 2020-05-15T14:49:50.005500Z

why form the repl

bhauman 2020-05-15T14:49:56.005800Z

why poll from the REPL?

dnolen 2020-05-15T14:49:57.005900Z

that's what I thought you were taking about πŸ™‚

dnolen 2020-05-15T14:50:04.006100Z

not from REPL, from client

bhauman 2020-05-15T14:50:16.006500Z

Oh ok

dnolen 2020-05-15T14:50:19.006700Z

{:preloads [cljs.hot-reloader]}

bhauman 2020-05-15T14:50:25.006900Z

when you say browser repl

bhauman 2020-05-15T14:50:31.007300Z

I missunderstood

bhauman 2020-05-15T14:50:33.007500Z

got it

dnolen 2020-05-15T14:50:34.007600Z

forget about REPL πŸ™‚

dnolen 2020-05-15T14:50:42.008200Z

just a hot reloader

bhauman 2020-05-15T14:50:48.008500Z

understood

dnolen 2020-05-15T14:50:52.008700Z

browser REPL would just add that preload

bhauman 2020-05-15T14:51:25.009400Z

absolutely we are on the same page for sure

bhauman 2020-05-15T14:51:56.010Z

OK so another suggestion, include compile excpetions, and warnings in the file

dnolen 2020-05-15T14:52:50.010900Z

[{ns-sym desc-map ...}]

dnolen 2020-05-15T14:53:22.011700Z

well timestamp somewhere

bhauman 2020-05-15T14:53:28.011900Z

yep and one more thing

bhauman 2020-05-15T14:54:11.012700Z

would be super nice mark which files were actually changed versus dependents

bhauman 2020-05-15T14:55:01.013600Z

thats just a detail but its nice to know which files the user actually changed versus which are dependently compiled

bhauman 2020-05-15T14:55:37.014200Z

but this is a nice to have and can be a future improvement

dnolen 2020-05-15T14:59:19.015800Z

@bhauman https://clojure.atlassian.net/browse/CLJS-3254

πŸ‘ 1
dnolen 2020-05-15T14:59:21.016Z

feedback appreciated

dominicm 2020-05-15T15:18:27.016200Z

;; needed for advanced but also fine in dev I assume? (from https://clojurescript.org/guides/webpack)

dominicm 2020-05-15T15:27:27.016300Z

Just to double check, I know there's the $ stuff in the works (which would be PERFECT!), but for the meantime is this considered valid? (require '[front-end :as front-end]) (front-end/utils.Auth.get "/some-url") Where utils is a folder, Auth is the default export of Auth.js (an instantiated class) and .get is a method on that class? I'm guessing I might need a .default in there.

souenzzo 2020-05-15T15:52:49.018500Z

about npx docs It always take the "newest" version of the thing and in JS community, break things is almost a "good pratice" ["npx" "webpack@4.43.0" ...] should avoid problems in the future (but it still can be problematic, once it pins only webpack, any subpackage required by range can break in the future

dnolen 2020-05-15T15:59:12.019100Z

@dominicm fine for dev too, yes that require should work

thheller 2020-05-15T16:32:05.020800Z

what? that is absolutely not valid?` utils.Auth.get only does property access, it will not look for files, folders or anything of that sort? it is valid if front-end exports the object structure like that but not otherwise

dnolen 2020-05-15T16:37:11.021300Z

oh sorry I missed the end of that sentence

dnolen 2020-05-15T16:37:29.021500Z

yeah that won't work

dnolen 2020-05-15T16:37:54.021900Z

@dominicm you really need to :require the same thing you would in Node.js

dnolen 2020-05-15T16:39:29.023500Z

I guess in this case maybe something like "front-end/utils/Auth" I'm not that familiar with conventions around exporting a Node module name

dnolen 2020-05-15T16:40:03.023800Z

but I'm assuming that relatively easy to sort out

dominicm 2020-05-15T17:32:01.025300Z

@dnolen yeah, you're right. Just figured that out. Then it's Auth/default.get I guess. I feel the need for $ more now. I think the generic solution is the right one.

dominicm 2020-05-15T17:33:16.025400Z

Where we're not using default it's quite beautiful though :)

dnolen 2020-05-15T17:44:13.025700Z

@dominicm sweet!

dnolen 2020-05-15T17:45:04.026600Z

that feature will definitely appear in the next release

dnolen 2020-05-15T17:48:03.027Z

the tsickle stuff is actually pretty interesting - https://medium.com/appmonet/using-closure-compilers-advanced-optimizations-with-webpack-816214b2fd5c

dnolen 2020-05-15T17:48:49.028100Z

There's a lot of TS code out there and probably a lot more DCE friendly

lilactown 2020-05-15T17:49:36.028700Z

yeah I got super excited about it

lilactown 2020-05-15T17:50:50.029600Z

there’s sometimes where I really want to drop down into JS and write some super performant/mutable stuff. TS makes it way easier to write JS. having it hook into closure would be πŸš€

πŸ‘ 1
bhauman 2020-05-15T17:52:18.031Z

@lilactown I’m sure you are aware of this already, but you can do that now, by writing a goog module compatible file, on the correct classpath?

dominicm 2020-05-15T17:52:48.031400Z

I think the key part was that TS makes it easier to write :)

lilactown 2020-05-15T17:52:49.031500Z

yes, closure JS is very tedious πŸ˜›

bhauman 2020-05-15T17:53:41.032300Z

hmmm interesting

bhauman 2020-05-15T17:54:44.033Z

goog.provide("my.ns"); my.ns = function() {}

bhauman 2020-05-15T17:54:57.033400Z

thats tedious πŸ˜‰

dominicm 2020-05-15T17:55:08.033600Z

Oh man, that syntax is so 10 minutes ago. Now we just write $12##$!

3
lilactown 2020-05-15T17:55:45.034300Z

it’s mainly the typing

bhauman 2020-05-15T17:55:53.034700Z

i get ya

lilactown 2020-05-15T17:56:12.035300Z

I actually enjoy TS’s interfaces type language

πŸ‘ 1
dnolen 2020-05-15T17:56:12.035400Z

heh I'm less interested in the JS writing part - which yes we need to improve, and more into the there's all this TS we can we use

lilactown 2020-05-15T17:56:22.036Z

yeah for sure

dominicm 2020-05-15T17:56:24.036100Z

I'm trying to find the xkcd about how humans can find anything interesting, if they're locked away in a box for an extended period for example. But <insert that>

dnolen 2020-05-15T17:56:28.036300Z

I only expect TS to get more and more popular

dnolen 2020-05-15T17:56:56.037100Z

and because it's Java/C# like it mean libs are less likely to do things that are overly dynamic

dnolen 2020-05-15T17:57:18.037500Z

plus Google is almost certainly going to go there anyway

lilactown 2020-05-15T17:57:22.037700Z

I think someone in a JIRA ticket pointed out https://github.com/google/incremental-dom

dnolen 2020-05-15T18:22:22.039100Z

huh webpack does tree shaking of ES2015 import now https://web.dev/commonjs-larger-bundles/

dominicm 2020-05-15T18:40:39.039500Z

Makes sense, that was one of the goals of esm.

dominicm 2020-05-15T19:31:17.039600Z

Is this an obvious "oh, you've done X" mistake? Caused by: java.lang.Exception: Could not write JavaScript nil

dominicm 2020-05-15T19:31:37.039700Z

Coming from write-js?

dominicm 2020-05-15T20:34:22.040300Z

Looks like find-sources is returning an empty list, which add-preloads does a (first post) on and gets nil. I'm not sure if -find-sources should be returning an empty list or not? I have no :modules in my opts (from a prn), and that seems to populate something of importance to cljs?

dnolen 2020-05-15T21:11:43.040600Z

not obvious - might need something minimal here

dominicm 2020-05-15T21:13:47.040700Z

blugh. I'm definitely in confused territory. That error doesn't happen with figwheel - but now I'm not getting an npm_deps.js produced, even though it's required by the main .js file...

dominicm 2020-05-15T21:13:57.040800Z

Something has gone very wrong :)

dominicm 2020-05-15T21:29:13.040900Z

@dnolen RE my first error, I can reproduce in mies by: bumping cljs & removing the "src" from build.clj

dominicm 2020-05-15T21:32:36.041100Z

Fixing that in my build.clj (by providing "src") gets me to the same place as figwheel, but now I can inject printlns :)

dominicm 2020-05-15T21:36:25.041200Z

@dnolen RE my second error, npm_deps.js is written, but was not a sibling of my output-dir. I was using:

:output-to "target/dev/public/frontend-output.js"
         :output-dir "target/dev/public/frontend.out"

dominicm 2020-05-15T22:53:00.041300Z

Parcel.js is an order of magnitude (4s vs 300ms) faster than webpack, and seems to produce js which is half the size in dev.

dnolen 2020-05-15T23:50:42.042Z

@dominicm I'm not completely following but if you believe there's a bug - it should be repro'd w/ just ClojureScript