Fork me on GitHub
#shadow-cljs
<
2020-04-08
>
Aron06:04:15

Hi. Can I use :compiler-options :output-to to specify a relative path for the production build script with :target :browser ?

Aron06:04:51

I realize I can just move the file with a separate shell command but it would be much neater to be able to specify the file name

Aron06:04:17

instead of having to use the namespace (which means atm I get main.js, but I guess that will change too)

Chris McCormick07:04:53

@ashnur can you use :release {:output-dir "build/js"}? I only learned of this option recently myself.

Aron08:04:32

@chris358 @thheller does :output-dir change the outputted file's NAME?

Aron08:04:57

if so, it's quite terribly named

Aron09:04:43

no, actually, I get an error that the path is not a directory

thheller09:04:59

no. you control that name via :modules {:main ...}

thheller09:04:04

:main becomes main.js

Aron09:04:18

I don't follow

thheller09:04:28

:output-dir specifies which directory the files are written to

Aron09:04:14

right, but I am asking how to have a specific filename for the production build

Aron09:04:17

'path' for me means 'dir' + 'filename', maybe terminology discrepancy

thheller09:04:26

why does it have to be different for your production build?

Aron09:04:54

because that is my goal for today

Aron09:04:12

at the moment 🙂

thheller09:04:22

weird goal ...

thheller09:04:34

the way this works in shadow-cljs is that you specify an :output-dir

Aron09:04:37

why so judgmental? :D

thheller09:04:43

all files are written into that directory

Aron09:04:54

so I can't change from shadowcljs this

thheller09:04:58

it should be exclusively for files compiled by shadow-cljs

thheller09:04:11

each module creates one file, named by the module name

thheller09:04:14

that is the assumption

Aron09:04:15

thanks, i will just use another process externally to move the files to their appropriate place with their appropriate name then

thheller09:04:17

it is hardcoded

thheller09:04:19

you cannot change it

Aron09:04:27

I thought I can use shadowcljs for build stuff

thheller09:04:52

not sure what you mean by appropriate

Aron09:04:07

intended

thheller09:04:18

if you want main-production.js or whatever it is advised to use a different directory for ALL files

thheller09:04:38

so /js/compiled/main.js or /js/dev/main.js or whatever

Aron09:04:55

sure, that's not a problem, but I still can't change the filename, just because other files are there too

thheller09:04:13

I really do not understand your problem?

Aron09:04:18

as it stand, I still need something else externally to find the file and rename it, so I need additional tooling

thheller09:04:23

you can change the name by changing the module name?

thheller09:04:36

:modules {:main ...} becomes main.js. :modules {:foo ...} becomes foo.js

Aron09:04:37

but that's the module name, not the filename

thheller09:04:45

THAT IS THE FILENAME!

Aron09:04:56

sorry, I don't want to frustrate you : (

Aron09:04:17

clearly I misunderstand something, it's not my intent to cause trouble

thheller09:04:58

I explained as best I can. It is a hardcoded assumption that cannot be changed.

Aron09:04:35

This is what I took that 'hardcoded, can't be changed -> filename must be the same as the namespace'

Aron09:04:39

Is this not correct?

Aron09:04:18

and it's not

Aron09:04:49

@thheller you explained well, but I misunderstood, {:output-dir "../dist" :modules {:new-filename {:init-fn app.core/main}}} creates ../dist/new-filename.js I am sorry for being thick headed at first

Aron09:04:55

now my only worry is that shadowcljs might overwrite something, but "luckily" production build assets are also in git so at least it's visible if it happens 🙂

thheller09:04:29

as I said it is recommended that shadow-cljs owns that directory completely

thheller09:04:42

so use :output-dir "../dist/js" or so

Aron09:04:00

but I can't do that

Aron09:04:28

it would mean that I have to rewrite gazzillionn legacy stuff in a huge django project that's over 8 years old that uses dist to publish everything

Chris McCormick00:04:50

ashnur I have ClojureScript (shadow-cljs) working along side Django successfully. I managed to get it working through judicious use of the static folders sytem of Django where multiple folders are seen by the browser as a single folder. Ping me if you need more details or my config.

Chris McCormick00:04:06

Basically while you are dev'ing on local one version of your .js file is used from the dev folder as it has static-files precedence, whilst on live the committed version is used instead.

Aron03:04:33

I just woke up, it's 4:10 AM : ) Just to explain why I didn't ask immediately. This sounds very useful, I can manually configure both the dev and the prod files and what is committed is going to get published (by hand), but something that requires less attention and is less error-prone would be nicer

Chris McCormick23:04:41

@ashnur my setup is as follows: the cljs project is in a folder called ui at the top level. its shadow-cljs.edn specifies :output-dir "static/dev/admin-ui" (note the "dev" folder). I have :release {:output-dir "static/admin-ui"} (note the lack of "dev". Then in my Django settings:

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATIC_DEV = os.path.join(BASE_DIR, "ui", "static", "dev")
STATICFILES_DIRS = []
if os.path.isdir(STATIC_DEV):
    STATICFILES_DIRS += [STATIC_DEV]
STATICFILES_DIRS += [os.path.join(BASE_DIR, "ui", "static")]
What this does is cause /static/ to resolve files in ui/static/dev and also in ui/static and the "dev" variant only exists on my local while running npx shadow-cljs watch app. It never appears on the live site. Note that ui/static/dev and ui/static appear to be overlayed, so if you request /js/main.js it will first look relative to the dev folder, and then look relative to the other non-dev folder.

Aron02:04:02

this is almost funny, twice in a row is a pattern : ) Thanks for the config, I shall try it right away

Aron02:04:58

It's a bit more complicated because I am trying devcards, so those need a place too, but I don't want to build them for productions, and tests that I do want to build for production.

