Fork me on GitHub
#shadow-cljs
<
2021-11-06
>
borkdude09:11:38

Is it possible to use shadow to invoke the google closure compiler with pure JS? The use case is yielding a smaller bundle size by cutting out CLJS since I only use it for small glue code. Say I would have a index.js instead of src/foobar/main.cljs , can I configure shadow to use this and bypass CLJS completely?

borkdude09:11:12

It's probably a more normal idea to use closure directly, but using shadow makes moving between these approaches less effort

thheller09:11:52

@borkdude shadow can compile JS just fine without any CLJS. instead of :entries [some.cljs.ns] just use :entries ["/some/files.js"]

borkdude09:11:16

going to try!

thheller09:11:06

:target :esm sort of doesn't support it though since there is no way to express the exports without namespaced vars 😛

thheller09:11:38

but you can just create a CLJS file with no actual use of CLJS

borkdude09:11:42

I don't need this target, any browser target will do just fine

thheller09:11:49

:advanced should take care of removing cljs.core and such

thheller09:11:56

ah yeah for browser its fine

thheller09:11:15

I built an entire JS project a while ago as a proof of concept

borkdude09:11:20

Right now I have this config:

{:deps {:aliases [:dev :demo]}
 :dev-http {8002 "public"
            8001 "public/test"}
 :nrepl {:port 9000}
 :builds {:highlighter
          {:compiler-options {:output-feature-set :es8}
           :target :browser
           :output-dir "public"
           :modules {:clojure_highlighter {:init-fn clojure-highlighter.main/render}}
           :build-hooks [(shadow.cljs.build-report/hook
                          {:output-to "report.html"})]}}}

borkdude09:11:28

How do I specify the JS file instead of the CLJS init fn thing?

thheller09:11:06

just remove :init-fn and add :entries ["/that/file.js"]

thheller09:11:52

note that the js needs to be on the classpath and will be treated as https://shadow-cljs.github.io/docs/UsersGuide.html#classpath-js

borkdude09:11:40

How to deal with hyphens, do I need to write them as underscores if the dir has underscores?

thheller09:11:02

actual filename

borkdude09:11:11

I tried:

:entries ["clojure_highlighter/main.js"]
:entries ["src/..."]
:entries ["clojure-highlighter/main.js]
but for all of them I get:
The required JS dependency "clojure_highlighter/main.js" is not available.

thheller09:11:25

I linked you the documentation 😛

borkdude09:11:33

$ ls src/clojure_highlighter/main.js
src/clojure_highlighter/main.js

thheller09:11:54

:entries ["/clojure_highlighter/main.js]

borkdude10:11:12

That did work.

borkdude10:11:35

[:highlighter] Compiling ...
Wrote build report to: /Users/borkdude/Dropbox/dev/blog/report.html
[:highlighter] Build completed. (16 files, 0 compiled, 0 warnings, 2,42s)
0 compiled ;)

borkdude10:11:42

yeah that is true, because there is no CLJS

thheller10:11:02

yeah that only counts compiled cljs files 😛

borkdude10:11:03

I tried rollup for tree-shaking, that yielded a bigger bundle size than with Closure + CLJS included ;)

borkdude10:11:25

600kb vs 300kb. Doing this pure JS + Closure is going to yield me 200kb instead of 300kb.

thheller10:11:36

did you minify properly? I mean that sounds unlikely?

thheller10:11:08

given that there is absolutely no dead code removal or :advanced for npm packages?

thheller10:11:40

rollup even without tree shaking should be similar in size minus the CLJS parts?

thheller10:11:51

but you need to setup terser or so

borkdude10:11:01

don't know.

$ node_modules/.bin/rollup src/clojure_highlighter/main.js -f iife -o public/js/editor.bundle.js -p @rollup/plugin-node-resolve

src/clojure_highlighter/main.js → public/js/editor.bundle.js...
created public/js/editor.bundle.js in 1.1s

$ ls -la public/js/editor.bundle.js
-rw-r--r--  1 borkdude  staff  603547 Nov  6 11:06 public/js/editor.bundle.js

thheller10:11:22

yeah without a config that won't minify at all

borkdude10:11:46

I did what codemirror suggested in their readme 🤷

thheller10:11:13

there is a bunch more you need to do to get an actual minified bundle with rollup

thheller10:11:41

little easier to do in webpack since that has a dedicated dev/production mode similar to shadow

borkdude10:11:30

yeah with terser I now get 200kb

borkdude10:11:16

awesome, thanks for the tip

West11:11:47

This actually makes me wonder, how do I simply transpile cljs to js? Like how is it done on http://app.klipse.tech/, where I can do (+ 2 2) and get ((2) + (2));?

dpsutton14:11:21

clojure -A:cljs -M -m cljs.main -re node -r
ClojureScript 1.10.773
cljs.user=> (set! *print-fn-bodies* true)
true
cljs.user=> (defn foo [x] (inc x))
#'cljs.user/foo
cljs.user=> foo
#object[cljs$user$foo "function cljs$user$foo(x){
return (x + (1));
}"]
cljs.user=>

👍 2
borkdude12:11:56

@c.westrom Hacky way, in a CLJS repl you can do:

cljs.user=> (str (fn [] (+ 1 2 3)))
"function (){\nreturn (((1) + (2)) + (3));\n}"

🙌 3
🤯 1
😲 1
West12:11:33

Woah! Potent stuff!

West12:11:09

I see so much potential just with this!

thheller14:11:39

there is no potential in this at all. please don't use it. this is not suitable to do anything with as one isolated part of JS won't run anywhere without the rest of the runtime 🙂

borkdude17:11:13

it's useful to the extent that you can see what the compiler makes of it, but not for anything more than that

West20:11:27

Hmmm, was thinking I could use the output if I wanted some dead simple scripts inside a <script> element in HTML.

borkdude07:11:26

If you want something like this you should compile to a single script using optimizations simple or advanced. You can also check out scittle which is an interpreter which allows you to directly include CLJS in script tags.

👀 1
ghaskins23:11:45

@thheller ran into a problem with some code I had submitted previously. This fixes it

ghaskins23:11:34

Im not sure if you want the PR to bump the version or if you have a different release mechanism, so happy to refactor however you’d like

ghaskins23:11:28

As im sure you are aware, there arent unit-tests in that lib directly, but I did override the dep in my shadow-cljs project and verified it seems to work as advertised