Fork me on GitHub
#shadow-cljs
<
2017-11-23
>
colindresj00:11:58

@thheller How can I generate the bundle-info.edn file for a build?

colindresj00:11:25

I though shadow-cljs release my-build would add it to the output, but I’m not seeing it

thheller02:11:28

@colindresj I’m still messing around with the functionality. its not ready but you can run shadow-cljs clj-repl and then (shadow/release-snapshot :build-id)

thheller02:11:21

it will be in target/shadow-cljs/release-snapshots/build-id/latest

thheller02:11:51

if you are only after the bundle-info.edn thats fine.

thheller04:11:31

@cmal can’t sleep and needed to code something so I did the keyword optimization we were talking about

thheller04:11:05

test compiled my production app which is split into 4 modules

thheller04:11:32

largest module went from 413761 bytes -> 406811 bytes before gzip and 53808 -> 52762 gzip’d.

thheller04:11:43

doesn’t seem that great …

thheller04:11:24

you can try it with [email protected] and setting :compiler-options {:shadow-keywords true}

thheller04:11:56

I’m really surprised how little difference it actually makes

thheller04:11:03

needs some more real world testing

thheller04:11:41

3kb gzip across all 4 modules

thheller04:11:15

should be much larger difference in reagent apps though

thheller04:11:23

a lot more keywords

thheller04:11:37

not sure how to test overall perf impact

devo04:11:25

Anyone gotten a fulcro project building with shadow-cljs? Getting an error about clojure.future not being on the classpath, which I'm pretty sure is from https://github.com/tonsky/clojure-future-spec.

devo04:11:32

nvm, rolling version back to 1.1.1 resolved it.

cmal05:11:07

@thheller Excellent work! I will check how this will decrease my compiled and gzip'd file.

cmal05:11:50

187304 -> 185424 for gzipped file

thheller08:11:08

hmm thats like 1%.

thheller08:11:17

@devo @mitchelkuijpers is using fulcro. clojure-future-spec is ignored by default since its a backport of clojure.spec to 1.8 but shadow-cljs already uses clojure 1.9

thheller08:11:56

but it seems like that the backport was changed so it should be safe to require now

thheller08:11:43

last time I checked it wasn’t safe to use. I will remove the removal so the clojure.future works again.

thheller08:11:25

@cmal wrote a post about it, hope its ok that I used your numbers and mentioned you. https://clojureverse.org/t/feature-highlight-shadow-keywords/952

cmal08:11:17

That is OK. Thanks @thheller

rauh09:11:07

@thheller Very cool stuff. I'm envisioning keyword interning here 🙂

rauh09:11:22

Btw, you probably wanna remove the console.log statement in the code

rauh09:11:41

(in constants-inject)

thheller09:11:11

should not code at 5am

rauh09:11:21

Keyword interning could mean we can rewrite (= :foo a) to (identical? :foo a)

thheller09:11:30

nah that can never work with :none

rauh09:11:44

Well yeah, in production builds.

thheller09:11:12

well it could work now that we have weak references (in some browsers)

rauh09:11:51

Yeah browser builds only for interning keywords. No risk there. Doesnt' even need a weakref

sundbp09:11:37

Hi. I’m testing out shadow-cljs for a node cli tool. Looks cool so far - great project!

sundbp09:11:37

I’m looking at the release build output of a very simple hell-world:

sundbp09:11:40

(ns permafrost.main)

(def value-a 3)
(defonce value-b 2)


(defn reload!
  []
  (println "Code updated.")
  (println "Trying values:" value-a value-b))


(defn main
  [ & argv ]
  (println "App loaded:" argv))

sundbp09:11:12

the shadow-cljs.edn:

sundbp09:11:15

;; shadow-cljs configuration
{:source-paths
 ["src"]

 :dependencies
 [[cider/cider-nrepl "0.16.0-SNAPSHOT"]
  [refactor-nrepl "2.4.0-SNAPSHOT"]]

 :nrepl
 {:port 8202}

 :builds
 {:pf {:target :node-script
       :output-to "out/permafrost.js"
       :main permafrost.main/main
       :devtools {:after-load permafrost.main/reload!}
       :release {:output-to "permafrost.js"}}}}

mitchelkuijpers09:11:36

@devo Send me a message if you need help, will publish a shadow-cljs starter with fulcro soon

sundbp09:11:48

