This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-10-26
Channels
- # announcements (17)
- # babashka (68)
- # beginners (8)
- # biff (14)
- # calva (25)
- # cherry (10)
- # clj-kondo (1)
- # clj-on-windows (12)
- # cljsrn (6)
- # clojure (134)
- # clojure-berlin (1)
- # clojure-europe (33)
- # clojure-nl (4)
- # clojure-norway (6)
- # clojure-uk (10)
- # clojurescript (9)
- # datalevin (8)
- # datomic (34)
- # docker (1)
- # emacs (31)
- # fulcro (6)
- # honeysql (8)
- # java (7)
- # joyride (14)
- # kaocha (7)
- # malli (11)
- # nbb (4)
- # off-topic (11)
- # pedestal (14)
- # rdf (53)
- # re-frame (6)
- # reagent (39)
- # reitit (2)
- # releases (9)
- # rewrite-clj (14)
- # shadow-cljs (97)
- # specter (1)
- # testing (5)
- # tools-deps (12)
- # vim (4)
- # xtdb (9)
Hi Team, I need help with shadow-cljs. I want to exclude particular library while building. The shadow-cljs.edn looks such as
:app {:target :browser
....
:modules {:shared {:entries []}
:other {:entries ..}
...
My assumption is if the entries is empty (i.e []) then bundling all dependencies in public/shared.js file. I want to exclude a library which is not required at client side. I appreciate your time. Thanksshadow-cljs includes everything you :require
in the ns forms, thus you need to remove the require to get rid of it?
Thanks @U05224H0W for your quick response. I cannot remove that because it is required for one of the backend service
And I want to exclude it in shared.js, because it is not needed in client side
then you may need to split a namespace that contains the backend code into one that is one included on the backend and one that contains the client side
I was facing issues with https://www.npmjs.com/package/aws4-axios. I too have other npm modules such as axios, Luxon etc, there are fine.
FYI, I have separate name space for UI and Server
in general server side code should just not be included in a client side build. your namespaces should be structured accordingly
and only your namespace :require
controls what is included, so thats what you need to work out. can't give many tips besides that
you can disable the inclusion of certain npm packages via :js-options {:resolve {"package-you-dont-want" false}}
but that won't affect the CLJS code getting included
so best option is clearly structuring namespaces so certain stuff just isn't required in the first place
Sure I will re-check the structure
just to confirm: you are not using :modules
and a single build to compile client and server code together? so you don't have a :shared
module and then a :client
and :server
?
I do have :shared module for client. For server we have separate build. Please find the shadow-cljs.edn file
FYI you do not need :entries [our-app.ui.pages.getting-started]
if :init-fn
is the same namespace. :init-fn
desugars to that :entries
, so specifying it again is redundant. just :init-fn
is fine.
Great @U05224H0W. It worked. I appreciate your help. Thanks
Is it true that I can't have local dependencies in my shadow-cljs.edn
? When I Google it, people say to use deps.edn
as a fallback, but then I won't be able to use NPM packages. I feel stuck between a rock and a hard place.
using deps.edn has no impact on the ability to use npm packages. that continues to work just fine
I'm trying to follow the electron instructions for https://www.electronjs.org/docs/latest/tutorial/ipc and I added a build for the preload.js file.
{:builds {:preload {:target :node-script
:output-to "resources/preload.js"
:main app.preload.core/main
:hashbang false}
...}
...}
Now, I'm getting tons of warnings like DevTools failed to load source map: Could not parse content for file:///C:/Users/richie/Documents/org/projects/electric-clj-play/resources/public/goog.debug.error.js.map: Unexpected end of JSON input
It's not at resources/public/goog.debug.error.js.map
, it's at resources/public/js/cljs-runtime/goog.debug.error.js.map
.
How can I fix this?
Thanks!as far as I know the preload script is not actually node? its been many years since I even looked at electron so I'm not actually sure what this needs
I think you're right. It was described as being the same as the "renderer" but runs with more permissions. I first tried :target :browser
but had some trouble and then found https://clojurians.slack.com/archives/C6N245JGG/p1634150800435700 thread. I'll try :target :browser
again since now I don't remember what the problem was.
yeah :node-script
really assumes node and at least watch/compile
builds will probably only run in actual node
:target :esm
might also be an option. last time I looked at electron it didn't support ESM but its been a while
I don't get results in https://grep.app/search?q=exposeInMainWorld&filter[lang][0]=Clojure and I haven't found examples e.g. https://github.com/logseq/logseq/blob/master/resources/js/preload.js just does it in javascript. I tried adding a new browser target
:preload {:target :browser
:devtools {:watch-dir "resources/public"}
:output-dir "resources/public/js/preload"
:asset-path "js/preload"
:modules {:preload {:entries [app.preload.core]
:init-fn app.preload.core/main}}}
:renderer {:target :browser
:devtools {:watch-dir "resources/public"}
:output-dir "resources/public/js"
:asset-path "js"
:modules {:renderer {:entries [user]
:init-fn app.renderer.core/start!}}}
which gives me a bunch of errors like ReferenceError: goog is not defined
and I tried not adding a browser target for preload and instead just adding a module
:renderer {:target :browser
:devtools {:watch-dir "resources/public"}
:output-dir "resources/public/js"
:asset-path "js"
:modules {:shared {:entries []}
:renderer {:entries [user]
:init-fn app.renderer.core/start!
:depends-on #{:shared}}
:preload {:entries [app.preload.core]
:init-fn app.preload.core/main
:depends-on #{:shared}}}}}
but that gives me
Unable to load preload script: C:\Users\richie\Documents\org\projects\electric-clj-play\resources\public\js\preload.js
ReferenceError: SHADOW_ENV is not defined
Uncaught ReferenceError: SHADOW_ENV is not defined
:target :esm
didn't work right away although now I can't remember what was wrong... shoot.
Aww man. When I started out, it was working but had warnings. Now, it's broken and I can't make it work at all. I'm sad. I think I'm going to give up on electron.
if you want to setup a repo with the failing setup I can probably tell you where the error is
I tried to get everything back to where I think it was when I started. The time where I was just complaining about warnings. Now I have ReferenceError: __dirname is not defined
coming from the preload.js file.
https://github.com/rgkirch/electron-help
Thanks a million! My goal was to add a second electron window to help debug things. I have some tracing in my main app that I wanted to send over. Initially I assumed they'd share my global state but it looks like I have to use ipc.
Alright. I must have had nodeIntegration
enabled. e.g. :webPreferences {:nodeIntegration true
I'm back to just having the warnings.
That means I just don't know the "right" way to do this since I'm override the default behavior and what I'm doing here is discouraged for security reasons.
After I got discouraged I started reading the docs on cljfx but I might keep trucking with this for a bit.
Since :target
shouldn't be a :node-script
, do you have any suggestions on how to make it work as :esm
or :browser
?
Thanks again!
I tried :esm
https://github.com/rgkirch/electron-help/compare/master...target-esm. I get SyntaxError: Cannot use import statement outside a module
.
:target :browser
might be a better fit, but running with :js-options {:js-provider :require}
so it doesn't attempt to bundle stuff
I misunderstood this comment. I read it as suggesting either :target :browser
or :target :node-script
with :js-options {:js-provider :require}
I tried
:preload {:target :browser
:devtools {:watch-dir "resources/public"}
:output-dir "resources/public/js"
:asset-path "js"
:modules {:preload {:entries [app.preload.core]
:init-fn app.preload.core/main}}
:js-options {:js-provider :require}}
:renderer {:target :browser
:devtools {:watch-dir "resources/public"}
:output-dir "resources/public/js"
:asset-path "js"
:modules {:renderer {:entries [user]
:init-fn app.renderer.core/start!}}}
but get ReferenceError: goog is not defined
Is there a "cannonical" alternative...?
(:require ["/my/awesome/stuff" :as awesome-stuff])
Previously I'd been using figwheel with webpack to make an index.bundle.js
and then
(:require awesome-stuff)
with
// index.js
awesomeStuff = require('src/js/my/awesome/stuff.js')
window.awesomeStuff = awesomeStuff
then yarn webpack
etcthis is way better
Ok I have a flagrantly stupid question but if anyone is up for a little typescript/javascript/clojurescript/shadow-cljs to challenge themselves, here goes... one of my javascript imports is not being resolved.
import {Config} from "../config"; // this explodes in the browser
Ironically, if I do this:
(ns app.lib.ext.config
(:require ["/app/config" :as app-config]))
(def ^:export Config app-config/Config)
and then in my javascript I do
import config from "goog:app.lib.ext.config";
const Config = config.Config;
it works greatOk I think this question resolves to “how does goog.require
work “
import config from "goog:app.lib.ext.config";
why is this importing the CLJS ns instead of just the config directly?
goog.require
is no-op and does nothing at runtime. it merely serves as static information for the compiler so it can sort sources in the proper order
it serves no other purpose in shadow-cljs. in regular CLJS it is used by the debug loader and actually does something, in shadow-cljs it does not since it uses its own loader.
Sorry, yeah I know it’s confusing I wasn’t sure how much info to include
In the browser that JavaScript expands to ”/app/config”
the import statement
here's what the error looks like, expanded:
Uncaught (in promise) ReferenceError: Config$$module$app$config is not defined
I should also add this is executing in a webworker context
when I set a break point it still comes up as undefined which is odd considering the import seems to be working
I'm wondering, should
"/app/config.js"
expand to
"/js/compiled/cljs-runtime/app/config.js"
instead?so I'm not entirely sure what you are doing but the code you showed is not generated by shadow-cljs
If you don't think this is insanity I can DM you some more detailed code, it's company code so I can't really put in public chat. But here's the setup:
• shadow-clj project
• three typescript files, (config module config
and module that calls a webworker, thread-utils
) and (webworker worker
)
◦ thread-utils
depends on config
(this is where the error is happening)
• tsconfig file that compiles the typescript into a location in src/gen
• shadow project builds :main
, :base
, and :worker
• clojurescript code from :main
calls thread-utils
from src/gen
• crash
so you are right that shadow-cljs is not generating the javascript
the generated javascript from the tsconfig is being called with
(:require ["/classpath/to/thread-utils" :as thread-utils])
(thread-utils/testAdd)
I realize this is insanity, yes.
mostly I'm trying to localize if this is a google-closure-compiler issue, a misconfigured typescript issue, or a misconfigured shadow-cljs issue
so what does the JS file header look like after ts is done with it? just the import statements is fine
TS might not like the absolute includes, so instead try relative ones. so just ./config.js
if they are all in the same dir
I'm really only guessing here. I do not understand your setup, so my guesses will not be very accurate or helpful
ok just to close the loop, the error was very strange
// case1.js
export class Config {}
Config.fooPath = Paths.foo
Config.barPath = Paths.bar
vs
// case2.js
export class Config {
fooPath = Paths.foo
barPath = Paths.bar
}
the top one does not work with
import {Config} from "/path/to/config";
while the bottom on does. I have no idea why this is the case. But this is the result of:
// case1.tsx
export class Config {
static readonly fooPath = Paths.foo
static readonly barPath = Paths.bar
}
// case2.tsx
export class Config {
fooPath = Paths.foo
barPath = Paths.bar
}
The only thing I can think of here is that since the export
is declared in the generated code before the static methods are added, the static methods are not exported
so it wasn't a config error at all, just a masking bug
How would you debug when your project runs fine in development mode but when in release mode, the compiled js code crashes with a Error: xx is not a function
?
For me the difficulty is the code has already been minified and it's hard for me to find out what xx
originally was in the source code
> :pretty-print
and :pseudo-names
default to false
. You can use shadow-cljs release app --debug
to enable both temporarily without touching your config. This is very useful when running into problem with release
builds
from the https://shadow-cljs.github.io/docs/UsersGuide.html#compiler-options
Information about https://clojurescript.org/reference/compiler-options#pseudo-names