Aron03:04:06

Ok, so the trick really is in the static resolution order in django, using /dev/ when there is one instead of always using the prod version which might exist during dev time too

thheller09:04:56

"everything" but not subdirectories?

Aron09:04:03

I am trying to sneak in something on the back door, if I have to work on this 2 weeks just to get the paths right (you can see how slow I am, I am not exxargerating), it will not work : )

Aron09:04:21

no, I mean, there are already paths pointing to this filename I am writing

Aron09:04:42

of course it would get published in a subdirectory too, you are entirely correct in everything you said 🙂

thheller09:04:10

yeah as soon as you said legacy stuff I understood 😛

Aron09:04:31

thanks, next time I will lead with that then : )

Aron09:04:29

in like 8 years since I've been trying to use clojure(script) for work, this is the first time I think I will succeed, it's thrilling

🎉 8
yenda12:04:17

I'm switching a cljs react-native project from lein/clj/clj-rn to shadow-cljs. I got the dev and build working but I'm struggling with the tests. Previously the react-native libs were mocked by importing dependencies in a namespace. That namespace would be at different source path, one for the project code with requires, and one for the test with mocks of the functions that are called in tests. Now with shadow-cljs since the imports are made directly in the require I'm not sure how to proceed to mock these imports

thheller12:04:34

not sure I understand the setup, will need to see some code I'm afraid 😛

yenda12:04:13

sure do you want the old setup or the new one?\

thheller12:04:21

so the tests are running completely without any react-native involvement?

yenda12:04:03

yes they are just meant to test the logic and react-native effects are mocked

yenda12:04:00

most of the time they don't even happen because most tests are testing the map of effects outputed by events without applying them (so no effects occur)

thheller12:04:10

so how does the code look now?

thheller12:04:09

or do the sources access the react-native deps directly?

yenda12:04:23

yeah they access the deps directly from require

yenda12:04:07

this ns was the mock, in any case I couldn't use the same method with shadow since you can't define different src-path for different builds, which was how it worked

thheller12:04:21

thats not entirely true

thheller12:04:42

shadow-cljs allows aliasing namespaces

yenda12:04:08

that is the original namespace

thheller12:04:25

so you can use the mocked ns and call it (ns status-im.react-native.js-dependencies-mock)

thheller12:04:02

then in your build config use :build-options {:ns-aliases {status-im.react-native.js-dependencies status-im.react-native.js-dependencies-mock}}

thheller12:04:20

that would make every namespace that references the js-dependencies use the mock instead

thheller12:04:21

if each ns has the requires directly you can use the :resolve option to mock things https://shadow-cljs.github.io/docs/UsersGuide.html#js-resolve

thheller12:04:56

or use :js-options {:js-provide :require} (assuming its a :browser) build and provide your own require fn that returns the mocks

thheller12:04:35

so something like <script>window.require = function(name) { if (name == "foo") { return {} } else ... }; </script>

thheller12:04:58

can of course write that in CLJS also

thheller12:04:28

plenty of ways to mess with this 😛

yenda12:04:36

ideally I'd like to keep the requires directly in the ns declaration "shadow style", and keep the tests as vanilla cljs as possible so I'll look at js-options and js-resolve

thheller12:04:37

resolve will be rather verbose and since you are likely going to override all of them it might be better to just create a custom require fn

thheller12:04:21

its typically meant for single rewrites like react -> preact or so

felipethome17:04:36

Hi! I’m having an issue when using schema-generators along with shadow-cljs. If I use clojurescript version 1.10.520 with shadow <= 2.8.83 everything works. If I bump clojurescript to version 1.10.597, or keep the version 1.10.520 but bump shadow-cljs to 2.8.84 I start to get the error Couldn't satisfy such-that predicate after 10 tries when trying to generate a schema. I’m asking for help here because if I use clojurescript version 1.10.597 and the cljs.build.api everything works fine. Do you have any clue about what may be happening? I thought it could a dependecy issue, but I compared both dependency trees (printed with lein deps :tree) and the tree using version 2.8.83 and 2.8.84 are identical (with exclusions loom pathom and core.async). Maybe I’m missing something when checking the dependencies. I have a sample project reproducing the issue at: https://github.com/felipethome/sg-issue

thheller17:04:55

make sure you get these versions

[com.google.javascript/closure-compiler-unshaded "v20191027"]

   [org.clojure/google-closure-library "0.0-20191016-6ae1f72f"]
   [org.clojure/google-closure-library-third-party "0.0-20191016-6ae1f72f"]

thheller17:04:00

looks like you don't have those

felipethome17:04:52

Still the same problem here

thheller17:04:14

sorry don't have time to look at that further

thheller17:04:21

try without lein

felipethome17:04:54

Unfortunately I can’t stop using lein at this moment. Thank you! I will try to investigate more

Prometheus17:04:55

Is it possible to specify different configs before build for

shadow-cljs watch app
And
shadow-cljs release app
I different config-variables for each environment. On the serverside I use yogthos/config with lein. And I simply specify which profile to use.

Prometheus17:04:23

So you do it directly in shadow-cljs.edn?

Prometheus17:04:37

That’s a little bit to awesome for my taste Mr @thheller 🙏 You sir are a legend, and so is shadow-cljs

Prometheus17:04:57

How do I access the config variables inside my cljs files?

Aron19:04:41

i have not been this happy for months

Aron19:04:44

everything just works

parens 24
Chris McCormick00:04:50

ashnur I have ClojureScript (shadow-cljs) working along side Django successfully. I managed to get it working through judicious use of the static folders sytem of Django where multiple folders are seen by the browser as a single folder. Ping me if you need more details or my config.