Clojurians
#cljs-dev
<
2018-03-13
>

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

john00:03:35

what's the best way to use your locally built clojurescript jar in maven with -Srepro? :mvn/version doesn't appear to be pulling my latest local artifact... Does -Srepro pull from remote?

mfikes00:03:26

:mvn/version should work

mfikes00:03:43

In ClojureScript, if you do a script/build it will deploy to your local maven repo

john00:03:54

Layer 8 error

john00:03:08

How's this:

cljs.user=> js/blah
ReferenceError: blah is not defined
	 (<NO_SOURCE_FILE>)
cljs.user=> (ffirst [1])
Error: 1 is not ISeqable
	 cljs.core/seq (cljs/core.cljs:1221:20)
	 cljs.core/first (cljs/core.cljs:1230:16)
	 cljs$core$ffirst (cljs/core.cljs:1742:4)

john00:03:25

(defn file-display
  [file {:keys [output-dir temp-output-dir?]}]
  (if (and temp-output-dir? (not= "<NO_SOURCE_FILE>" file))
    (let [canonicalize (fn [file] (.getCanonicalPath (io/file file)))]
      (subs (canonicalize file) (inc (count (canonicalize output-dir)))))
    file))

mfikes00:03:15

In theory the value of file could have anything between the angle braces

mfikes00:03:36

There are bits of code here and there that check to see if it starts with "<"

mfikes00:03:02

All this stuff was written a couple of years before Spec came out, but this is all we have to go on :slightly_smiling_face: https://github.com/clojure/clojurescript/blob/7a5a65cb4d1eeca63746dd21e138ee9e56676ae4/src/main/clojure/cljs/repl.cljc#L172-L174

john00:03:13

k I think I've got something

john01:03:01

confusing how it worked at all. All canonical paths, when made as temp file, are coming back as /private/var/folder... whereas the :output-dir is always /var/folder..., so I don't see how the subs is working correctly... but I'm getting closer

john01:03:29

ah nevermind

john01:03:43

output-dir is getting canonicalized too, so it's getting a /private folder too. So, I'll probably just compare the directories, and if they're different, switch on that.

john01:03:12

It's a little hairy :slightly_smiling_face:

john01:03:38

Yeah, backed out of that strategy. David's try catch suggestion is probably the simplest. Something like:

john01:03:02

(defn file-display
  [file {:keys [output-dir temp-output-dir? repl-verbose]}]
  (if temp-output-dir?
    (let [canonicalize (fn [file] (.getCanonicalPath (io/file file)))]
      (try
        (subs (canonicalize file) (inc (count (canonicalize output-dir))))
        (catch Throwable e
          (when repl-verbose
            (println "Failed to canonicalize stacktrace")
            (println (Throwables/getStackTraceAsString e)))
          file)))
    file))

john01:03:01

Though perhaps this wouldn't be considered a failing condition, worthy of verbose logging?

mfikes01:03:27

Right, that works too. I would probably not log anything. You could think of it as a "best effort" to try to shorten the paths shown.

john02:03:12

@mfikes You think I should catch on java.lang.StringIndexOutOfBoundsException specifically and let it blow up otherwise?

john02:03:30

I don't want to silence any necessarily loud errors here

mfikes02:03:25

Well, the call to subs is not meeting its precondition. Perhaps another way to fix it is to not even call it if the first string is too short.

john02:03:04

The problem is that "too short" depends on whether the incoming file is actually a file or a string coming in

john02:03:08

Because the only way to get the correct length off of the path in front of "<whatever>" is to .getLastIndexOf File.separator

mfikes02:03:20

Maybe even a call to starts-with? would make things cleaner

john02:03:48

seems clean. I'll check it

mfikes02:03:11

It is really like "/foo/output/dir" and "/foo/output/dir/file" trigger the logic if 2nd starts with the 1st

john02:03:20

right... that's the direction I was trying to go in, but the trailing file path confused me. I think starts-with? should work though.

mfikes02:03:30

Roughly logic like

(let [output-dir "/foo/output/dir"
      file "/foo/output/dir/file"]
 (if (clojure.string/starts-with? file output-dir)
  (subs file (inc (count output-dir)))
  file))
but with the canonicalization, etc

john02:03:39

there we go:

(defn file-display
  [file {:keys [output-dir temp-output-dir?]}]
  (if temp-output-dir?
    (let [canonicalize (fn [file] (.getCanonicalPath (io/file file)))
          can-file (canonicalize file)
          can-out (canonicalize output-dir)]
      (if (.startsWith can-file can-out)
        (subs can-file (inc (count can-out)))
        (subs can-file (inc (.lastIndexOf can-file java.io.File/separator)))))
    file))

john02:03:27

cljs.user=> js/blah
ReferenceError: blah is not defined
	 (<NO_SOURCE_FILE>)
cljs.user=> (ffirst [1])
Error: 1 is not ISeqable
	 cljs.core/seq (cljs/core.cljs:1221:20)
	 cljs.core/first (cljs/core.cljs:1230:16)
	 cljs$core$ffirst (cljs/core.cljs:1742:4)

kommen13:03:11

trying current cljs master hangs when compiling

kommen13:03:11

investigating…

mfikes14:03:38

@dnolen I figured out https://dev.clojure.org/jira/browse/CLJS-2639 will assign to me temporarily to put together a patch

mfikes14:03:12

@kommen For now you can work around by adding :cache-analysis true to your compiler options.

mfikes14:03:33

You may need to clear out ~/.cljs in order to recover

kommen14:03:53

@mfikes thanks, I just had disabled aot-cache for now

mfikes14:03:11

That's another way to do it.

dnolen19:03:53

@kommen probably need to memoize

kommen19:03:18

