Fork me on GitHub
#shadow-cljs
<
2023-02-08
>
hifumi12303:02:20

Is there a way to make changes in environment variables invalidate shadow-cljs cache? At the moment I am resorting to adding a namespace to my :cache-blockers , but I’m wondering if there is a more elegant way to handle this. In short, my configuration has a few :closure-defines like so

:closure-defines
{foo.bar/const #shadow/env ["FOO_BAR" "BAZ"]}
I’ve noticed that running npx shadow-cljs release target once then running FOO_BAR=QUUX npx shadow-cljs release target will give me a bundle with the older environment variable set, unless I delete cache in between builds. Maybe finding a way to set :cache-level to :off in release builds is what I want?

thheller06:02:11

are you running the release when a previous server is already running?

thheller06:02:20

env vars are only picked up if a new process is started

thheller06:02:30

so either make sure the server is stopped before that

thheller06:02:45

or use FOO_BAR=QUUX npx shadow-cljs release target --force-spawn

hifumi12306:02:20

There wasn’t a server running beforehand, but invalidating caches would ensure changes would be reflected in the compiled bundle. The problem appeared when I would run npx shadow-cljs compile target multiple times, yet I didn’t see :closure-defines update in the app. Then out of sheer luck I tried a release build and everything worked; then I suspected my compilation caches were messing with things

thheller06:02:11

env variables are used from the started server, so if you don't restart that they are not picked up

thheller06:02:36

:closure-defines are also not cached, so nuking the cache doesn't have any effect

thheller06:02:57

if you want to be sure don't use env variables at all

thheller06:02:37

lets you set whatever directly without the env indirection

Shuai Lin06:02:12

@thheller another ESM related issue: when I 1) use :js-provider :import and 2) have a classpath ESM that makes uses of a npm ESM pkg (`promsemirror-state` in the repro below) then advanced compilation would fail with Required namespace "esm_import$prosemirror_state" never defined. Repro is here https://github.com/lins05/my-repros/tree/master/repro-shadow-cljs-advanced-using-npm-esm

thheller06:02:38

might be the same issue as :npm-module, I'll check it out

Shuai Lin06:02:26

Thx! To be accurate, npm-module is only warning, but this completely fails the release build

alexdavis14:02:18

I want to be able to build several versions of my app, each with different :closure-defines values. At the moment I am duplicating everything for each build, so

:builds {:env1 {:target :browser
                 :compiler-options {:output-feature-set :es-next
                                    :closure-defines {app.foo/BAR "baz1"}}
                 :modules {:main {:init-fn app.core/init}}
                 :output-dir "public/js"
                 :asset-path "/js"
                 :dev {:closure-defines {"re_frame.trace.trace_enabled_QMARK_" true}}
                 :devtools {:http-root "public"
                            :http-port 3900
                            :preloads [devtools.preload
                                       shadow.remote.runtime.cljs.browser]}}
          :env2 {:target :browser
                 :compiler-options {:output-feature-set :es-next
                                    :closure-defines {app.foo/BAR "baz2"}}
                 :modules {:main {:init-fn app.core/init}}
                 ...
Is there a way to share things between these different builds? or maybe a better way to inject variables for different builds?

Mario Trost14:02:17

There is --config-merge to use from the command line https://shadow-cljs.github.io/docs/UsersGuide.html#config-merge (edit: wrong link)

alexdavis14:02:49

ah thank you! I thought I'd read the guide but obviously not carefully enough 😞

thheller16:02:17

any cypress testing enthusiasts arround?

lilactown18:02:19

we use cypress at work with shadow.

lilactown18:02:33

I've written my share of cypress tests as well

thheller19:02:37

tests are written in CLJS? do you use component testing or e2e?

thheller19:02:59

do you use macros to make syntax nicer or just plain JS interop?

lilactown19:02:08

tests are written in CLJS

lilactown19:02:50

we use a mix of interop and helper functions, no macros

lilactown19:02:58

ah we do use mocha-latte for writing tests https://github.com/contentjon/mocha-latte

lilactown19:02:35

we only do e2e testing. for component tests, we use react-testing-library. again just with helper functions and interop

thheller20:02:34

so I assume its done via :npm-module build and running through the built-in webpack?

lilactown20:02:54

that's right

lilactown20:02:51

the way we do it is a bit strange, I didn't set it up, but it works. we write the CLJS output to a dir in node_modules, and then we have a JS file for each test ns that requires it. e.g. we have a namespace amperity.cypress.integration.databases and then a cypress/integration/databases.spec.js which contains a require

require("amperity-cypress/amperity.cypress.integration.databases");
and cypress watches that dir and rebuilds when the node_module/amperity-cypress code changes

thheller20:02:26

interesting