shadow-cljs

https://github.com/thheller/shadow-cljs | https://github.com/sponsors/thheller | https://www.patreon.com/thheller
wombawomba 2020-11-10T09:19:37.427500Z

I'm trying to import an ES module (https://github.com/otakustay/react-diff-view — via :require [react-diff-view :refer [parse Diff Hunk]]) that shows up as empty (i.e. (js/console.log react-diff-view parse Diff Hunk) gives me {__esModule: true} undefined undefined undefined). Any idea what's causing this or what could be done about it?

wombawomba 2020-11-10T09:43:21.427800Z

Alright, I was able to figure this out by importing the library in a REPL. Apparently there was an error due to a mismatch in React versions.

wombawomba 2020-11-10T09:48:17.428Z

FWIW the note at the end of https://shadow-cljs.github.io/docs/UsersGuide.html#_using_npm_packages about using a REPL was very helpful. I had originally skipped over it because it's in the default exports section and I wasn't using those — might be a good idea to put it in a more prominent place?

raymcdermott 2020-11-10T10:12:07.429Z

is it possible, (using the support for git in NPM) to rely on a git repo SHA rather than a published package?

raymcdermott 2020-11-10T10:12:22.429500Z

[ I can’t find it in the book ]

2020-11-10T10:45:29.436Z

Are Shadow-cljs builds intended to be deterministic? I read that the Google Closure Compiler itself is deterministic, but my builds always seem to include large-%age changes to files which haven't changed from release to release (eg cljs.core.js). Looking at the first example in a diff, the differences can be something so trivial as: var p=$CLJS.zh;this.ri=p instead of this.ri=$CLJS.zh 😕 So I'm wondering where the extra entropy in my builds is coming from!

thheller 2020-11-10T11:04:09.438Z

@raymcdermott whatever npm installs will be used and I think you can use something like github:foo/bar#commit instead of a version number. whether that works entirely depends on the npm package though. most of them require a build step so using them from source-only usually doesn't work.

1
thheller 2020-11-10T11:06:25.440Z

@mel.collins builds are not really deterministic and really can't be if you factor in DCE. any change you make may lead to something in cljs.core staying alive or being removed. :advanced output must be used as one contained unit and cannot be mixed with output from other builds.

2020-11-10T11:32:45.447600Z

@thheller My intent isn't to split builds in this case - the compiled JS gets committed to git (primarily to enable using the git repo as a dependency elsewhere), and it bothers me that every release has so many changes to the compiled source. Even running shadow-cljs release npm twice in a row produces different output each time, so it's definitely not (only) a DCE thing. It would be nice to have IMO, but if reproducible builds isn't a design goal for shadow-cljs then I can stop concerning myself with it!

thheller 2020-11-10T12:16:25.449900Z

well here it comes to definitions. reproducible of course that is a goal. 100% binary identical is not. half of the "blame" here also goes to the closure compiler so not much to do about that. the CLJS compiler and macros also use gensym quite frequently so thats also not deterministic.

2020-11-10T15:34:22.450300Z

Fair enough, thanks for the info

oliver 2020-11-10T20:57:39.450800Z

Hi everyone! I'm currently working through Dmitry Sotnikov's book on Luminus: His approach is to distinguish builds (production, development) by varying the source-paths in order to load code selectively. For ClojureScript he accomplishes this by integrating shadow-cljs with Leiningen. Since I'm using boot (and the shadow-cljs guide seems to discourage integration with lein/boot/cli anyway) I'd like to achieve the same thing using shadow-cljs separately. The guide, however, states “the source path is only specified once in the entire configuration.” So I guess there's no way to include different versions of namespaces for different builds using standalone shadow-cljs. If I want, say, three different flavors of my app with different environment settings, where would I start?

thheller 2020-11-10T21:02:11.452300Z

you can only do so by using lein or deps.edn. shadow-cljs.edn does not and will not support it.

thheller 2020-11-10T21:02:43.452800Z

I personally don't like that approach and have never used it myself

oliver 2020-11-10T21:11:31.457900Z

Many thanks for the quick reply! Given what I've been able to piece together on the Internet I'm not even all that surprised (or disappointed ). Seems this is more opinionated than I thought… Is there any other native way to distinguish between more environments than just :dev and :release? (I know how to set variables for these with :closure-defines, but wouldn't know how to define a third one)

thheller 2020-11-10T21:12:35.458800Z

first you need to differentiate between BUILD configuration and RUNTIME configuration. you are most likely talking about runtime configuration which IMHO should not be in the build config at all.

thheller 2020-11-10T21:12:48.459300Z

that is my approach and that is how shadow-cljs is set up basically

thheller 2020-11-10T21:13:12.459900Z

so I never had a need to define anything other than :dev or :release and as such is not supported

thheller 2020-11-10T21:13:30.460300Z

you can always use --config-merge to override stuff if you want though which sort of gets you whatever you might need with regards to :closure-defines etc

oliver 2020-11-10T21:29:51.462100Z

Alright, I have read that chapter in the guide… in any case: I'm much clearer now as to what's in the cards. (Actually I've never used a build tool prior to my Clojure days, so I'm still trying to figure out the best way of doing things… so far shadow-cljs is the one one I understand best…) Many thanks for your swift help on this occasion (and previous ones)…

thheller 2020-11-10T21:30:56.462800Z

don't get sucked into too many configuration details. most of the time simple configs are enough for even complex projects.

oliver 2020-11-10T21:34:02.463300Z

Thanks I'll try to keep that in mind!

2020-11-10T22:04:46.465300Z

Any way to ignore The required JS dependency "&lt;npm-package&gt;" is not available, it was required by ..., I’m porting pretty large js codebase and they seem to be not having using the code in <npm-package> ...

2020-11-10T22:06:10.466500Z

btw. <npm-package> is a transitive dependency somewhere, I tried to add it by hand, but that leads to another issue with incompatible react versions required by different packages

2020-11-10T22:23:02.467300Z

ah, nevermind, it looks like yarn did the right job and installed all npm packages from transitive dependencies, not sure why npm didn’t do that

dpsutton 2020-11-10T22:26:39.468200Z

it kinda sounds like the dependency set is unsatisfiable if trying by hand gives incompatible react versions. i wonder if npm is doing the right thing and yarn is doing a thing that is wrong but relied upon?

2020-11-10T22:51:11.469100Z

now, I have a different problem, shadow-cljs complains The required JS dependency "use-cannon" is not available but I’m sure it is in node_modules/use-cannon, and package.json there properly points to compiled index.js file

2020-11-10T23:03:06.471800Z

uhmm, I’m not familiar with npm stuff, turned out the package.json contains only module key and has no main key[1]. I renamed module to main and shadow-cljs started working as expected. Quickly googled this[2] Maybe shadow-cljs should warn and fallback to module? [1] https://github.com/pmndrs/use-cannon/blob/cf8a7482ed9eb8dfc2f39a58bec5b8027caee542/package.json#L16 [2] https://stackoverflow.com/questions/42708484/what-is-the-module-package-json-field-for

thheller 2020-11-13T10:50:56.012600Z

btw I missed this. you can set :js-options {:entry-keys ["module" "browser" "main"]} to make it use module by default. it isn't in the list by default since mixing commonjs and ESM is PITA. in the next release it'll use module last just in case neither browser or main are set.