I want to move some of my app's UI components into a library. these will depend on some npm packages, as well as a compiled package (to remove some js features unsupported by goog) that I pull in via {:js-package-dirs ["vendor" "node_modules"]} . what's the most user-friendly way to package this? should I move the vendor contents to the src dir? will library users have to add npm deps to their package.json themselves?
is that app's UI components code CLJS?
there is no supported way to bundle JS code in .jars
yes, it is wrapping some npm js components with some added features, as well as some vendored js, as well as some js in the src dir.
so basically, the installation will be adding my lib, then running npm install <list of deps>, correct?
if I moved the contents of vendor to src and removed the :js-package-dir config, should it work the same?
no, none of that will work
first of all you cannot compile some CLJS and then include that compiled code in another CLJS build
then, as I said, you cannot bundle precompiled JS code in .jars and consume those as-if they were npm packages
you can publish it to npm, then sure
kinda hard to guess what you are trying to achieve without seeing any code
gotcha, so I'd need to publish an npm package that had all the npm deps in its package.json, as well as the vendored code and my own js code. the user would need to install that into via npm. then I could package my cljs code (uncompiled) and the user would add this to their deps.edn is that roughly correct?
yes, kinda have to be careful how the JS code is bundled though
the cljs code can include a deps.cljs file with {:npm-deps {"your-stuff" "1.1.0"}}, which automates the user having to run npm install your-stuff@1.1.0
oh, cool
thanks!
We have a use case where we’re migrating our ClojureScript application to anhttps://developer.atlassian.com/platform/forge/. Forge doesn’t directly support ClojureScript, but I believe shadow-cljs is responsible for compiling ClojureScript to JavaScript. We’re considering using that compiled JavaScript file as the entry point for Forge. My questions are: 1. Is it possible to compile and generate JavaScript output for a specific piece of code or a single readable javascript file instead of compiling the entire application in an single file? 2. Are there any tools or methods that can convert Clojure code directly into human-readable or reusable JavaScript code? This would help us reuse some of our existing functionality during the migration.
1) any CLJS build will require at least a single namespace and will include all the dependencies it has, so the implicit cljs.core and closure library bits. readable is not a goal during compilation, so a no there
Is it possible to use Atlassian forge framework dependencies directly in clojurescript project - "@forge/api": "^4.0.0", "@forge/bridge": "^4.1.0", "@forge/react": "^10.6.1", "@forge/resolver": "^1.6.0" \
any inputs will really help me pls
sorry, I know absolutely nothing about the forge stuff. I'd assume you use those dependencies like any other npm dependency
yes
@forge/react is UI and rest all for back end so my doubt was is it recommended to use this directly in clojure .. officially they just support JS
CLJS compiles to JS so thats fine. https://shadow-cljs.github.io/docs/UsersGuide.html#_using_npm_packages
I cannot walk you through any detail blindly, so you either show me some code of what you have tried or you are on your own
I'm trying to set up shadow-cljs with webpack and in dev mode I run into Uncaught TypeError: Cannot set properties of undefined (setting 'NodeType') (the build works fine in release mode)
I feel like I've seen similar errors talked about here but I can't for my life find it
if why "with webpack" you mean the shadow-cljs output it running through webpack entirely then only a few targets support this
Config
{,,,
:js-options
{:js-provider :import}
:builds
{:target :esm
:runtime :browserok for esm it should be fine
NodeType is usually goog.dom, so if that doesn't exist something is fundamentally broken 😛
I'm confused because it works with the release/prod config I looked at the generated code and it seems that webpack pulls in goog.dom.dom after goog.dom.nodetype which might be causing it?
release builds are optimized and collapse the "namespace" structure completely, they are also a single file, so basically anything that may confuse webpack is removed
dev builds obviously do not do that as that would make things like hot-reload or REPLs impossible
:esm should make the code look like something webpack supports, and I have seen people do that successfully
impossible for me to guess why it wouldn't work in your case without seeing any code
usually best to study the JS webpack generates. that isn't exactly easy but the most direct path.
I managed to get it to work but tbf I have no idea why it wouldn't work in the first place...
what was it?
I really don't know. Probably some pollution in webpack's node_modules cache? It kept breaking in seemingly unrelated ways at different points during attempts I got it working based on the config from https://deh.li/2022/11/04/shadow-cljs-webpack.html
Is it possible to write a macro for a require?
To get webpack to deal with my images I require them like this
(ns foo
(:require ["images/icons/login_active.png$default" :as LoginActive]))
Like this LoginActive will be = the uri of the image asset.
But writing this all over the place is repetitive and long and gets messy with variants.
Can I write a macro that does this for me?
(asset/uri "icons/login" :active)
;; "images/icons/login_active.png"
I first tried just putting a (require '["images/foo.jpg" :as Foo]) in the top level of a ns (outside of the ns form) but it complained about it being outside of the ns form. Hoped to do something like below
(defmacro uri
([item] (uri item :default))
([item variant]
(let [import-name (gensym)]
`(do
(require '[~(str "images/" item "$default") :as ~import-name])
~import-name)))no, macros creating require calls is not supported. that is a special form reserved for the REPL in CLJS