This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
Hey, I'm trying to run shadow in a docker container but it refuses to build with AssertionError Assert failed: (cljs-util/is-file-instance? cache-root)
. Info in thread
I have a container with Clojure + Node which starts with nrepl server. I connect to nrepl and run:
user> (require '[shadow.cljs.devtools.server :as shadow-server])
user> (shadow-server/start! {:http {:port 2345}, :nrepl {:port 2346}})
May 05, 2024 7:33:47 AM io.undertow.Undertow start
INFO: starting server: Undertow - 2.3.10.Final
shadow-cljs - server version: 2.28.3 running at
shadow-cljs - nREPL server started on port 2346
:shadow.cljs.devtools.server/started
Project root now has these new files:
cli-repl.port
http.port
jar-manifest/
nrepl.port
server.pid
server.token
socket-repl.port
Then I run
user> (require '[shadow.cljs.devtools.api :as shadow-api])
user> (shadow-api/watch
{:build-id :my-build,
:target :browser,
:output-dir "build/frontend/my-build/js",
:modules
{:main
{:init-fn 'my.ns/main}}})
[:my-build] Configuring build.
[2024-05-05 07:29:20.729 - WARNING] :shadow.cljs.devtools.server.util/handle-ex - {:msg {:type :start-autobuild}}
AssertionError Assert failed: (cljs-util/is-file-instance? cache-root)
shadow.cljs.devtools.config/make-cache-dir (config.clj:169)
shadow.cljs.devtools.config/make-cache-dir (config.clj:169)
shadow.cljs.devtools.server.util/new-build (util.clj:88)
shadow.cljs.devtools.server.util/new-build (util.clj:79)
shadow.cljs.devtools.server.worker.impl/build-configure (impl.clj:195)
shadow.cljs.devtools.server.worker.impl/build-configure (impl.clj:156)
shadow.cljs.devtools.server.worker.impl/eval33643/fn--33648 (impl.clj:447)
clojure.lang.MultiFn.invoke (MultiFn.java:234)
shadow.cljs.devtools.server.util/server-thread/fn--33158/fn--33160/fn--33176 (util.clj:283)
shadow.cljs.devtools.server.util/server-thread/fn--33158/fn--33160 (util.clj:282)
shadow.cljs.devtools.server.util/server-thread/fn--33158 (util.clj:255)
java.lang.Thread.run (Thread.java:1570)
:watching
The expected JS file is not built.
I have published ports 2345, 2346 and my container's working directory /usr/app is mounted to my project's root. I can see localhost:2345/dashboard . Build tab contains zero information. localhost:2346 is not accessible.
When I stop the server I am left with only these files:
jar-manifest/
server.pid
server.token
I think those generated files should sit in .shadow-cljs, so maybe something went wrong there?I'm guessing something in your docker setup is messed up? which directories do you mount (or whatever thats called in docker)
my local project root is connected to container's /usr/app
which is where the main nrepl is started, that's it.
and is there any shadow-cljs.edn
file? maybe one actually trying to set :cache-root
?
None, I only use those 2 commands I mentioned before. Perhaps I am not providing enough information to those functions?
Yeah nrepl is also started in the same container and it is working fine.
That is a non-shadow nrepl
the directory the process is started in is used in a lot of places, so it that is a different directory than where the files are actually located that may lead to issues
Does that mean I have to change my current working directory to another place before starting the server?
I suppose try (shadow-server/start! {:cache-root ".shadow-cljs" :http {:port 2345}, :nrepl {:port 2346}})
frankly working without a shadow-cljs.edn
isn't really supported, so you will likely run into all sorts of issues
yes, it's the project root. (clojure.java.shell/sh "pwd")
returns "/usr/app"
which is the expected location.
Specifying the cache root explicitly did the trick, thanks for the help!
I suspect the issue comes from the fact that if the config is passed explicitly then no defaults are applied. If start!
is run w/o args then the loaded config goes through config/normalize
, merged on config/default-config
and additional attributes are added.
If others people would find this kind of info useful, I could contribute to the shadow user guide.
whats your reason for not having a shadow-cljs.edn? I mean you are sort of fighting the system by not having it?
I want to build several independent pages and if I used shadow-cljs.edn directly, I would have to duplicate the information because each page has a similar build config + I want to use that information in another build stage.
otherwise the amount of overhead is going to be gigantic? you'll probably want code splitting instead?
They are independent pages, if one user is going to look at 1 page, they are not that likely to look at another which is why they have to be independent. I could be making each page as a separate project but I tend to reuse several components and it's nicer to have everything in one project. It is an odd setup but it works quite fine so far.
well, you could still have a shadow-cljs.edn for generic stuff and just put the builds elsewhere
I would still need shadow to make that final js and define a build config eventually, no?
then do your builds as you are currently doing, as-in not defined in shadow-cljs.edn, which is what I define as elsewhere. I do not mean use something else to compile.
Oh yeah, that could also work
Thanks for the comments, appreciate all the help you provided so far!
hey all, I have a problem with large bundle (~16MB)
Im running shadow using :external
js provider (with webpack). Running shadow in release
I have set webpack in production
mode.
Looking at webpack analyser, I see that some of the modules (both ours and 3rd party) are concatenating the node modules.
I think that some settings are misconfigured, but I'm not sure where to look for.
I'm also using icons from fortawesome, importing them individually, but it still seems to import all of them (tree shake doesn't work)
:app {:target :browser
:modules {:main {:init-fn main.main/init}}
:build-hooks [(dev.core/rcf-shadow-hook)]
:js-options {:js-provider :external
:external-index "target/index.js"
:ignore-asset-requires true}}
module.exports = {
mode: "production",
entry: "./target/index.js", // Entry point for your application
output: {
filename: "libs.js", // Output bundle file name
path: path.resolve(__dirname, "public/js"), // Output directory
},
resolve: {
extensions: [".js", ".mjs"], // Allow importing both .js and .mjs files without specifying the extension
},
plugins: [new Dotenv()],
module: {
rules: [
{ test: /\.json$/, type: "json", use: ["json-loader"] },
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
test: /\.m?js/,
type: "javascript/auto", // Treat .mjs files as JavaScript modules
resolve: {
fullySpecified: false,
},
},
],
},
};