the output is 838kb. I expected something smaller.

sundbp09:11:27

is my assumption or setup wrong?

thheller09:11:36

@sundbp by default the node targets are just using :optimizations :simple due to larger number of externs required on node setups

sundbp09:11:01

so no dead code deleting?

thheller09:11:02

try compiling with :compiler-options {:infer-externs :auto :optimizations :advanced}

thheller09:11:02

some DCE is still done but much less aggressive. also no renaming happens since file size usually is not that important for node.

thheller09:11:39

but the above settings will take care of that

thheller09:11:56

then you get the full experience but might need to fix a few externs

sundbp09:11:00

ok. i was just surprised that not most got eliminated as i assumed just some println would bring in almost nothing

thheller09:11:29

nah barely anything is removed in :simple

sundbp09:11:40

so with those settings it’s 85kb

thheller09:11:03

sounds about right

sundbp09:11:09

cool. thanks

thheller09:11:33

can get it even lower but then you can’t println or prn only console.log

thheller09:11:42

but any real code will be about that size minimum since its cljs.core with the datastructures

sundbp09:11:46

right. made 1k diff to change to console.log

sundbp09:11:04

not worried about size - just verifying my understanding of what’s going on

sundbp09:11:12

another assumption: if i aim to package up an npm package with a cli tool using some npm packages. I put my dependencies in package.json, do my thing. the release build will not bring in any code from the npm packages into my output, right?

thheller09:11:46

if you set :build-options {:print-fn :none} it should go down more

sundbp09:11:47

i.e. i’ll get an output that has all the code from the “cljs land”, but none from the “npm land” and hence fitting in nicely with npm

thheller09:11:26

you can take a look at what I do for shadow-cljs itself

thheller09:11:54

thats the package for npm

sundbp09:11:01

cool. will do

sundbp09:11:53

btw, I didn’t see any change with the print-fn change

thheller09:11:12

oh you might need to wipe your cache

sundbp09:11:15

ah. the npm-module target. was reading the source on that one as no docs yet.

sundbp09:11:23

ah. how do i do that?

thheller09:11:24

rm -rf target/shadow-cljs/builds/build-id

thheller09:11:44

I think I missed adding that setting to the cache-affecting-options 😉

thheller09:11:28

the :npm-module name is a bit misleading. you can use :node-library as well which is a bit smaller and better optimizable than :npm-module

thheller09:11:47

I needed to a few “special” things thats why I used :npm-module

thheller09:11:05

:node-script is fine too, thats how I started.

sundbp09:11:08

still see no effect of the :print-fn :none

thheller09:11:40

with just (js/console.log "foo") in your code?

thheller09:11:04

(defn main
  [ & argv ]
  (println "App loaded:" argv))

thheller09:11:38

remove the &

thheller09:11:47

varargs keep some collection code alive

thheller09:11:10

but really don’t go down this road .. it won’t get below 85k in any reasonable app

thheller09:11:24

thats pretty much the minimum as soon as you use anything from cljs.core

sundbp09:11:45

understood. wasn’t the intention - just wanted to check my understanding of what was going on

thheller09:11:37

as for the npm thing I recommend outputting into a dedicated directory with its own package.json. don’t use the one at the project root.

thheller09:11:59

you can but you have to be really careful with devDependencies and such then

sundbp09:11:18

right. i figured it’d be pretty safe with devDependencies vs dependencies?

sundbp09:11:38

just have the right thing in the right category and you’ll get the right outcome?

thheller09:11:07

yeah if you are careful it should work out.

sundbp09:11:13

thanks a lot for the help - looks like the way to go for CLI tools in cljs for me!

sundbp09:11:23

i’m curious about closh using lumo to run its node output: https://github.com/dundalek/closh/blob/master/bin/closh.js

thheller09:11:59

its pretty terrible to use lumo to do that if you ask me 😛

sundbp09:11:07

wonder if related to that --cache option?

thheller09:11:48

lumo is great but having it check if something needs to be compiled before running it is not useful for production builds

thheller09:11:08

much rather launch directly without all that overhead

sundbp09:11:40

yes. i don’t quite understand.. because they already do a cljsbuild via lein to get an :advanced optimization output..

thheller09:11:42

closh is a different story since it needs runtime eval

sundbp09:11:58

ah. that’s why they want lumo, got it.

