This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-08-21
Channels
- # announcements (1)
- # beginners (30)
- # calva (3)
- # cider (23)
- # clerk (5)
- # clj-kondo (16)
- # clojure (39)
- # clojure-brasil (3)
- # clojure-europe (19)
- # clojure-nl (1)
- # clojure-norway (54)
- # clojure-seattle (1)
- # clojure-uk (2)
- # clojurescript (9)
- # cursive (3)
- # datahike (13)
- # datomic (4)
- # emacs (7)
- # events (1)
- # fulcro (32)
- # hyperfiddle (17)
- # jobs-discuss (3)
- # meander (5)
- # missionary (132)
- # music (2)
- # nyc (1)
- # off-topic (33)
- # polylith (22)
- # proletarian (3)
- # scittle (106)
- # shadow-cljs (23)
Hi, would it be possible to configure scittle to resolve external libraries imported via <script> tags, like so?
<script src="" type="application/javascript"></script>
<script src="" type="application/javascript"></script>
<script type="application/x-scittle">
(ns my-ns
(:require [clojure.string :as str]
["@codemirror/state" :refer [EditorState]]))
...
</script>
I don't think this is possible since "@codemirror/state" refers to something external which is not known by scittle or the JS environment, right?
should work with cherry though if you stick the complete CDN url in there: https://dev.livecodes.io/?template=clojurescript
but usually when you use a script tag in this way, the script defines a global which you can then use
An example of codemirror with scittle: https://babashka.org/scittle/codemirror.html
scittle will work, but you need to access the codemirror stuff via the globals it defines (see example)
or if it only defines modules, you even need to define globals yourself:
<script type="importmap">
{
"imports": {
"codemirror": "",
"@codemirror/commands": "",
"@codemirror/search": "",
"@codemirror/autocomplete": "",
"@codemirror/lint": "",
"crelt": "",
"@nextjournal/lang-clojure": "",
"@nextjournal/lezer-clojure": "",
"@lezer/highlight": "",
"@lezer/lr": "",
"@lezer/common": "",
"@codemirror/language": "",
"@codemirror/state": "",
"@codemirror/view": "",
"style-mod": "",
"w3c-keyname": ""
}
}
</script>
<script type="module" type="application/javascript">
import * as cm from 'codemirror';
import * as lc from '@nextjournal/lang-clojure'
import * as cv from '@codemirror/view';
import * as cs from '@codemirror/state';
= cm;
= lc;
= cv;
globalThis.cs = cs;
scittle.core.eval_script_tags();
</script>
yeah I saw that... I was thinking more of keeping the cljs code as is to suit different targets (e.g. shadow)
this is a minimal example of how to compile and run: https://squint-cljs.github.io/squint/
I think you could theoretically use eval
if you would wrap it in a self-executing async function
I'm contemplating an output that is more suited for hot-reloading / nREPL, then I'd have to emit import()
instead and some global stuff where (defn foo [])
becomes the_namespace.foo = function
and then you could likely also also use eval
could sci async also support require of js modules using import maps or does it already maybe?
if you insert the right import maps in that page, dynamic import using those aliases will automatically work, this is just browser behavior
would that require a custom build of scittle, like you do with plugins? I mean to tell scittle to use the :async-load-fn
option...
yeah, it would require some (breaking) changes, but I wonder if I can accomodate both ways in one build, both have their trade-offs. Perhaps it's possible to include scittle in a second way that does it the ESM + async way
amazing this already works:
(ns scittle-build
(:require [sci.core :as sci]
[sci.async :as scia]
[scittle.core :as scit]
[shadow.esm :refer [dynamic-import]]
[scittle.impl.error :as error]))
(swap! scit/!sci-ctx
sci/merge-opts {:async-load-fn (fn [{:keys [ctx libname]}]
(.then (dynamic-import libname)
(fn [mod]
(js/console.log :require libname
:mod mod)))
{:handled true})})
(set! scit/eval-string (fn [txt]
(try
(scia/eval-string* @scit/!sci-ctx txt)
(catch :default e
(error/error-handler e (:src @scit/!sci-ctx))
(throw e)))))
with the import mapping eg. “@codemirror/state”: “https://cdn.jsdelivr.net/npm/@codemirror/state/dist/index.js”, then it can eval
(ns foo
(:require ["@codemirror/state"])
note that scia/eval-string* returns a promise, so you should handle the promise error probably
now I guess I’ll go find the 1000 implementation of the async-load-fn we did already 🙂
trying to write code once but target more build envs like shadow/scittle/squint possibly 🤞
I’m a bit confused now, it seems forms in the namespace gets evaluated before the requires are resolved (via async-load-fn), this kind of makes sense in an async setting, but how can forms refer to the required names?
I now have two tags:
<script type="application/x-scittle" src="folio.cljs"></script>
<script type="application/x-scittle" src="demo.cljs"></script>
first loads just fine, the second however doesn’t seem able to require the namespace defined by the firstit's not clear to me what you mean with "or I also copy the ns defined in the first into the sci ctx"
if you change scittle.core/eval_string
to be async, you also need to account for that in other places
I need to swap a bunch of nss into scittle.core/!sci-ctx in order for the example above to work at all
btw I wouldn't merge this since that is a breaking change, but for experimentation it's ok
once you're finished, please let me know, perhaps we can find a way to make scittle1 work with scittle async so we don't have breakages and we can have both behaviors at once
I think this will mean a new var scittle.core/eval-string-async
and perhaps a new attribute on the script tags to indicate that it's ES6 code
I think we can make eval-script-tags work with both sync and async code by just using Promise.resolve on the return value and always work in a promise-like fashion
then we'll just leave eval-string synchronous for people who already used it and introduce a new var for async evaluation
no, react isn't shipped with reagent, with scittle you provide your own react version
this means that react isn't packaged along with scittle, you need to provide your own (global) version
I didn't even use string requires there, I think I ran into specific issues so I just made it depend on a global being defined
I just did this: https://github.com/borkdude/nbb-reagent/blob/315d702436719ea3a9a356773d6a10038ce9ea75/src/reagent/dom.cljs#L9C1-L9C41
yeah, I’m seeing that, I’ll try with the string require I’m not super keen on this global stuff
Is there any specific reason to prefer sci.configs for reagent than to use sci.core/copy-ns? I see e.g. set-default-compiler!
is missing in sci.configs ?
the string require didn’t fix my issue, and also if I’m providing reagent through :namespaces
in the sci context, it will pick the one compiled by shadow right? so string requires will be sourced from npm_modules right?