@dnolen not sure. trying to build a demo, a simple app compiles fine with cljs.build.api, but get’s stuck in validate-inputs* with when building it with figwheel-sidecar.repl-api/start-figwheel!

dnolen19:03:29

@kommen try master

dnolen19:03:59

first, for dep graph stuff if you don’t memoize it’s easy to get into situations where it takes forever

dnolen19:03:27

oh though if this something simple then there’s maybe a bug

dnolen19:03:32

so maybe worth reviewing that to see if there’s a problem

dnolen19:03:10

other thing is if you can dump inputs, then we can use that as the test case

kommen20:03:12

@dnolen best way to dump the inputs?

dnolen20:03:02

honestly I would just hack the ClojureScript compiler and dump inputs before we call validate-inputs

dnolen20:03:11

install that locally and use it

dnolen20:03:28

then attach that edn file to a ticket

dnolen20:03:37

I’m sure the problem is trivial whatever it is

dnolen20:03:36

that said - building tests with ClojureScript uses parallel build so I’m surprised that didn’t catch something simple

kommen20:03:23

trying to dump the inputs, that’s quite a blob. would the :requires and :provides keys be sufficient for the test?

juhoteperi20:03:30

I've been testing Reagent with advanced optimized build and looks like there are few cases (at least with ReactDOM/server) where Closure breaks React code :confused:

juhoteperi20:03:48

React children property gets written HTML when using server/renderToString etc. because the check which should detect children is special property doesn't work

juhoteperi20:03:55

Externs don't help in this case

dnolen20:03:25

@kommen yep

danielcompton22:03:51

I've found an issue with source mapping ClojureScript code, but I'm not quite sure where the issue is:

danielcompton22:03:09

(ns source-map-test2.core)

;; (defonce conn
;;   (repl/connect ""))

(defn test-fn
  [one-one]
  (let [two-two 2]
    ((fn rebind [] one-one))
    (js-debugger)))

(test-fn 1)

danielcompton22:03:27

compiles to:

// Compiled by ClojureScript 1.9.946 {}
goog.provide('source_map_test2.core');
goog.require('cljs.core');
source_map_test2.core.test_fn = (function source_map_test2$core$test_fn(one_one) {
    var two_two = (2);
    ((function (two_two) {
        return (function source_map_test2$core$test_fn_$_rebind() {
            return one_one;
        });
    })(two_two))
        .call(null);

    debugger;

    return null;
});
source_map_test2.core.test_fn.call(null, (1));

//# sourceMappingURL=core.js.map

danielcompton22:03:48

If you look at the locals, one-one is resolved twice to the two values

danielcompton22:03:43

But the non sourcemapped version shows up correctly

danielcompton23:03:37

I notice the Source map spec says that we always must have 1, 4, or 5 values, but in the generated source maps I see lines with 2 and 3 values:

{"version":3,"file":"<snip>/source-map-test2\/out\/source_map_test2\/core.js","sources":["core.cljs"],"lineCount":18,"mappings":
";
  AAAA;
  ;
  AAKA,gCAAA,hCAAMA,wEACHC;
  AADH,AAEE,cAAA,VAAMC;
  AAAN,AACE,AAAB;
  ;
  AAAA,AAAcD;
  ;
  ;
  ;
  AACf,AAAA;
  ;AAAA
  ;
  ;AAEJ,wCAAA,xCAACD"
,"names":["source-map-test2.core\/test-fn","one-one","two-two"]}

john23:03:53

Can this effect line numbers in the console as well?

darwin23:03:04

@danielcompton I believe, this is a bug in chrome devtools, nothing to do with cljs: https://github.com/binaryage/dirac/issues/53

darwin23:03:07

as a side note: speaking about better chrome devtools interaction, it would help if generated javascript could be processed by jsbeautify or something similar which would break long lines into “natural” javascript linebreaks, this would help to place breakpoints and in general interact with devtools debugger (aka “inline breakpoints”) - because for some reason they have some assumptions about the shape of underlying javascript, they treat it as line-based source file and scan N-lines up or have limits on how many inline breakpoints they scan per-line and similar hard-coded line-based limits, compounded with source-mapping bugs this can cause some problems when trying to use devtools debugger with cljs-generated javascript

danielcompton23:03:53

@darwin good idea

juhoteperi23:03:05

Running code through jsbeautify or such would probably make builds measurably slower, but it should be easy to add some newlines to compiler output?

darwin23:03:06

@juhoteperi I agree that performance is an issue here, I was thinking about a toggle or something optional. Also note that this would be used in dev-time only. And applied to incremental builds most of the time.

juhoteperi23:03:21

Yeah, that could work.

lee.justin.m23:03:19

have you tried prettier? it is fast enough that I have it hooked into the save function of my editor

juhoteperi23:03:59

But if it is possible to find certain cases which produce code which is hard to debug, I think it would be easy to add some newlines to output. Like, I think in function calls all arguments are currently written to single line, but they could be easily split to several lines.

darwin23:03:16

whatever works, best would be some in-process java library, which would do the job without spawning a new process

darwin23:03:00

@juhoteperi newlines would help, but I don’t believe this would be a future-proof solution, all future contributors would have to think about newlines for this to not degrade again, but I’m with you here that it is maybe better to improve this at least a bit with this low-hanging-fruit than not at all

juhoteperi23:03:17

I think compiler part doesn't change that often so probably wouldn't be much work keep this working okay

darwin23:03:48

what do you guys think about adding some hook in compiler options as a :post-build step? user could then specify a shell command to run on produced js artifacts

darwin23:03:25

maybe something like this exists already?

juhoteperi23:03:50

preprocess is quite similar but pre hook

juhoteperi23:03:05

(and only for foreign lib files)