sundbp09:11:02

makes more sense now

thheller09:11:41

still wouldn’t use lumo but its the easiest option for that

sundbp09:11:46

then the lumo+eval+cache thing starts to make sense.

thheller09:11:06

but as I understand lumo is adding a way to build projects as well

sundbp09:11:16

yes, read some blog post about it

sundbp09:11:24

but don’t think any docs are about

sundbp09:11:38

i’d love closh to become a viable day-to-day shell.

thheller09:11:10

seems cool yeah

sundbp09:11:39

so for shadow-clj cli you output to packages/shadow-cljs/cli/dist, install a bin runner.js that loads this file with some logic around how it’s finding the file. what’s the purpose of the runner here?

thheller10:11:26

if shadow-cljs is installed globally it should still use the one installed in the project

thheller10:11:39

thats what the runner does

sundbp10:11:25

seems generally sensible

sundbp10:11:40

thanks. that’s all I was pondering - should work out well!

mitchelkuijpers13:11:52

Nice new test support works awesome

mitchelkuijpers13:11:27

I love removing the ns that includes al test nses

mitchelkuijpers13:11:50

Something still goes wrong with reloading but that is because the fulcro-spec runner is macro I think

thheller16:11:47

@mitchelkuijpers [email protected] also adds :target :karma which always produces one output file (missing source maps currently, will add later)

:test-karma
  {:target :karma
   :output-to "out/demo-karma/test.js"}

module.exports = function(config) {
  config.set({
    browsers: ['ChromeHeadless'],
    basePath: 'out/demo-karma',
    files: ['test.js'],
    frameworks: ['cljs-test'],
    plugins: ['karma-cljs-test', 'karma-chrome-launcher'],
    colors: true,
    logLevel: config.LOG_INFO,
    // FIXME: do we need this?
    client: {args: ["shadow.test.karma.init"],
    singleRun: true}
  })
};

mitchelkuijpers16:11:25

Ah I already had it working with browser-test 😛

mitchelkuijpers16:11:31

It even works with karma watch

thheller16:11:58

oh really. with watch?

thheller16:11:32

ah hehe I couldn’t figure out how to make that work

mitchelkuijpers16:11:47

Hehe I wrote my own runner, sort of

mitchelkuijpers16:11:53

(ns atlas-crm.CI-runner
  (:require
   [shadow.test :as shadow-test]
   [doo.runner :as runner :refer-macros [doo-tests]]))

(doo.runner/set-entry-point!
 (fn [tc]
   (let [total-tests (reduce
                      (fn [acc {:keys [vars]}]
                        (+ acc (count (keys vars))))
                      0
                      (vals (shadow-test/get-tests)))]
     (jx.reporter.karma/start tc total-tests))
   (shadow-test/run-tests (cljs.test/empty-env :jx.reporter.karma/karma))))

thheller16:11:50

there is now shadow.test.env which has the get-tests fn

thheller16:11:57

also a get-test-count fn 😉

thheller16:11:48

had to split into a seperate namespace since shadow.test depends on cljs.test but shadow.test.env needs to be loaded before cljs.test

thheller17:11:53

how does your karma config look then?

mitchelkuijpers17:11:17

module.exports = function(config) {
  config.set({
    browsers: ['ChromeHeadless'],
    basePath: 'resources/public/',
    files: ['ci/js/test.js', {pattern: 'ci/js/cljs-runtime/**', included: false}],
    frameworks: ['cljs-test'],
    plugins: ['karma-cljs-test', 'karma-chrome-launcher'],
    colors: true,
    logLevel: config.LOG_INFO,
    client: {args: ["doo.runner.run_BANG_"],
    singleRun: true}
  })
};

mitchelkuijpers17:11:13

and my shadow-cljs.edn

mitchelkuijpers17:11:19

:ci {:target :browser-test
               :asset-path "/base/ci/js"
               :ns-regexp "-spec$"
               :runner-ns atlas-crm.CI-runner
               :test-dir "resources/public/ci/"}

mitchelkuijpers17:11:27

Sorry have to run, hope it helps!

thheller17:11:35

thx, it does.

mitchelkuijpers17:11:46

I really love the shadow-test stuff btw

mitchelkuijpers17:11:55

I have to fix fulcro spec I think since it uses macros

thheller17:11:52

glad it works for you. yeah those macros are annoying with respect to reloading