This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-05-13
Channels
- # announcements (8)
- # architecture (11)
- # babashka (159)
- # beginners (112)
- # biff (4)
- # chlorine-clover (4)
- # cider (10)
- # clj-kondo (51)
- # cljs-dev (43)
- # cljsrn (10)
- # clojure (45)
- # clojure-bay-area (5)
- # clojure-europe (11)
- # clojure-france (4)
- # clojure-italy (4)
- # clojure-nl (2)
- # clojure-norway (1)
- # clojure-sweden (1)
- # clojure-uk (8)
- # clojurescript (75)
- # code-reviews (1)
- # community-development (2)
- # conjure (88)
- # cryogen (5)
- # data-science (1)
- # datomic (3)
- # dirac (2)
- # fulcro (4)
- # helix (1)
- # jackdaw (5)
- # kaocha (5)
- # leiningen (2)
- # lsp (49)
- # malli (9)
- # mid-cities-meetup (1)
- # off-topic (8)
- # pathom (3)
- # polylith (19)
- # re-frame (6)
- # releases (3)
- # rewrite-clj (1)
- # shadow-cljs (98)
- # spacemacs (2)
- # tools-deps (6)
- # vim (4)
- # xtdb (6)
When using the {:js-options {:js-provider :require}}
the luminus landing page tells me that the javascript has not compiled and I get these errors in the developer console:
app.js:1672 An error occurred when loading shadow.js.shim.module$react.js
env.evalLoad @ app.js:1672
app.js:1673 ReferenceError: require is not defined
at eval (:3000/js/cljs-runtime/shadow.js.shim.module$react.js:3)
at eval (<anonymous>)
at Object.goog.globalEval (app.js:577)
at Object.env.evalLoad (app.js:1670)
at app.js:1773
env.evalLoad @ app.js:1673
app.js:1672 An error occurred when loading shadow.js.shim.module$react_dom.js
env.evalLoad @ app.js:1672
app.js:1673 ReferenceError: require is not defined
at eval (:3000/js/cljs-runtime/shadow.js.shim.module$react_dom.js:3)
at eval (<anonymous>)
at Object.goog.globalEval (app.js:577)
at Object.env.evalLoad (app.js:1670)
at app.js:1811
env.evalLoad @ app.js:1673
util.cljs:187 Installing CLJS DevTools 1.0.3 and enabling features :formatters :hints :async
app.js:1672 An error occurred when loading everclear.app.js
env.evalLoad @ app.js:1672
app.js:1673 TypeError: Cannot read property 'prototype' of undefined
at Object.reagent$impl$component$create_class [as create_class] (component.cljs:323)
at Object.reagent$impl$component$fn_to_class [as fn_to_class] (component.cljs:373)
at Object.reagent$impl$component$as_class [as as_class] (component.cljs:379)
at reagent$impl$template$reag_element (template.cljs:159)
at Object.reagent$impl$template$vec_to_elem [as vec_to_elem] (template.cljs:284)
at Object.reagent$impl$template$as_element [as as_element] (template.cljs:288)
at Object.eval [as reagent$impl$protocols$Compiler$as_element$arity$2] (template.cljs:305)
at Object.reagent$impl$protocols$as_element [as as_element] (protocols.cljs:5)
at f (dom.cljs:47)
at Object.reagent$dom$render_comp [as render_comp] (dom.cljs:19)
env.evalLoad @ app.js:1673
This happens even though lein shadow watch app
builds and compiles just fine. Any hints for how to debug it?@UT770EY2K Why do you use :js-provider :require? This is option isn't intended for code that should run in the browser.
Ah, I want to use some npm libraries that do not compile with the regular settings.
It seems like :js-provider :require isn't the right solution for that. What error do you get with the regular settings?
[:app] Compiling ...
[:app] Build failure:
Closure compilation failed with 2 errors
--- node_modules/d3-array/dist/d3-array.js:280
This code cannot be converted from ES6. extending native class: Map
--- node_modules/d3-array/dist/d3-array.js:300
This code cannot be converted from ES6. extending native class: Set
With :require
it compiles (but does not work in the browser)
I am a complete JS-n00b, but I tried to follow the guide https://shadow-cljs.github.io/docs/UsersGuide.html#_using_npm_packages.
Well, the JS ecosystem is a mess 🙂 JS is constantly extended with new language features, and the Google Closure compiler doesn't understand all of them. The library d3-array apparently uses features that the Google Closure compiler doesn't understand. What I would try is to load d3-array separately in the browser and use :js-options {:resolve {"d3-array" {:target :global }}} https://shadow-cljs.github.io/docs/UsersGuide.html#js-resolve-global. You'll probably have to process d3-array for the browser as well. Usually people use Babel for that.
Notably d3-array also appears here as an example for a JS module that tends to need special treatment for the browser: https://github.com/babel/babel-loader#some-files-in-my-node_modules-are-not-transpiled-for-ie-11
Hmmm, d3-array is a dependency of some other library, so trying to choose a specific library version manually sounds like it might easily lead to problems. Thanks for the pointers. I will try to understand them now :)
Maybe :js-provider :shadow works. It could be the default already, I'm not sure, but that's something you could try easily.
@UT770EY2K set :compiler-options {:output-feature-set :es6}
not :js-provider
if you set :js-provider :require
shadow-cljs will NOT process any JS dependencies and instead expect a separate tool to do that. this is not what you want
the default :output-feature-set
is :es5
but as the error is telling you the d3 code cannot be converted "down". so by setting a "higher" feature set that problem goes away
:js-provider :shadow
is the default for :browser
builds, do not change it unless you know what you are doing.
Interesting. So Google Closure is apparently quite good in supporting newer JS features. https://shadow-cljs.github.io/docs/UsersGuide.html#_output_language_options
yes, not super bleeding edge but quite good. usually when there is a standard there is support.
@thheller https://cljs.github.io/api/compiler-options/language-out doesn't mention :ecmascript6
. Is that correct?
yeah .. doesn't matter. closure keeps changing the names of those. in shadow thats just an alias for ecmascript-2015, same option
Thanks for all the help 🙂 It seems to be working fine now.
This is a question where I seem to have found a workaround, so please ignore if busy.
shadow-cljs release node
wasn't working, even though
shadow-cljs compile node
was.
Following advice in the troubleshooting guide, I compared versions of the major dependent libraries across working and non-working projects and noticed that the com.google.javascript/closure-compiler
version was different, someone had pinned it in the deps.edn
with a note about "enable for node", I also noted that there is a specified shadow-cljs version in the deps.edn
it eventually worked only when I both installed the specified version of shadow-cljs (through npm, how I'd originally installed), and unpinned the versions of
com.google.javascript/closure-compiler
and org.clojure/google-closure-library
which had both been pinned under a note.
The things I remain confused about:
do aliases like:
:aliases {:cljs {:extra-deps {thheller/shadow-cljs {:mvn/version "2.10.21"}
enforce shadow-cljs version? From my troubleshooting, I guess not if you install via npm, therefore I should be installing via lein?
Does anyone have an idea why these libraries have to be pinned, and shadow-cljs has to be an older version? the errors I got with the newer version were like this:
No matching field found: getSourceName for class com.google.javascript.jscomp.JSError
and
The result of a goog.define call must be assigned as an isolated statement.
one for pinned and one for unpinned closure compiler versions
if you use deps.edn
and have a true-ish :deps
key in shadow-cljs.edn
then ONLY deps.edn
controls the version for shadow-cljs you get
the one in package.json
then only controls the version of the shadow-cljs
command line tools
I have set up shadow-cljs to compile my cljs
to a specific folder from where I'm serving them with a different HTTP server. Everything seems to work ok... code compiles on save and hot reloads on the browser 😃. However, I do not get a browser repl after the code is compiled when I run shadow-cljs watch app
I have commented out ;; :dev-http {3000 "public"}
in my shadow-cljs.edn file because my server is running on the same port
error messages also sometimes, on the browser console don't seem to pinpoint exactly where the error is.
using shadow.loader/load
but the XHR request it makes has this undefined
segment in the url
and I’m not sure why
don't know why you posted the mm line? if that didn't exist you'd never get an URL from anything, it would error out differently
needs to get one argument for the prefix it is supposed to use, just an empty string for no prefix
I think it’s a user error that I need to sort out because I’m only getting the issue when I load the async route (in my app) directly
but if I go to another route first that isn’t a separate module, and then go to async route it loads correctly
oh… lol uhh I thought I was following the code for shadow.loader/load
shadow.loader.load = function(id, cb) {
shadow.loader.ensureInitWasCalled();
id = shadow.loader.string_id(id);
if (cb) {
shadow.loader.mm.execOnLoad(id, cb);
}
return shadow.loader.mm.load(id);
};
if you intent to call something when the code is loaded use :init-fn
in the module config
hmm, interesting question. I’m trying to work the async module loading into my app’s router which is represented as data in state, so like, when the ‘on-navigate’ event fires I load the new page’s module and call it’s render function. I’m sure it could be improved like how you suggested, I’m trying to get a poc working
maybe you want something like shadow.lazy
or the example from here https://code.thheller.com/blog/shadow-cljs/2019/03/03/code-splitting-clojurescript.html
the lazy-component util is using shadow.lazy https://github.com/thheller/code-splitting-clojurescript/blob/master/src/main/demo/util.cljs
["blog"
{:name :,
:weight 5,
:view #'deli-pages-blog/render,
:label "blog",
:controllers
[{:identity
(clojure.core/juxt :parameters :path-params :query-params),
:start #(rf/dispatch [:fetch-blog])}]}]
the only reason it’s all bundled together is for importing the namespace and passing it to that :view
keyword, so if I can just lazy reference that, bingoAny idea what I'm doing here. My shadow-cljs.edn
:source-paths ["src/main" "src/test"]
:builds {
:test {:target :karma
:output-to "target/ci.js"}}
$ npx shadow-cljs compile test
shadow-cljs - config: /home/stuart/Source/cljs/cljs-asm/shadow-cljs.edn
shadow-cljs - connected to server
[:test] Compiling ...
[:test] Build completed. (62 files, 1 compiled, 0 warnings, 0.45s)
This puts a file ci.js
in a folder named target
I have a karma.conf.js
module.exports = function (config) {
config.set({
browsers: ['ChromeHeadless'],
// The directory where the output file lives
basePath: 'target',
// The file itself
files: ['ci.js'],
frameworks: ['cljs-test'],
plugins: ['karma-cljs-test', 'karma-chrome-launcher'],
colors: true,
logLevel: config.LOG_INFO,
client: {
args: ["shadow.test.karma.init"],
singleRun: true
}
})
};
When I run karma start --single-run
I see this:
13 05 2021 20:11:24.219:INFO [karma-server]: Karma v6.3.2 server started at
13 05 2021 20:11:24.222:INFO [launcher]: Launching browsers ChromeHeadless with concurrency unlimited
13 05 2021 20:11:24.230:INFO [launcher]: Starting browser ChromeHeadless
13 05 2021 20:11:24.539:INFO [Chrome Headless 90.0.4430.212 (Linux x86_64)]: Connected on socket 63Mi3R7buKBGnu2WAAAB with id 43705700
Chrome Headless 90.0.4430.212 (Linux x86_64): Executed 0 of 0 SUCCESS (0.003 secs / 0 secs)
TOTAL: 0 SUCCESS
My tests are namespaced like this
(ns exfn.parser-test
(:require [cljs.test :refer-macros [deftest is testing run-tests]]))
anyone any ideas why its not finding my tests?hard to say. you omitted several important details. like which version is this? where is the actual test file?
I'm using shadow-cljs via commands like
npx shadow-cljs watch app
npx shadow-cljs release app
etcshadow-cljs - config: /home/stuart/Source/cljs/cljs-asm/shadow-cljs.edn
=== Version
jar: 2.11.22
cli: 2.11.22
deps: 1.3.2
config-version: 2.11.22
do you use project.clj or deps.edn? is there a :lein
or :deps
key in your shadow-cljs.edn
?
My whole shadow-cljs.edn
;; shadow-cljs configuration
{:source-paths
["src/main"
"src/test"]
:dependencies
[[binaryage/devtools "0.9.10"]
[reagent "1.0.0"]
[re-frame "1.2.0"]
[day8.re-frame/re-frame-10x "1.0.1"]
[org.clojars.ertucetin/re-frame-flow "0.1.1"]
[bidi "2.1.6"]
[com.rpl/specter "1.1.3"]]
:nrepl {:port 3333}
:dev-http {8080 "public"}
:builds {:app {:target :browser
:output-dir "public/js"
:modules {:main {:init-fn }}
:dev {:compiler-options {:closure-defines {re-frame.trace/trace-enabled? true
day8.re-frame.tracing/trace-enabled? true}}}
:devtools {:http-root "public"
:http-port 3000
:preloads [day8.re-frame-10x.preload
re-frame-flow.preload]}
:compiler-options {:closure-defines {re-frame.trace.trace-enabled? true}
:silence-optimizations-warning true
;; in production so you can do an :advanced compile.
:optimizations :simple}
:release {:build-options {:ns-aliases {day8.re-frame.tracing day8.re-frame.tracing-stubs}}}}
:release {:target :browser
:output-dir "release/js"
:modules {:main {:init-fn }}
:compiler-options {:silence-optimizations-warning true
:optimizations :advanced}}
:test {:target :karma
:ns-regexp "-test$"
:output-to "target/ci.js"}}}
yeah, so i have a bunch of tests over 2 files. The tests are
src/test/interpreter-tests.cljs
src/test/parser-tests.cljs
A test looks like
(deftest is-register-tests?
(is (true? (is-register? ":x")))
(is (false? (is-register? "5")))
(is (false? (is-register? "foo")))
(is (false? (is-register? "b_010101"))))
don't know where you get :silence-optimizations-warning
from but that config option does not exist
I am adding a server to my shadow project to handle endpoints and Crux. I would normally add Ring and Compojure to do that. Do I add these deps to shadow-cljs.edn or somewhere else? Are some of them already included… if so where are they pulled in? Thanks!
I created my app with create-cljs-app
so that’s the structure.
I use lein
for all my CLJ needs so I'll have a project.clj
for that with the proper dependencies. so I'll have a shadow-cljs.edn
for everything CLJS related and a project.clj
for CLJ stuff
just pushed me to finish posting this 😉 might help a little in understanding why those names/paths matter
in terms of adding a project.clj to a shadow project (next to a shadow-cljs.edn), I have (from lein new app server
(defproject server "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url ""
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
:url " "}
:dependencies [[org.clojure/clojure "1.10.1"]]
:main ^:skip-aot server.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all}})
how much of this is relevant pr meeds to be changed? (thanks for the hand holding).maybe follow some tutorial first and then integrate the files into actual project later
I totally understand! And thanks for all the help… you’ve got me going in the right direction.