Fork me on GitHub
#cljs-dev
<
2020-08-06
>
plexus09:08:51

@dnolen

clojure -Sdeps '{:deps {org.clojure/clojurescript {:git/url "" :sha "42bcb07b8bf23d57f98e4617e4c4c93347f09715"} reagent/reagent {:mvn/version "1.0.0-alpha2"}}}' -m cljs.main --install-deps
no node_modules gets created, npm is never called

plexus09:08:35

because in the code path that the patch touches npm-deps will be nil rather than a map

plexus09:08:50

in this case I also get an error on earlier versions of clojurescript, but at least it's shelling out to npm

npm ERR! 404 Not Found - GET  - Not found

plexus11:08:42

I finally got around to trying out emitting require statements from a macro, the thing we talked about a while back (https://clojurians-log.clojureverse.org/cljs-dev/2020-05-29/1590760413.380700)

plexus11:08:25

ran into two issues, the first one is small and I can submit a patch for that https://github.com/plexus/require-from-macro-test

plexus11:08:54

the second issue is that the required namespaces are not actually getting compiled. Is that something that could/should work, or is it up to me to do that as part of the macro?

thheller11:08:58

require needs to be completely static and cannot be emitted dynamically like that. no macroexpansion takes place when the files are first read to gather the ns data.

thheller11:08:37

require was only meant to work in files that don't have a ns in the first place but are still completely static

plexus11:08:40

@thheller David specifically suggested trying this approach, see the referenced conversation

thheller11:08:38

yeah I saw. to get this working however you need to change a bunch of machinery and I'm not sure calling the compiler API from within a macro isn't going to lead to crazy issues.

plexus12:08:47

I guess we're about to find out 🙂 this issue is for the first issue which I think is straightforward, and is separate from the question how/where/if those required namespaces should get compiled.

dnolen12:08:14

@plexus ok, make a issue w/ that repro - I guess I haven't run into this because I don't run that with :npm-deps empty

dnolen12:08:32

@thheller I wasn't suggesting dynamic require, that can never work

dnolen12:08:03

@plexus the other issue is interesting, I would say unexpected since original use case (`user.cljs` and other free floating scripts) should trigger compilation of required namespaces? Any issue should talk about this more fundamental problem

thheller12:08:47

well at what point is it a "dynamic require"? I'd say the example from Arne is dynamic

dnolen12:08:53

that is, it should in fact work (`ns*` adding things to compilation work)

dnolen12:08:16

@thheller dynamic how? it's happening from a macro, not at rutnime

thheller12:08:40

as in you need to macroexpand to discover new requires "dynamically". who knows what other side-effects those macroexpansions may trigger

dnolen12:08:30

not a big deal

dnolen12:08:52

we already have stuff like that - as long as people understand the limitations doesn't seem like there's anything to be concerned about

dnolen12:08:17

i.e. mostly useful for testing - which is what @plexus was wanting this for

thheller12:08:15

I understand but it makes things really annoying for tools (eg. Cursive) but also the build aspects like caching, parallel-compile, etc

dnolen12:08:44

for testing use can't matter since this is at the entry point

thheller12:08:45

well not actually sure about Cursive. maybe it already expands macros.

dnolen12:08:49

nor parallel compile

dnolen12:08:12

all existing limitations apply, it's gotta be a require right after ns form

dnolen12:08:19

so I don't see it adding much complexity either

dnolen12:08:31

I think for entry points it's actually probably something of a win

dnolen12:08:42

since we're never going to do custom reader conditionals

dnolen12:08:02

so this approach could get you other benefits to configure a build at the entrypoint

dnolen12:08:23

since you can't do this stuff in ns directly

dnolen12:08:29

interestingly ...

dnolen12:08:42

given all the restrictions it might be possible to solve the caching issue?

dnolen12:08:51

that would be a big win, since then you're not limited to entry point

thheller12:08:17

I don't think that solving build related things in side-effecting macros is a good idea

dnolen12:08:00

to be clear - this isn't new stuff anyway

dnolen12:08:23

how people use stuff that should work is up to them - we can make it better

thheller12:08:24

heck even a simple CLJ function that just returns a "dynamic" ns form that tools can invoke to figure out the "entries" is probably better

dnolen12:08:42

like I said - not interested in new ideas

dnolen12:08:51

just making sure there's a way with stuff we've already done

dnolen12:08:41

most of what @plexus has mentioned are just bugs

thheller12:08:51

so unless I'm completely out of touch with the CLJS codebase there is still a parse-ns that reads forms only until it encounters none ns or ns*. it then stops and analzyes the deps it found

thheller12:08:29

and then starts actual compilation

dnolen12:08:41

parse-ns is just a general helper

dnolen12:08:55

analyze uses, compile uses, the build stuff uses it

dnolen12:08:11

but yeah, that's how it works

plexus13:08:52

ok, I'll make a ticket for the :npm-deps issue, I'm not sure what the conclusion is for compiling the required files. Do I get it right that you're saying it is intended to work, and the current behavior is a bug?

thheller13:08:31

well I guess the only issue I have with this is that is breaks some assumptions about caching I have built into shadow-cljs (eg. if the file doesn't change its ns info and requires don't either)

thheller13:08:04

but I guess I can easily adapt that or just automatically opt of of caching in files that have ns* forms

dnolen13:08:48

@plexus well what I want to know is why this doesn't already work

dnolen13:08:08

i.e. you make a file a w/o a namespace that (require ...) at the top

thheller13:08:19

but it maybe opens the doof for some more "dynamic" require and not solving those via build config (eg. (require-in-dev-only '[re-frame-10x.whatever :as x]))

dnolen13:08:30

that should already work

dnolen13:08:52

@thheller yes, I'm not saying you can't carried away but I think there are some easy problem you could solve w/o build tool support

dnolen13:08:29

@plexus the whole point of (require ...) was so that you could compile scripts that don't declare ns

dnolen13:08:50

so I'm assuming we tested this at some point so maybe there's a narrower thing that's not working here

plexus13:08:53

right but in this case there's ns + require

dnolen13:08:04

ok so that's what I want to know 🙂

plexus13:08:15

ns to pull in the macro which then does the require

dnolen13:08:18

minimal case showing require works fine, and ns + require doesn't

dnolen13:08:24

the macro stuff doesn't matter really

thheller13:08:52

assuming that this is still the relevant code then it just stops when it finds ns and doesn't look further https://github.com/clojure/clojurescript/blob/f5f9b79f6f446cef768e190971cf67fc78bf5b93/src/main/clojure/cljs/analyzer.cljc#L4439

dnolen13:08:52

or if the macro part does matter - of course include that

dnolen13:08:16

the issue is that ns stops, ns* doesn't

dnolen13:08:33

or perhaps ns* star does too - anyways don't remember

dnolen13:08:38

@plexus let me know 😉

thheller13:08:45

ns* recurs so that continues

dnolen13:08:28

so that's the issue, I think if you solve that, that ns will continue if ns* exists

dnolen13:08:30

it will work

thheller13:08:28

well then it always analyzes the second form in each file and immediately discards it in most cases which may cost a bit of perf. probably not a big deal though.

dnolen13:08:05

yeah, I think reading a few more form probably isn't going to matter much though

plexus13:08:17

cool, thanks! I'll try to come up with a patch

dnolen13:08:58

👍:skin-tone-4:

dnolen13:08:09

@thheller definitely looks like your CLJS patch yesterday was fine and our CI setup is borked - I think what happened was that if the cache expires then WebKit master gets pulled down? will try to repro that locally and then start pinning WebKit to a known good sha that we can bump periodically

thheller13:08:29

yeah I saw. failure looked too weird to be related to my patch 😛

mfikes13:08:20

I've added a separate ticket for the CI issue and was also going to take a peek if nobody else gets to it first: https://clojure.atlassian.net/browse/CLJS-3274

mfikes13:08:05

FWIW, CI is still passing in the older Travis-based tests which also make use of JSC, so a JSC regression on master (or whatever is being used in GitHub actions tests) seems to be a good theory.

dnolen13:08:39

@mfikes were you pinning to a version? or to a build you had made and reusing?

dnolen13:08:52

ah huh, you know I couldn't get that to work which is why I used the OS X runner

dnolen13:08:19

@mfikes fwiw, it might be nicer to track WebKit since then we can test against newer JS features when that makes sense?

dnolen13:08:27

my impression is that version of WebKit in gtk might be old?

dnolen13:08:47

given that this literally worked last week

dnolen13:08:56

maybe we should just need to specify that sha to that time

mfikes13:08:14

Yeah... I'm also running a side test in CI to see what JSC is actually returning from tap>. Maybe we can catch something ahead of time and file a ticket with JSC

plexus15:08:10

adding a recur to cljs.analyzer/parse-ns for :ns makes the basic case of (ns foo.bar) (require 'foo.baz) work, I'll submit a patch for that. The next problem is that when creating the require via a macro the macroexpansion fails, get-expander* fails to find the macro var

plexus15:08:36

if I change it to use a requiring-resolve then it works, so this is the last thing blocking me. suggestions on how to actually fix this are welcome.

plexus15:08:14

might be enough to change it to (or (nil? npm-deps) (map? npm-deps))

dnolen15:08:38

@plexus patch for that welcome

dnolen15:08:03

@plexus further back - finding what macro var?

dnolen15:08:16

a snippet would clarify things a bit

plexus15:08:40

(ns foo.bar (:require-macros [foo.baz :refer [macro-that-requires]]))
(macro-that-requires)

thheller15:08:35

that should solve itself if foo.baz does the proper self require and you just (ns foo.bar (:require [foo.baz :refer [macro-that-requires]]))

thheller15:08:42

oh wait no. it doesn't actually analyze the deps at that point

dnolen15:08:09

@plexus but what is not being resolved? the macro?

plexus15:08:27

yes, the macro is not loaded yet when it's trying to be expanded, this causes an NPE

(.findInternedVar ^clojure.lang.Namespace
              #?(:clj (find-ns nsym) :cljs (find-macros-ns nsym)) sym)

plexus15:08:16

@thheller the self-requires works in that the compilation succeeds, but the build is invalid, the namespace that the macro requires isn't compiled

plexus15:08:44

where exactly are macro namespaces loaded? does the analyzer do that?

plexus15:08:56

(signing off soon but I'll continue with this tomorrow. thanks for all the help!)

dnolen16:08:33

@plexus ah right, there's the ns-side-effects pass in the analyzer

mfikes20:08:22

FWIW, the CI tests are failing in JSC because it returns undefined for setTimeout. Details in https://clojure.atlassian.net/browse/CLJS-3274

dpsutton21:08:27

interesting, i'm seeing SO posts saying that JSC doesn't implement setTimeout, setInterval, and clearTimeout