This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-09-14
Channels
- # announcements (40)
- # aws (9)
- # babashka (21)
- # beginners (75)
- # calva (56)
- # chlorine-clover (1)
- # cider (12)
- # circleci (1)
- # clj-kondo (7)
- # cljsrn (13)
- # clojars (3)
- # clojure (171)
- # clojure-dev (11)
- # clojure-europe (64)
- # clojure-nl (11)
- # clojure-spec (6)
- # clojure-uk (9)
- # clojurescript (31)
- # conjure (1)
- # cursive (7)
- # datascript (7)
- # datomic (9)
- # emacs (4)
- # fulcro (65)
- # introduce-yourself (1)
- # jobs-discuss (7)
- # kaocha (7)
- # lsp (39)
- # missionary (5)
- # off-topic (54)
- # pathom (10)
- # re-frame (6)
- # shadow-cljs (110)
- # tools-deps (41)
Do preloads work in ~/.shadow-cljs/config.edn
?
no, build configs are not supported there. what kind of preload do you have in mind?
A coworker is using reframe 10x but I dislike it because my app-db output in the chrome console is no longer sorted. A solution I’ve thought of is two seperate builds.
one option would be shadow-cljs watch app --config-merge '{:devtools {:preloads [foo.bar]}}'
or using the clojure API to start things
@thheller Sorry for the confusion, turns out I was calling my build with the wrong alias, reloading on :local/root
works great
How do I interpret this error?
Execution error (TypeError) at (<cljs repl>:1). shadow.js.shim.module$unified.unified is not a function
Here’s a sample of the source.
(ns app.org-parser
(:require ["unified" :as unified]
["rehype-stringify" :as html]
["uniorg-parse" :as uniorg]
["uniorg-rehype" :as rehype]
["rehype-raw" :as raw]
["uniorg-extract-keywords" :refer [extractKeywords]]
shadow.resource))
(def ^:private processor
(.. (unified)
(use uniorg)
(use extractKeywords)
(use rehype)
(use raw)
(use html)))
Is there something wrong with unified such that I can’t import it?
I also tried using js/require
but that didn’t work either.
require() of ES Module /Users/main/Code/clojure/mysite/node_modules/unified/index.js from /Users/main/Code/clojure/mysite/[stdin] not supported.
Instead change the require of index.js in /Users/main/Code/clojure/mysite/[stdin] to a dynamic import() which is available in all CommonJS modules.
@c.westrom If you want to use ES modules in your project, it might be best to compile your project itself as an ES module.
@c.westrom I have an example of such a project here: https://github.com/borkdude/nbb/blob/main/shadow-cljs.edn
Note that you will likely also have to change your import to "unified$default" :as unified
after switching
@c.westrom There are currently no docs for the :esm
target, but you can read about it here:
https://clojureverse.org/t/generating-es-modules-browser-deno/6116
which is cool, then you can fully dance with the whole esm/deno ecosystem, downside is old browsers compat, but who cares 🤷 we had that curse for a decade already, time to get moving
I hope Github also moves to Node 14 or 16 for their action runners, then I can finally use nbb (ESM) for that
12 already supports it but their action runner doesn't use the appropriate --experimental flag
so I'm actually not sure what the problem is with the Github action runner: I think they're using an even older 12 version
Well, it seems like :target :esm
as an option works in the browser just fine, I’m still getting the same errors when trying to use unified though.
@c.westrom what error are you getting. Did you use script type="module"
as well?
Ah, forgot about $default
again, but after adding I get this now.
------ REPL Error while processing ---------------------------------------------
(cljs.core/load-file "/Users/main/Code/clojure/mysite/src/app/org_parser.cljs")
------ REPL Error while processing ---------------------------------------------
(ns app.org-parser
(:require ["unified$default" :as unified]
["rehype-stringify" :as html]
["uniorg-parse" :as uniorg]
["uniorg-rehype" :as rehype]
["rehype-raw" :as raw]
["uniorg-extract-keywords" :refer [extractKeywords]]
shadow.resource))
In :require [shadow.js.shim.module$unified$default :refer (unified)] already used by [shadow.js.shim.module$unified :refer (unified)]
@c.westrom I think you will also need to add $default
to the other requires btw
Ok, heavily stripped it down
(ns app.org-parser
(:require ["unified$default" :as unified]
#_["uniorg-parse$default" :as uniorg]
#_["uniorg-rehype$default" :as rehype]
#_["rehype-stringify$default" :as html]
#_["rehype-raw$default" :as raw]
#_["uniorg-extract-keywords" :refer [extractKeywords]]
;;shadow.resource
))
Here’s the result.
Execution error (TypeError) at (<cljs repl>:1).
shadow.js.shim.module$unified$default is not a function
Looking at the source for unified, it isn’t labeled as a default export, just an export.
export const unified = base().freeze()
------ REPL Error while processing ---------------------------------------------
(cljs.core/load-file "/Users/main/Code/clojure/mysite/src/app/org_parser.cljs")
------ REPL Error while processing ---------------------------------------------
(ns app.org-parser
(:require ["unified$unified" :as unified]
#_["uniorg-parse$default" :as uniorg]
#_["uniorg-rehype$default" :as rehype]
#_["rehype-stringify$default" :as html]
#_["rehype-raw$default" :as raw]
#_["uniorg-extract-keywords" :refer [extractKeywords]]
#_shadow.resource
))
In :require [shadow.js.shim.module$unified$unified :refer (unified)] already used by [shadow.js.shim.module$unified$default :refer (unified)]
cljs.user> (ns app.org-parser
(:require ["unified$unified" :as unified]
#_["uniorg-parse$default" :as uniorg]
#_["uniorg-rehype$default" :as rehype]
#_["rehype-stringify$default" :as html]
#_["rehype-raw$default" :as raw]
#_["uniorg-extract-keywords" :refer [extractKeywords]]
#_shadow.resource
))
nil
Execution error (TypeError) at (<cljs repl>:1).
shadow.js.shim.module$unified$unified is not a function
again$ nbb -e '(ns foo (:require ["unified$unified" :as u])) (.log js/console u)'
[Function: processor] {
data: [Function: data],
Parser: undefined,
Compiler: undefined,
freeze: [Function: freeze],
attachers: [],
use: [Function: use],
parse: [Function: parse],
stringify: [Function: stringify],
run: [Function: run],
runSync: [Function: runSync],
process: [Function: process],
processSync: [Function: processSync]
}
the workaround I had to do before, was compile a separate program as a node script and then import the compiled script for my site
@c.westrom Perhaps you can make a tiny repository on Github with this code
https://github.com/wildwestrom/mysite/tree/develop I was just thinking of that. I’ll make a minimal one though.
Execution error (TypeError) at (<cljs repl>:1).
shadow.js.shim.module$unified$unified is not a function
Ok, minimal project here: https://github.com/wildwestrom/minimal-unified-troubleshooting@c.westrom I am seeing: > Holy fuckeroni, is this working? I guess it is if you can see it.
but at this point, we've demonstrated that your ES module works. The rest is a tooling problem, either downstream or in shadow itself.
Alright, imma update the example. Also, here’s the separate script I made as a workaround: https://github.com/wildwestrom/uniorg-util
@c.westrom is this just for command line invocation?
cool. I think it would be a nice challenge to make this project work with #nbb as that is kind of the niche of what it's for: making scripts/CLIs with interop for node
👋 is it technically possible to reduce code splitting setup to Webpack’s Dynamic Imports experience (https://webpack.js.org/guides/code-splitting/#dynamic-imports) i.e. import("./file.js")
? Basically removing configuration step in build config. I was thinking about something like a macro that would inject modules configuration into shadow’s build state, not sure if it makes sense. cc @dazld
maybe unrelated but I've recently tried import(..)
within script type="module"
to lazy-load a shadow-cljs module. (context is to load new react page component then render after url change)
Currently hitting an issue where such import will download a shared module again, so if home
& about
module both depends on shared
module then both imports will trigger shared
module download. Which leads to duplicated cljs namespace error or even React error due to different React/ReactDOM instance kind of thing.
for your idea, I'd love see it happens 🙏 having to explicitly specify split modules is quite verbose imo, (although I think it can somehow achievable with a script that pass merge option to shadow-clja cli)
I think that effortless code splitting has an important side effect in developer engagement and reduced maintenance cost. If the tool encourages code splitting then it’s more likely that engineers would develop features in a way that defers code to later. An example would be not only splitting by route/page, but by particular component or feature that it not immediately accessible
@U0FR82FU1 FWIW I've also adopted this approach in #nbb: I lazily load code-splitted modules on demand, e.g. when someone requires reagent.core
I lazily load the reagent module using js/import
. I don't understand what you need from shadow since this is already supported?
I think he means to perform code split without having to declare modules in shadow-cljs edn confile file
Correct ^
in theory this can work but I believe the result is always worse than properly setting up your modules manually
its not that complicated and it won't just magically make an app work that isn't designed for it
there are limits to automatic splitting and you can often end up with many tiny modules which actually load slower due to the cascasding requests requiring to load them (a loads b loads c loads d etc)
FWIW if you start with https://clojureverse.org/t/shadow-lazy-convenience-wrapper-for-shadow-loader-cljs-loader/3841 you can write your code as-if you had this magic import thing and then at a later point worry about organizing your modules and tweaking them until happy
since that helper hides the actual module names and lets you focus on namespaces instead
I have a react-native app and I'm trying to introduce dynamic module loading, but keep hitting "shadow.loader API was called before shadow.loader.init!" error. I tried calling init, but it didn't change anything. Is there a particular place the init should happen?
@rosado you cannot use the shadow.loader with react-native at all. metro needs to handle the loading
https://github.com/thheller/shadow-cljs/blob/master/src/dev/demo/rn.cljs#L29 like that I guess
whereas the ./foo.js
file is created by this chunk https://github.com/thheller/shadow-cljs/blob/master/shadow-cljs.edn#L492-L494
I don't have a clue whether the js/require
is actually dynamic though. I don't use react-native and don't know what the situation there is
I want to have my public
folder in a resources
directory but whenever I make that switch my backend messes up. It says that foo
is not defined in foo.core.main()
portion of the js script in my index.html
. What I changed in my shadow-cljs.edn
file was the :output-dir
to "resources/public/js"
instead of "public/js"
, the :asset-path
to "/public/js"
instead of "/js"
and the :http-root
to "resources/public"
instead of "public"
.
your asset path needs to be "/js"
since that is the path to access the actual files over http
I'm trying to understand how I would :require npm package firebase: 9.0.1 in my code. I have tried multiple versions of "firebase/app" with :as :default and :refer. Compiler say
[BABEL] Note: The code generator has deoptimised the styling of "node_modules/@firebase/firestore/dist/index.esm2017.js" as it exceeds the max of "500KB".
And I get error in chrome saying
shadow-cljs - failed to load module$node_modules$$firebase$app$dist$index_esm2017
@fredrik245 impossible to answer without more info
what info do you need?
:client {:target :browser
:output-dir "dist/client/js"
:asset-path "js"
:modules {:main {:entries [percap.client.core]}}
:devtools {:before-load percap.client.core/stop
:after-load percap.client.core/start
:http-root "dist/client"
:http-port 8022}}
ok! thanks!
now it works!
just for future reference the important errors here were the red actual errors. the yellow one is just a warning and useful for diagnosis but not the actual error 😛
however the red errors didn't tell me much other then there is an error
but it works now. So I am happy 😃