Fork me on GitHub
#clojurescript
<
2022-07-21
>
zane19:07:16

When I use :target :bundle with no optimizations and I load the JavaScript file produced by Webpack I see the browser fail to load the following: • <asset-path>/goog/base.js<asset-path>/goog/deps.js<asset-path>/cljs_deps.js In the browser console I see:

Uncaught ReferenceError: goog is not defined
This appears to be because goog isn’t available at the top level. In index.js:
if(typeof goog == "undefined") document.write('<script src="js/goog/base.js"></script>');
document.write('<script src="js/goog/deps.js"></script>');
document.write('<script src="js/cljs_deps.js"></script>');
:optimizations :advanced seems to work fine. Should :optimizations :none work, or do I need :optimizations :simple?

athomasoriginal19:07:58

What does your config look like? are you using figwheel or shadow?

zane19:07:52

Neither.

{:main …
 :output-to "out/index.js"
 :output-dir "out"
 :asset-path "js"
 :target :bundle
 :bundle-cmd {:none ["pnpm" "webpack" "./out/index.js" "-o" "resources/js" "--mode=development"]
              :default ["pnpm" "webpack" "./out/index.js" "-o" "resources/js" "--mode=production"]}
:closure-defines {cljs.core/*global* "window"}} ; needed for advanced

p-himik19:07:31

https://cljs.github.io/api/compiler-options/optimizations:none - multiple unminified files (fastest for development). • :whitespace - single file w/ comments and whitespace removed • :simple - single file w/ whitespace optimizations + minified local var names • :advanced - single file w/ aggressive renaming, dead code removal, and inlining

zane19:07:58

Right, so I had it set to :advanced which works just fine.

zane19:07:30

But when I don’t set it to anything, per https://clojurescript.org/guides/webpack I get the error above.

athomasoriginal19:07:35

advanced would work because it's going to make a single JS file, but my hunch is the above is a result of asset-path

zane19:07:18

I still get the same issue without :asset-path. Let me try it again to confirm.

athomasoriginal19:07:23

So, to confirm, are you able to nix the asset-path and all that other jazz (`output-to` and output-dir)and just let CLJS output to its default location? From there, I would add back in the custom paths.

zane19:07:59

Yeah, I imagine :asset-path isn’t needed because it’s all going to be passed through Webpack anyway, right?

athomasoriginal19:07:50

You can add it when you want to customize where your serving your static assets from, but it might be incorrect as you showed above.

zane19:07:34

Same issue without :asset-path.

athomasoriginal20:07:01

indeed. So, where is out outputting to? target/out ?

zane20:07:07

The same three failed GET requests, followed by:

ReferenceError: goog is not defined

zane20:07:26

Not sure what you mean.

athomasoriginal20:07:40

in your directory structure. what does it look like?

zane20:07:42

The compiled ClojureScript is currently written to <project root>/out.

zane20:07:25

index.js is written to <project root>/out/index.js.

athomasoriginal20:07:46

right, does your web server server out or resources/public ?

zane20:07:49

Then Webpack turns those into resources/js/main.js.

zane20:07:06

The web server serves resources/js/*.

athomasoriginal20:07:26

:output-to "resources/js/main.js"
:output-dir "resources/js"
:asset-path "js/"

athomasoriginal20:07:06

What about something like the above? I can't remember where CLJS defaults to serving asset though, I thought it was resources/public

zane20:07:45

It probably was, but I’m, of course, using my own web server here.

zane20:07:49

Let me try that.

zane20:07:58

Using index.js instead of main.js here (`main.js` is what Webpack produces).

:output-to "resources/js/index.js"

zane20:07:17

That worked! Phew.

🎉 1
zane20:07:54

So, to cement my understanding:

zane20:07:46

…The compiled ClojureScript files need to be on the asset path?

athomasoriginal20:07:45

It's two level of thinking. 1. Where should the generated code files live? (`output-to` and output-dir) 2. Where should the content of the generated code look for the modules it depends on? (`asset-path`) So, output-to and output-dir tells the CLJS compiler where you want the code files to live. e.g.

app/
  src/
  resources/
    js/ <-- cljs/webpack puts the code they generate in here
      other-cljs-code/
      out/base.js
      index.js 
Then, the code inside of index.js needs to know where the generated code files live.
<asset-path>/base.js <--- resources/js/
...

zane20:07:06

Got it. That makes sense.

zane20:07:27

I think my misunderstanding was that even in development mode the output of Webpack would still be a completely stand-alone file.

👍 1
agorgl20:07:39

Can somebody tell me why setting a member property in a <canvas> 2d context leads to compilation error like this:

26 | (defn draw [ctx cw ch]
  27 |   (set! ctx -imageSmoothingEnabled false)
---------^----------------------------------------------------------------------
null
Can't set! local var or non-mutable field at line 27 core.cljs
--------------------------------------------------------------------------------
  28 |   (doto ctx
  29 |     (.clearRect 0 0 cw ch)
  30 |     (.fillRect 0 0 cw ch)
  31 |     (.drawImage (:cow @images) 40 40)))
relevant code:
(defn draw [ctx cw ch]
  (set! ctx -imageSmoothingEnabled false)
  (doto ctx
    (.clearRect 0 0 cw ch)
    (.fillRect 0 0 cw ch)
    (.drawImage (:cow @images) 40 40)))
called by component:
(defn canvas []
  (let [dimensions (dimensions)
        width (:width dimensions)
        height (:height dimensions)]
    (r/create-class
     {:display-name
      "app"
      :reagent-render
      (fn []
        [:canvas {:width (:width dimensions)
                  :height (:height dimensions)
                  :style {:width "100vw"
                          :height "100vh"
                          :display "block"}}])
      :component-did-mount
      (fn [this]
        (let [canvas (rdom/dom-node this)
              ctx (.getContext canvas "2d")]
          (draw ctx width height)))})))

isak20:07:39

(set! (.-imageSmoothingEnabled ctx) false)

agorgl20:07:09

aha it seems to be working

agorgl20:07:05

Thank you

1
p-himik05:07:42

Huh, weird. I thought the two ways to call set! are exactly the same.

p-himik05:07:32

Ha! They're exactly the same, but there's a bug and that false is treated as an absence of the value.

isak14:07:37

Interesting, didn't know that alternate syntax was a thing.