Just wanted to try and I cloned an existing project changed to :esm(https://github.com/minimal-xyz/minimal-shadow-cljs-esm)
=>> yarn watch
yarn run v1.22.1
$ shadow-cljs watch app
------------------------------------------------------------------------------
shadow-cljs - config: /Users/chen/repo/minimal-xyz/shadow-cljs-esm/shadow-cljs.edn
shadow-cljs - HTTP server available at http://localhost:8080
shadow-cljs - server version: 2.10.10 running at http://localhost:9630
shadow-cljs - nREPL server started on port 63013
shadow-cljs - watching build :app
[:app] Configuring build.
[:app] Compiling ...
[:app] Build failure:
FileNotFoundException: target/cljs-runtime/cljs_env.js (No such file or directory)
java.io.FileOutputStream.open0 (FileOutputStream.java:-2)
java.io.FileOutputStream.open (FileOutputStream.java:270)
java.io.FileOutputStream.<init> (FileOutputStream.java:213)
clojure.java.io/fn--11498 (io.clj:230)
clojure.java.io/fn--11498 (io.clj:230)
clojure.java.io/fn--11435/G--11404--11442 (io.clj:69)
clojure.java.io/fn--11472 (io.clj:166)
clojure.java.io/fn--11472 (io.clj:166)
clojure.java.io/fn--11448/G--11400--11455 (io.clj:69)
clojure.java.io/writer (io.clj:119)
clojure.java.io/writer (io.clj:104)
clojure.core/apply (core.clj:667)
clojure.core/spit (core.clj:6954)
clojure.core/spit (core.clj:6954)
shadow.build.targets.esm/flush-dev/fn--24763 (esm.clj:346)
shadow.build.targets.esm/flush-dev (esm.clj:342)
shadow.build.targets.esm/flush-dev (esm.clj:338)
shadow.build.targets.esm/process (esm.clj:432)
shadow.build.targets.esm/process (esm.clj:418)
clojure.lang.Var.invoke (Var.java:384)
shadow.build/process-stage/fn--12932 (build.clj:162)
shadow.build/process-stage (build.clj:159)
shadow.build/process-stage (build.clj:151)
shadow.build/flush (build.clj:475)
shadow.build/flush (build.clj:469)
shadow.cljs.devtools.server.worker.impl/build-compile (impl.clj:365)
shadow.cljs.devtools.server.worker.impl/build-compile (impl.clj:345)
shadow.cljs.devtools.server.worker.impl/fn--14268 (impl.clj:440)
shadow.cljs.devtools.server.worker.impl/fn--14268 (impl.clj:429)
clojure.lang.MultiFn.invoke (MultiFn.java:234)
shadow.cljs.devtools.server.util/server-thread/fn--14045/fn--14046/fn--14054 (util.clj:285)
shadow.cljs.devtools.server.util/server-thread/fn--14045/fn--14046 (util.clj:284)
shadow.cljs.devtools.server.util/server-thread/fn--14045 (util.clj:257)
java.lang.Thread.run (Thread.java:748)
The first time it threw an exception that was a little different(not copied..) but as I try again and again I still get this error.
Nothing generated yet.
=>> tree target/
target/
0 directories, 0 files
Oops... fixed with
mkdir target/cljs-runtime/
Turned out it's meaningless to add :devtools in this mode?
Ah, forgot to create the directory properly. Fixed in 2.10.11.
Which :devtools are you refering to?
Which :devtools are you refering to?
I thought for a while it could be a replacement for browser(since using init-fn) so It might do hot swap as I edit cljs files. Turned out nothing happened... then I realized the code loads via import, which is different from original :browser target.
I added :after-reload here:
https://github.com/minimal-xyz/minimal-shadow-cljs-esm/blob/master/shadow-cljs.edn#L9
I browsed network and the frontend is aware of new builds. :after-load is supposed to be called right? (I'm not sure...
Use the metadata hints instead. :devtools :after-load is ancient history by now and shouldn't be used.
I added ^:dev/after-load and tried again. I think it's not working.
I'm using :after-load for too long already. If it's not supported anymore, then there should be a deprecation log.
Right. Guess I should have actually tested this before. Should be sort of working in 2.10.12. It does however have certain limitations that won't currently work. Mostly arround hot-reloading ESM imports and exports also won't be updated.
I'll try to document that somewhere later.
It's working now.
馃槄 Luckily :after-load still works, I have too many small repos and feel afraid of migrating all of them.
Its fine to keep it in old repos. Just don't put it into new ones.
guess you also need to review this https://github.com/shadow-cljs/shadow-cljs.org/blob/master/markdown/introduction.md in case there're other deprecated features. :after-load has been on the page for long while.
emm... is manifest file supported yet?
:release {
:output-dir "dist/", :module-hash-names 8
:build-options {:manifest-name "assets.edn"}
}
No and probably won't be.
I'd suggest using a custom :output-dir. For example in Deno each "release" will be put into a directory for its version
https://deno.land/[email protected]/http/server.ts
So I'd recommend shadow-cljs release app --config-merge '{:output-dir "foo/1.0.0"}' or so. Hashes and all that stuff are just annoying to deal with from every single perspective.
I don't agree that adding versions into path is a good idea. With hash name and manifest.edn we have a simpler way to ensure js assets get refreshed when changed and cached when unchanged, in the webpack days. I'm not sure how it would work for days of ES6 files and HTTP2, not learnt or explored yet. ES6 target from shadow-cljs feels like an unknown area, I want to try it and it might be interesting, but uncertain why I want it or whether I can really make use of it. :browser target looks somehow good enough enough except for the annoying enormous <script/> tags.
You don't have to use the version. You could use your git-sha or any random uuid. Point is that you use something you control. I haven't use the :module-hash-names for years and wouldn't recommend to use it. Too much hassle to ensure it is passed everywhere. If you just choose a unique name for the output dir everything is much easier and ensures that caching works equally well.
I'm not sure. I'm just following some habits from my webpack projects. shadow-cljs uses EDN which less customizable than webpack which is using bare js, solutions are limited. So I most following old paths. And also not sure how other shadow-cljs users consider this. Anyway I'm just trying randomly, I will stick to :browser target for most cases.
This isn't meant to replace :browser in any way. It is a more modern version of :npm-module. Do not use it unless you know that you need ESM (eg. integrating with other ESM code that can't be part of the main build).