Fork me on GitHub
#shadow-cljs
<
2019-08-08
>
carkh07:08:45

@thheller you told me shadow-cljs now works with powershell (i didn't check that). But i don't have the cli tools for powershell anymore and it still works. Are you first checking the regular cmd path ?

carkh07:08:57

or maybe my version of shadow-cljs is old

thheller07:08:38

no it isn't checking anything, it just directly executes the powershell cmd (assuming Windows and using deps.edn)

thheller07:08:46

wasn't aware there were usable alternatives

thheller07:08:54

can add a check if needed though

carkh07:08:16

i was just curious as to how it is working here =)

carkh07:08:16

i'm guessing we're going inside powershell,n then out to get my cli

carkh07:08:23

as long as it works it's all fine

hlolli09:08:11

I'm not sure if it's my side or shadow's. It seems that on react-native with shadow version 2.8.41 or later sometimes failes to spit big chunk of the .js files. This happens on mac and on our ci build, but on my local linux, the js files are filled with correct data (not unlikley due to cache-ing). The error is goog is not defined, but I cant imagine what causes half of the file's data to go missing.

hlolli09:08:00

here's from mac

cat tests/tests.first_test.js
goog.provide('tests.first_test');
goog.require('cljs.core');
test("Adds 1 + 2 to equal 3",(function (){
return expect(((1) + (2))).toBe((3));
}));

hlolli09:08:16

and here is from (likely) cached linux

var $CLJS = require("./cljs_env");
var $jscomp = $CLJS.$jscomp;
require("./cljs.core.js");
var module$shadow_js_shim_module$react=$CLJS.module$shadow_js_shim_module$react || ($CLJS.module$shadow_js_shim_module$react = {});
var clojure=$CLJS.clojure || ($CLJS.clojure = {});
var cljs=$CLJS.cljs || ($CLJS.cljs = {});
var shadow=$CLJS.shadow || ($CLJS.shadow = {});
var goog=$CLJS.goog || ($CLJS.goog = {});
var reagent=$CLJS.reagent || ($CLJS.reagent = {});
var app=$ || ($ = {});
var taoensso=$CLJS.taoensso || ($CLJS.taoensso = {});
var module$shadow_js_shim_module$create_react_class=$CLJS.module$shadow_js_shim_module$create_react_class || ($CLJS.module$shadow_js_shim_module$create_react_class = {});
var tests=$CLJS.tests || ($CLJS.tests = {});
var module$shadow_js_shim_module$react_navigation=$CLJS.module$shadow_js_shim_module$react_navigation || ($CLJS.module$shadow_js_shim_module$react_navigation = {});

$CLJS.SHADOW_ENV.setLoaded("tests.first_test.js");

goog.provide('tests.first_test');
goog.require('cljs.core');
test("Adds 1 + 2 to equal 3",(function (){
return expect(((1) + (2))).toBe((3));
}));

module.exports = tests.first_test;

//# sourceMappingURL=tests.first_test.js.map

hlolli09:08:27

this doesn't happen in 2.8.37, so for my mac, this truncation only happens 2.8.41+

thheller10:08:00

@hlolli not sure which truncation you are talking about? the output you showed is "old". that is not the current output format

hlolli10:08:49

yes that's right, it's old, after nuke-ing the lockfile and node_modules, I can reproduce it on mac and linux.

hlolli10:08:10

with a new output format, I guess we need to change the way we require index.js?

thheller10:08:10

please take a step back and explain what your actual problem ist

thheller10:08:16

the source files that are generated have changed

thheller10:08:23

so comparing them the old stuff is pointless

hlolli10:08:42

ok, my initial reaction was that this change was the bug

thheller10:08:12

index.js require should be the same but depending on what you were doing it maybe changed?

hlolli10:08:01

for example "jest --verbose tests/*" where

"testMatch": [
            "**/*+(_test).js"
        ]
is my matcher

thheller10:08:28

how are tests relevant to a :react-native build?

hlolli10:08:29

