This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # adventofcode (1)
- # aleph (2)
- # beginners (38)
- # boot (26)
- # boot-dev (8)
- # cider (8)
- # clara (10)
- # cljs-dev (130)
- # cljs-experience (1)
- # cljsrn (12)
- # clojure (119)
- # clojure-austin (40)
- # clojure-boston (1)
- # clojure-chicago (1)
- # clojure-dusseldorf (1)
- # clojure-estonia (11)
- # clojure-france (1)
- # clojure-greece (3)
- # clojure-italy (20)
- # clojure-nl (1)
- # clojure-russia (2)
- # clojure-spec (19)
- # clojure-uk (31)
- # clojurescript (62)
- # core-logic (7)
- # cursive (13)
- # datomic (28)
- # emacs (15)
- # fulcro (260)
- # jobs (4)
- # leiningen (5)
- # midje (4)
- # off-topic (75)
- # onyx (27)
- # planck (14)
- # protorepl (4)
- # re-frame (37)
- # reagent (62)
- # rum (2)
- # shadow-cljs (170)
- # slack-help (5)
- # spacemacs (6)
- # specter (9)
hi all, if you don't mind a sneaky question: at work our project has 586 cljs files (not counting tests), 60K LOC total, including white lines these are the compilation sizes with most dependencies removed (as an experiment): :advanced = 3.5MB :simple - 13.2MB :none - 45MB again, this is just with core dependencies (React, Om, Sablono, core.async) and removing ~15 dependencies (and therefore some other transitive dependencies).
Not sure if this is the right channel. But to answer your question: You need to measure what namespaces are taking up the space. FWIW, i have a project about half the size with ~700KB output size. (W/o react though).
:default is a replacement for the directly invokable
:as. CLJS doesn’t allow directly invokeable namespaces and we added that as a hack for CJS that only have a “default” export (ie.
module.exports = aThing).
Yeah, but this also affects other functions, in addition to directly exported function
(:require [react-dom :as react-dom]) (react/render ...) needs to call
no matter if CJS exports object or function, it will always be the default property
Our solution is special case as we do the module processing as separate step and then use the processed JS as input files, instead of doing everything in one go
we don't get a source map to begin with :disappointed: I think it stops working past a size thanks for the measuring suggestion! I'll look at the directory tree with optimizations :none and note any outliers finally, I know what #cljs-dev is for, was hesitant about asking this but sincerely I find it a question few should be able to answer. as emphasized, I genuinely don't know if this can be considered a compiler issue
hmm indeed. I thought the intent was to make CJS look like ES6 and emulate the “default” export since that only exists when directly assigning
module.exports not with
wonder how rewriting everything to
module$path$react-dom$react-dom.default instead of
module$path$react-dom$react-dom makes anything easier :stuck_out_tongue:
Closure rewrites all ES6 to access default properties, so CJS modules need to export that
I think I proposed just doing
module$path$react-dom$react-dom.default = module$path$react-dom$react-dom, so CJS modules would work as previously, at some point but that probably had some problems
CLJS_module$path$react-dom$react-dom = cljs.core.jsRequireInterop(module$path$react-dom$react-dom)
But would still require small change to analyzer/compiler to add those CLJS_ parts
default property can't be solved using that because the module name on js-modules-index is mangled so default is rewritten to default$
jsRequireInterop could test if the exported object only contains the
.default property and adjust accordingly
I sort of hacked this in
shadow-cljs as well, https://github.com/thheller/shadow-cljs/blob/master/src/main/shadow/js.js#L74-L90
@juhoteperi I would test for DCE issues when you try this. Aliasing is sketch-y for DCE or at least it was in the past.
@juhoteperi given that we know if a
:require is ES6 or CJS module, another approach would be to add
default via the compiler or at the REPL?
the JS world keeps coming up with new fun hacks … https://twitter.com/dan_abramov/status/950689118077571072
Opinion... is it a bug that
(count (subvec [1 2] 0 1.5)) evaluates to
1.5? (Clojure appears to round down in this case.)
This is one of those programs where it is difficult to claim whether it is even correct.
A practical motivating example is a function that attempts to return the fist half of a vector:
(defn half [v] (subvec v 0 (/ (count v) 2)))
I'll log a JIRA so that more investigation can be done to determine whether it is a valid defect.
yeah but if your elements are 64 bit values, that’s nearly 256gb of RAM for that vector anyway
> However, the maximum length of an array according to the ECMA-262 5th Edition specification is bound by an unsigned 32-bit integer due to the ToUint32 abstract operation, so the longest possible array could have 232-1 = 4,294,967,295 = 4.29 billion elements.
Testing the module-name default property thing now. I can append some code to the modules, but I can't find easy way to change the code emitted when invoking functions from those modules.
:name probably shouldn't contain
.default because that needs to match with the module provide name
I got a hacky solution working using
emit* :var: https://github.com/Deraen/clojurescript/commit/3103a0b29286d384dd1a2e979a945c0c48808c6f
I'm not sure at which point I could emit that. At the current location the value being emitted is map, munge maybe turns that into string which is then printed?
This is output from Google Closure, yes. Not sure about DCE at all. But at least they don't munge the name.
as well as cross module code motion - so that stuff must work even if
["default"] is present
I don't understand how accessing module fns/vars through one additional property would affect that (especially after I rewrite this without the additional
if on modules)
Yes, true. I'll try to understand the compiler part to properly emit default directly.
So something like this maybe:
(if (namespace n) (emits (namespace n) "[\"default\"]." (name n)) (emits (name n) "[\"default\"]"))
Okay, got this version working: https://github.com/Deraen/clojurescript/commit/fbd20dd7e3d919e6ad784c5e38b25e43cb132d7a
var-name check make any sense or is there better way to check if var is from JS module?
at this point var name is resolved to the full
module$ so it is not easy to check against
I attached latest patch to the issue. Still seeing warnings about optimization passes, otherwise should be OK now.
Aha! Setting :language-in to :ecmascript-3/5 works, 6 or later doesn't. After this the optimized output is the same size as with 946.
Closure defaults to EcmaScript 2017 now, we should probably set default to 3 or 5 at Cljs side?
(Compiler options page says default for both is es3, though default language-out has been no-transpile)
@juhoteperi yeah we need to change that, if we could get series of patches to bring us up to-date would definitely push this stuff through on Friday