This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-06-12
Channels
- # babashka (26)
- # beginners (19)
- # biff (4)
- # cider (44)
- # clerk (7)
- # clj-kondo (12)
- # clojure (25)
- # clojure-austin (9)
- # clojure-denmark (2)
- # clojure-europe (28)
- # clojure-losangeles (1)
- # clojure-nl (4)
- # clojure-norway (35)
- # clojure-spec (7)
- # clojure-sweden (5)
- # clojure-uk (6)
- # cursive (22)
- # datascript (1)
- # datomic (4)
- # dev-tooling (2)
- # events (3)
- # gratitude (1)
- # honeysql (30)
- # hoplon (6)
- # hyperfiddle (4)
- # malli (4)
- # missionary (3)
- # off-topic (2)
- # overtone (2)
- # pathom (21)
- # reitit (3)
- # releases (4)
- # shadow-cljs (32)
- # sql (22)
- # xtdb (8)
- # yamlscript (6)
In a :target :browser
build, I am setting the following options.
:js-options {:js-provider :external
:external-index "public/index.js"
:external-index-format :esm}
I am using Vite as the bundler. When I make dev builds with Shadow CLJS, the index.html needs to look like this
or else I get the error ReferenceError: goog is not defined
. However, when I make release builds, the index.html file needs to look like this
or else I get the error Uncaught SyntaxError: import declarations may only appear at top level of a module
Am I doing something wrong?its a bit confusing to answer since I don't really know what vite is doing. :browser
definitely does not output anything using import
for :target :browser
Well, unfortunately I am now simply unable to build anything, despite clearing build caches and deleting old build artifacts 😛
In the case of :target :esm
, I was facing an issue stating shadow$bridge
was undefined, even though the index.js
file contains a line like
globalThis.shadow$bridge = ...
Both the index.js
and main.js
seemed to be actual ESM output. But for some reason shadow$bridge
isnt being added to the global this object. May be some strange thing with ESM. Not sure yet. But Vite was successfully resolving dependencies declared in the index.js
file. The problems occurred as soon as main.js
was loaded and attempted to call shadow$bridge
any reason you are using :target :browser
at all? :target :esm
might be a better fit for vite?
Initially I was using :target :browser
since my build was already using that. I decided to try switching to :target :esm
in attempt to fix the (now unreproducible) issue I described at the start of this thread
the thread does not mention :target :esm
at all. it mentions :external-index-format
which is something else entirely
OK so I am testing with :target :esm
and a single main
module. Here is a snippet of the config
{:target :esm
:output-dir "public/app/js"
:asset-path "/app/js"
:modules {:main {:entries []
:init-fn
:compiler-options {:output-feature-set :es-next}
:js-options {:js-provider :external
:external-index "public/app/js/index.js"
:external-index-format :esm}}
the index.js file looks like this
import * as i0 from "react";
import * as i1 from "react-dom";
...
const ALL = {};
globalThis.shadow$bridge = function(name) {
const ret = ALL[name];
if (ret == undefined) {
throw new Error("Dependency: " + name + " not provided by external JS!");
} else {
return ret;
}
};
...
the main.js file looks like this
import "./cljs-runtime/shadow.module.main.prepend.js";
SHADOW_ENV.setLoaded("shadow.module.main.prepend.js");
...
try { my.app.init(); } catch (e) { console.error("An error occurred when calling ()"); console.error(e); }
In the browser, I see
Uncaught ReferenceError: shadow$bridge is not defined
from the file
shadow.js.shim.module$react.js:5:1
{:target :esm
:output-dir "public/app/js"
:modules {:main {:entries []
:init-fn
:compiler-options {:output-feature-set :es-next}
:js-options {:js-provider :import}}
I suspected. So I also tried setting :js-provider :import
but with no success either IIRC. I’m trying it again, with the exact same suggestion provided just now
<script type="module" src="/public/index.js"></script>
disappears and no longer exists
is the only thing remaining (or however this works so that vite processes this file. I'm assuming you are using its http server
Using your suggestions, I now have a single main.js
file with import
statements and shadow.env.SetLoaded(…)
calls. Each import successfully runs (the Network tab shows vite fetching each module). Instead I get
Uncaught TypeError: Failed to resolve module specifier "react". Relative references must start with either "/", "./", or "../".
I assume this is not a shadow-cljs error anymoreok, this seems like vite then did NOT process this file as it should have rewritten that
Your guess about processing seems to be correct. With your suggestions, I ran
npx shadow-cljs release app && npx vite build
and the CLJS app works fine. The only issue now is when using npx vite
, which is the dev modeit could be that vite just doesn't recognize the files shadow-cljs creates and it is definitely a bit of stretch calling this ESM for development builds
Looks like my bigger, more complex project, does not configure the index.html
correctly. In short, Vite looks at the script tags in your HTML in order to determine what to bundle
For anyone else looking at this thread in the future: double-check that the paths used in the tags of your
index.html
match exactly the paths you’ve configured in your shadow-cljs.edn
. Otherwise Vite will not properly discover your NPM dependencies.
Is it possible to make the HTTP server (local host:8080) available to other devices on the network?