this will try to open files that don't have the goog in its environment

hlolli10:08:19

we are testing react-native app and this worked fine before

thheller10:08:48

I still don't get what you are doing

thheller10:08:01

the only file you were supposed to be using was <output-dir>/index.js

thheller10:08:12

all of the others were implementation details and not intended for direct use

hlolli10:08:24

we were doing

import './app/shadow.cljs.devtools.client.react_native';
import { init } from './app/app.core';
init();
so we were using it wrong.

thheller10:08:51

uhm you are using some old setup?

thheller10:08:32

you should just be calling import "./app/index.js"

hlolli10:08:41

yes, I knew about the index file, since it worked, we didn't change it. But I'll change it now 🙂

thheller10:08:44

it was never meant for you to be used that way

thheller10:08:51

if you want to use this that way

thheller10:08:59

just switch to :npm-module target

thheller10:08:10

but then source maps still won't work

hlolli10:08:29

I'm all for better source maps! Excited to see them

thheller10:08:48

for them to work I had to switch the output format

thheller10:08:55

which is why everything is now in index.js itself

thheller10:08:15

and the "supporting" files are only there because otherwise metro throws an exception when an error is thrown in the app

thheller10:08:33

they aren't actually used for anything

thheller10:08:42

only index.js matters and contains all code

thheller10:08:03

if you want to run tests with jest I'd suggest creating a secondary :npm-module build

hlolli10:08:12

yes, exactly

thheller10:08:18

that output will still behave as before

hlolli10:08:18

makes all sense now

Daniel Leong13:08:25

I thought I would poke around on my nrepl issue and ran into an issue following the CONTRIBUTING.md, is it out of date?

Daniel Leong13:08:27

lein with-profiles +cljs repl
Error loading shadow.cljs.devtools.server.nrepl: Syntax error compiling at (shadow/cljs/devtools/server/nrepl.clj:1:1).
Error loading shadow.cljs.devtools.server.nrepl: Syntax error compiling at (shadow/cljs/devtools/server/nrepl.clj:1:1).
Error loading shadow.cljs.devtools.server.nrepl: Syntax error compiling at (shadow/cljs/devtools/server/nrepl.clj:1:1).
Syntax error compiling var at (/private/var/folders/9q/s674cplx7qv122xbwcchw3jm0000gn/T/form-init6039849328054616621.clj:1:10151).
Unable to resolve var: shadow.cljs.devtools.server.nrepl/cljs-load-file in this context

Full report at:
/var/folders/9q/s674cplx7qv122xbwcchw3jm0000gn/T/clojure-2400420031541069613.edn
Subprocess failed
REPL server launch timed out.
Error encountered performing task 'repl' with profile(s): 'base,system,user,provided,dev,cljs'
REPL server launch timed out.

thheller13:08:16

not sure what that is about. I start everything with that command?

thheller13:08:39

$ lein -v
Leiningen 2.9.1 on Java 11.0.2 OpenJDK 64-Bit Server VM

Saikyun13:08:05

I'm trying out react native + shadow-cljs, and I've managed to turn off live reload for the mobile, but do you know how to do it for expo web?

Daniel Leong13:08:08

lein -v
Leiningen 2.9.1 on Java 1.8.0_144 Java HotSpot(TM) 64-Bit Server VM

thheller13:08:44

@saikyun I did not try expo web at all yet so I don't know anything about that

Saikyun13:08:34

all right, thanks. it seems like shadow-cljs will work great with it -- the cljs-reload is super fast, sadly after expo (or metro?) is done "compiling" it reloads the whole page, resetting all state x)

Saikyun13:08:50

it's almost comical how I see the cljs-changes before it starts reloading

Saikyun13:08:53

lol, I "solved" it; I could just turn off the expo-process

Saikyun13:08:23

anyway, I'll come back if I find anything helpful

p-himik13:08:15

Is there any way to set optimizations to :none for {:js-options {:js-provider :shadow}}? Debugging with source maps is PITA.

