Fork me on GitHub

@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 ?


or maybe my version of shadow-cljs is old


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


wasn't aware there were usable alternatives


can add a check if needed though


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


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


as long as it works it's all fine


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.


here's from mac

cat tests/tests.first_test.js
test("Adds 1 + 2 to equal 3",(function (){
return expect(((1) + (2))).toBe((3));


and here is from (likely) cached linux

var $CLJS = require("./cljs_env");
var $jscomp = $CLJS.$jscomp;
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=$ || ($ = {});
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 = {});


test("Adds 1 + 2 to equal 3",(function (){
return expect(((1) + (2))).toBe((3));

module.exports = tests.first_test;



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


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


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


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


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


the source files that are generated have changed


so comparing them the old stuff is pointless


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


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


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

"testMatch": [
is my matcher


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


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


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


I still don't get what you are doing


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


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


we were doing

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


uhm you are using some old setup?


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


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


it was never meant for you to be used that way


if you want to use this that way


just switch to :npm-module target


but then source maps still won't work


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


for them to work I had to switch the output format


which is why everything is now in index.js itself


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


they aren't actually used for anything


only index.js matters and contains all code


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


yes, exactly


that output will still behave as before


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, 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:
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.


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


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


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


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


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)


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


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


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


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


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.


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


that should be relatively close to the original


but what are you debugging precisely?


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.


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


oh and yes under :js-options


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.


Thanks, I'll try the options.


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


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


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.


not sure what you mean?


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.


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


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


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


Here's the SSCCE: 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.


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.


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


(no readme in repo)


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.


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


I can maybe enable :whitespace again for debugging purposes


maybe thats more useful for debugging


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.


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.


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


it is purely done by the google closure compiler


and the cause of that rewrite is :simple optimizations


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


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


optimized code isn't intended to be readable


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


so there isn't even any const use in there


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.


yeah whitespace would make that easier


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


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


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


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?


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


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


failed to use latest expo with latest shadow-cljs

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


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


@neupsh thanks for the tip 🙂

👍 4

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