This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-10-06
Channels
- # aleph (70)
- # announcements (9)
- # babashka (43)
- # babashka-sci-dev (6)
- # beginners (97)
- # cider (2)
- # clj-commons (3)
- # clj-kondo (41)
- # clojure (88)
- # clojure-europe (44)
- # clojure-nl (2)
- # clojure-spec (22)
- # clojurescript (65)
- # community-development (6)
- # conjure (10)
- # cursive (6)
- # datahike (13)
- # datomic (4)
- # eastwood (11)
- # events (1)
- # fulcro (45)
- # graalvm (1)
- # graphql (3)
- # hyperfiddle (3)
- # integrant (7)
- # jobs (1)
- # lambdaisland (1)
- # lsp (58)
- # nbb (4)
- # nrepl (3)
- # pathom (15)
- # shadow-cljs (27)
- # tools-deps (1)
I've just included prismatic schema in a shadow-cljs project running under node. I've used schema in clj many times with success but I'm struggling to get a coercer to convert a string to a keyword. I'm using schema.coerce/json-coercion-matcher
which does recognise string->keyword coercions and I've made sure to :include-macros true when requiring schema.core. Are there any gotchas I should be aware of when using prismatic schema with cljs? Thanks in advance for any advice. 🙂
I see the following: #schema.utils.ErrorContainer{:error {:policies missing-required-key, "policies" disallowed-key}}
Schema is (s/defschema bb {:policies #{s/Str}})
and I'm using a coercer which has worked just fine under the jvm to do the right thing. Was wondering if there's a cljs trick I'm missing.
I'm trying to bundle some static assets into a cljs library that can be used from js-land. There's no classpath, so it's not as simple as just using io/resource
. One solution I've read about and would like to try is to use new URL('<filename>', import.meta.url)
. However, I can't figure out how to translate the import.meta.url
syntax into cljs - it's a bit of weird syntax. According to the mdn docs:
> The syntax consists of the keyword import, a dot, and the identifier meta. Normally the left-hand side of the dot is the object on which property access is performed, but here import is not really an object.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta
I've tried js/import.meta
, but that reports Execution error (ReferenceError) at (<cljs repl>:1). import$ is not defined
.
Which may be because I'm trying it from the repl and I think it only works inside a module, but this will be in a ES module.
It won't work while hosted in the browser, but in node the plan is to use fs/readFileSync
If the trouble is only with import
being renamed into import$
, then you can try using js*
- not documented, IIRC, but will emit its string argument as is. I.e. (js* "import.meta.url")
will become import.meta.url
in the compiled JS.
!!! I think that will work. I'm now getting a proper error: Cannot use 'import.meta' outside a module
, but I'm pretty sure that's because I'm working from the repl.
js/__dirname
is the special binding to get the dir of the current file (meaning the produced JS file, not the CLJS file)
https://unpkg.com/browse/[email protected]/cli/ this is the contents of the npm package. dist.js
is the compiled CLJS output
The problem is when this library is used in another application and is living in node_modules/path/to/my/package/
then I need to be able access the /assets
folder of the library even though the relative directory has changed.
I was looking at this thread to come up with the new URL("filename", import.meta.url)
solution.
I'm not using webpack, that's just the only place where I could find a discussion on how to do it.
no matter what. you need something that puts the files out of the npm package into a web accessible location
But I'm not dealing with the browser - as long as Node has support for this ES syntax, which I believe it does, it should work. It's a complicated chain, but this cljc library is included in a cljc application that uses shadow-cljs to produce a browser artifact (using :target :esm), a webworker artifact (using :target :esm), and a node artifact (using :target :node-library), and a jvm artifact.
I may need to change the node artifact build to use :target :esm
too, but I've got some time to fiddle.
if its a CLJS lib the story is entirely different and none of the JS information applies
as I just said. you need something that puts the file into a web accessible location
so the browser needs to be able to access it via HTTP, however you deal with that. eg. your public
folder
No, this functionality will not work from the browser, it's server side only. Something like this:
#?(:cljs (if (browser-runtime?)
(throw (ex-info "Not supported" {:sorry :dude}))
(read-static-asset))
:clj (read-static-asset))
I don't know what you are asking anymore. what do you want to do? do you need it accessible in the browser or not?
According to some previous statements, the library works everywhere, including browsers. The static asset will be used only on the server side - on JVM, on Node via CLJS, on Node via JS.
Maybe the "on Node via JS" part is incorrect though, since I see that above ESM modules are mentioned only in the context of a browser and a web worker.
Sorry for the confusion - I'm building a nodejs application, that uses this cljc library, which needs to read a giant data file off of the filesystem. I need a way for this cljs asset to be accessible to another cljs application that produces an artifact that runs in Node on the server.
^you got it right, @U2FRKM4TW
there should be some node specific code that is only actually executed in the node env