p-himik13:08:49

Found this in a seemingly relevant context:

;; :whitespace or :simple work but some patterns really require the DCE done by :simple
;; eg some conditional imports done by react&friends
So apparently the answer is no. Oh well.

thheller14:08:17

yeah :simple is a must but you can use {:source-map false :pretty-print true :variable-renaming :off}

thheller14:08:30

that should be relatively close to the original

thheller14:08:46

but what are you debugging precisely?

p-himik14:08:59

Hmm. Do I just put those right in :js-options? I'm trying to debug a nice library called react-beautiful-dnd. Not sure why, but it seems that the source maps are not aligned with the source code itself - breakpoints are set on different lines, and when they hit I get a completely different context from what I'd expect. I'll try cleaning everything and rebuilding.

thheller14:08:17

source maps might be off by one line. couldn't figure out how to fix that yet

thheller14:08:03

oh and yes under :js-options

p-himik14:08:59

It seems that apart from the line numbers, the names are also off. There can be a variable x with some particular content but in the Scope panel its content resides within y. Whereas y could not possibly have such a value. But it may be an issue with V8 (I think?) optimizing some variables away. It basically removes some of the variables completely, and you cannot disable it. Drives me nuts.

p-himik14:08:04

Thanks, I'll try the options.

thheller14:08:39

if you have something reproducible I can take a look. I got some experience debugging weird JS code 😉

p-himik15:08:31

Thank you for the offer, I appreciate it. Beware though - I might just follow up on it if I get really stuck. 🙂

p-himik16:08:31

Oh... that would explain it. Check out this minified JS:

var _action$payload = action.payload;
      state = _action$payload.critical;
      action = _action$payload.dimensions;
state and action have been used before but now a piece of code const {critical, dimensions} = action.payload; has been turned into that abomination with variable reuse.

thheller18:08:58

not sure what you mean?

p-himik18:08:27

When const {critical, dimensions} = action.payload is represented as is, the Scope panel should correctly display variables named critical and dimensions. However, the above code is compiled into that snippet with var _action$payload which reuses variables. Because of that, the Scope panel now displays the value of action.payload.critical as belonging to the state variable. Of course, it is correct from the POV of the compiled code. But in this case, I can just throw away the original source code since it can't help me at all because of all the renaming and reuse.

p-himik18:08:29

I wonder - is there a way to have only DCE optimization to avoid all those issues with reuse and code shuffling in general?

thheller18:08:34

not sure, there might be config option but its not exposed if there is

thheller18:08:43

if you can reproduce the error I'm still willing to look into it 😛

p-himik00:08:02

Here's the SSCCE: https://github.com/p-himik/shadow-cljs-optimizations-test After you compile it with npm ci && shadow-cljs compile main, check the file at public/js/cljs-runtime/module$node_modules$react_beautiful_dnd$dist$react_beautiful_dnd_cjs.js and look for INITIAL_PUBLISH must come after a IDLE phase. Compare the following few lines to the code after the same string at node_modules/react-beautiful-dnd/src/state/reducer.js.

p-himik00:08:20

Note that this is not an error per se. It's just the way the CLJS compiler reuses the variables that's annoying and makes the debugging much harder due to source maps not working in this case.

thheller10:08:09

can you describe what the actual problem is though? not sure what I'm supposed to be looking for exactly?

thheller10:08:18

(no readme in repo)

p-himik10:08:24

My message with the link is basically the readme in this case. 🙂 If you mean the actual problem that I was trying to debug - that was not my intention to show it in this case. The issue is rather domain-specific and basically results from me trying to hammer a square peg into a round hole simply because there are no rounds pegs available. And I think I got it in the end - it works for now. The intention of the repo is to show how the optimizations make it much harder to debug anything for no apparent reason, even with those :js-options. Since between us you're the the only one with the relevant domain knowledge, I thought that maybe this behavior can somehow be changed, if that makes sense.

thheller10:08:19

well I can't really help if I don't know what the problem is 😛

thheller10:08:49

I can maybe enable :whitespace again for debugging purposes

thheller10:08:15

maybe thats more useful for debugging

p-himik11:08:57

OK, maybe I described it wrong. The essence of the problem is that code like const {a} = b; is compiled into something like variable_used_before = b.a; instead of just const a = b.a;. The variable reuse is what makes it hard to debug since the old value is now hidden and the name how has wrong semantics.

p-himik11:08:33

But if I understand it correctly, that's probably an issue with the CLJS compiler itself - I have no idea if Shadow-CLJS can even do anything in this case.

thheller11:08:03

the CLJS compiler is not involved in any of that at all

thheller11:08:11

it is purely done by the google closure compiler

thheller11:08:42

and the cause of that rewrite is :simple optimizations

thheller11:08:41

you are only describing that the code looks weird (which it does)

thheller11:08:51

you are not saying WHY you are looking at that code in the first place

thheller11:08:01

optimized code isn't intended to be readable

thheller11:08:24

node_modules\react-beautiful-dnd\dist\react-beautiful-dnd.cjs.js this is the file shadow-cljs uses in the first place

thheller11:08:40

so there isn't even any const use in there

p-himik11:08:24

Ah, right, thanks - I mixed up Google Closure and CLJS compilers. I guess in an ideal world the original JS files would not be changed at all for the development build, except maybe for DCE. Because e.g. the code like const {a} = b; can already be run in the modern browsers, which should probably be used for the main development workflow anyway. > you are not saying WHY you are looking at that code Because it's not relevant to the issue with the compiler itself. 🙂 "Give a man a fish" and all that. > optimized code isn't intended to be readable I agree. But because we have to run some optimizations even during development, it makes debugging hard - that's my whole point. > node_modules\react-beautiful-dnd\dist\react-beautiful-dnd.cjs.js this is the file shadow-cljs uses in the first place Oh... OK. Well const itself doesn't change anything thought - that file still got the naming correct. E.g. the relevant section has critical = _action$payload.critical which in the compiled version looks like state = _action$payload.critical. Again - there is no error here of any kind. It just makes it much harder to understand what's going on during debugging, regardless of the reason why someone is trying to understand what's going on.

thheller11:08:30

yeah whitespace would make that easier

thheller11:08:51

at the cost of losing DCE which will end up loading more code than needed

thheller11:08:03

but given that you are only doing this for debugging it probably doesn't matter too much

p-himik11:08:33

Awesome! Yes, I don't think loading extra code makes any significant difference for the development process. But it may differ for someone, so maybe making it configurable would make sense. But what about the "some patterns really require the DCE done by :simple" comment? Is there no way to somehow combine :whitespace and DCE or even have just DCE without any other optimizations?

Daniel Leong15:08:04

Hmm if I comment out the :nrepl-middleware in the :cljs profile it starts up

Daniel Leong15:08:35

Ah, also if I change the ..server.nrepl to ..server.nrepl04 in the :nrepl-middleware map

thheller18:08:08

still wonder why it works for me and on CI but not on your machine

David Pham18:08:02

@saikyun how do you turn off the expo-process?

neupsh18:08:10

@saikyun you can't turn off the live reload, but you can workaround it

neupsh18:08:50

you can block requests to /sockjs-node/* in chrome (didn't work on firefox)

tianshu18:08:20

failed to use latest expo with latest shadow-cljs

error SHA-1 for file /home/tianshu/sandbox/expo-proj/awesome/app/rn-input.android.is (/home/tianshu/sandbox/expo-proj/awesome/app/rn-input.android.is) is not computed. Run CLI with --verbose flag for more details.
node v10.16.0 shadow-cljs 2.8.45 expo 34.0.1

thheller18:08:49

@doglooksgood not sure what that is about. it is not an error from shadow-cljs

Saikyun18:08:21

@neupsh thanks for the tip 🙂

👍 4
tianshu19:08:35

@thheller just saw your reply on clojureverse. I switch to :react-native and it works great!