Fork me on GitHub
#clojurescript
<
2017-10-02
>
henrik05:10:16

I’m making a Chrome extension, and came across the following error when trying to use some third part libraries (https://github.com/roman01la/cljss, https://github.com/r0man/cljs-http, …): Could not load file 'bookmark.js' for content script. It isn't UTF-8 encoded. This error appears when trying to load the script. After ripping stuff out piece by piece, I’ve managed to trigger it with a simple (:import [ XhrIo]). So apparently, when Closure stuff is included, something is produced that Chrome interprets as “not UTF-8” (although the file itself is certifiably UTF-8 encoded). This is on whitespace optimization and cljs 1.9.908.

henrik05:10:16

I found the offending character. The [weird character here] in /\uffff/.test("[weird character here]") below. If I remove it from the compiled JS, the script loads.

goog.json.Serializer.charToJsonCharCache_ = {'"':'\\"', "\\":"\\\\", "/":"\\/", "\b":"\\b", "\f":"\\f", "\n":"\\n", "\r":"\\r", "\t":"\\t", "\x0B":"\\u000b"};
goog.json.Serializer.charsToReplace_ = /\uffff/.test("[weird character here]") ? /[\\\"\x00-\x1f\x7f-\uffff]/g : /[\\\"\x00-\x1f\x7f-\xff]/g;
goog.json.Serializer.prototype.serializeString_ = function(s, sb) {
  sb.push('"', s.replace(goog.json.Serializer.charsToReplace_, function(c) {
    var rv = goog.json.Serializer.charToJsonCharCache_[c];
    if (!rv) {
      rv = "\\u" + (c.charCodeAt(0) | 65536).toString(16).substr(1);
      goog.json.Serializer.charToJsonCharCache_[c] = rv;
    }
    return rv;
  }), '"');
};
(Edit: Slack strips out the offending character. Replaced it’s location with [weird character here]. It’s this one: http://www.fileformat.info/info/unicode/char/ffff/index.htm) Is this a problem with Chrome or with the compiler?

cycle33709:10:22

hello, can anyone help me ? I'm getting Duplicate extern input: when trying to build my cljs app

mseddon10:10:02

Hi. Just starting out with clojurescript and I have a weird problem. If I add a cljc file to my project and DON'T require it from my main.cljs file (so it's just a file, sitting alone), I get "goog.require could not find: cljs.core" if I call (weasel.repl/connect "...") in my main.cljs. If I require the other file from my main.cljs, the error goes away, if I comment out the connect, the error goes away. I'm using lein-cljsbuild to compile and totally confused, seems to be some closure library issue that I don't understand. The error appears spurious- things actually work, and weirdly goog.require("cljs.core") has been invoked perfectly fine previously, so something seems to be toasting it in weasel.repl/connect or such?

mseddon10:10:28

I'm using weasel 0.7.0 with piggieback 0.2.2

mseddon11:10:03

aha. failed to set :main would do it. doh

chrisetheridge13:10:12

with sablono, what’s the best way to return a react element that contains a list of elements?

chrisetheridge13:10:28

i’ve got (list [:div "1"] [:div "2"])

chrisetheridge13:10:37

there must be a way to return that, without wrapping with a higher div

levitanong13:10:33

@biscuitpants try making it a vector

mfikes14:10:22

@henrik It would be interesting to know if you actually have two bytes FF FF in your file. That would be encoded as UTF-8 as the three bytes EF BF BF. If instead the file literally has FF FF in it, then that wouldn't be UTF-8 encoded.

henrik14:10:56

Master @mfikes cracked the Chrome Extension case. For posterity: when Chrome tells you that it wants your files to be UTF-8, it’s lying. It wants them to be ASCII. The solution is to set :closure-output-charset "us-ascii" in compiler options, and Chrome stops whining.

mfikes15:10:24

(My hunch is that Chrome has a bug interpreting UTF-8, and that by using "us-ascii" output encoding, you get \u-escaped JavaScript where needed, thus working around the Chrome bug.)

mfikes15:10:28

The root problem is that the '\uffff' JavaScript string here https://github.com/google/closure-library/blob/master/closure/goog/json/json.js#L305 gets emitted as well-formed UTF-8 (three characters EF BF BF), but evidently misinterpreted by Chrome. Using :closure-output-charset "us-ascii" causes "\uffff" to appear in the output instead.

mfikes15:10:54

I find the penultimate paragraph here of relevant historical interest https://groups.google.com/forum/#!topic/clojure/ZhP88akSnDo

mfikes15:10:26

That statement is no longer correct today (UTF-8 is output for :advanced)

mfikes15:10:34

Yes @darwin looks like the same sort of stuff. The open question in my mind is "Isn't this properly UTF-8 encoded anyway? Why would Chrome complain about the three-byte sequence EF BF BF?"

mfikes15:10:08

In other words, on the surface it appears Closure is emitting valid UTF-8.

darwin15:10:41

Don't know. I'm no UTF-8 expert. In my issue. Closure compiler was provably spitting invalid UTF-8 output.

mseddon15:10:45

i've seen this issue with closure compiler regex

mseddon15:10:08

in the original closure library code, there is a regex string encoded with hex escape literal "\xFF.."whatever

mseddon15:10:23

but that gets consumed by closure, and it then emits it out as utf-8 raw

mseddon15:10:29

this causes errors in certain cases

mseddon15:10:57

yep, that is the EXACT line 🙂

darwin15:10:57

when you happen to compile-in I18N stuff

mfikes15:10:21

In the particular case @henrik encountered, the emitted file is valid UTF-8, as far as I can tell. I'm of the mind that it is Chrome that is wrong, given my limited understanding.

darwin15:10:04

btw. when hunting down this bug, I had to compile Chrome from sources in debug mode and then debug it reading the source, that is how I figured it out, because some other UTF-8 validation tools I tried they didn't see anything wrong with the file

mfikes15:10:54

Ahh, so you actually saw Chrome's validation code. Hmm.

darwin15:10:00

I was suspicious, because I didn't believe it was UTF-8 thing, I thought it was just wrong error report

darwin15:10:38

so I needed to find exact place where chrome raised the error

mfikes15:10:43

Well, we have a minimal example. Is EF BF BF valid UTF-8 or not?

mfikes15:10:31

(This is potentially relevant to ClojureScript users because that particular character is in Closure library.)

mfikes15:10:34

While perhaps not authoritative, there is an example at the bottom of http://www.fileformat.info/info/unicode/utf8.htm that argues that it is correct UTF-8.

darwin15:10:09

"is it valid UTF-8 according to Chrome's UTF-8 validator?" 🙂

mfikes15:10:54

No, Chrome claims the file is not encoded as UTF-8. If you delete those three bytes and replace them with \uFFFF, Chrome is then happy.

bhauman15:10:35

@henrik how are you loading the files into the chrome extension? I'm wondering because I had to do some hacking on this the other day.

darwin15:10:45

AFAIK chrome extension script loading goes through a different code-path which is more strict at validating, that UTF-8 validation was extension code specific in my case, it was related to content script specified in chrome extension's manifest json

bhauman16:10:32

BTW for folks wanting to do optimizations: none and/or figwheel aided development inside of a chrome extension its all about writing a script to load the opt none compiled files.

bhauman16:10:58

@darwin does that square with your experience?

bhauman16:10:03

and the reason you would want to do optimizations: none based development for a chrome extension is so that you get speedy incremental compiles and reloading with figwheel as well

darwin16:10:51

@bhauman this is for content scripts, right? background-pages and popup-pages can work with normal Figwheel, AFAICT

bhauman16:10:47

this works for all

bhauman16:10:44

I had problems, with background pages as well I think

bhauman16:10:52

its been a week since I messed with it

bhauman16:10:26

pop up pages worked out of the box

bhauman16:10:56

if i'm remembering correctly

darwin16:10:08

well, in chromex-sample, I have working figwheel setup for both background/popup code: https://github.com/binaryage/chromex-sample/blob/master/project.clj#L30

bhauman16:10:33

oh cool so I'll take your word for it for sure

darwin16:10:23

and I'm afraid content script cannot do eval under normal circumstances, where does this fn come from? https://gist.github.com/bhauman/8af183a13e4446d45bdfe2b285a976df#file-clojurescriptloader-js-L60

bhauman16:10:13

top of the file, and I assure you it works

bhauman16:10:32

@darwin thanks! I forgot about that. I made some changes to figwheel so that you can override how it imports a script so that it is now possible to use figwheel

bhauman16:10:39

@darwin oh shoot I had to add eval permissions to get this to work

darwin16:10:11

@bhauman that is no big deal for development, I guess

darwin16:10:23

I forgot that it is was possible to enable

bhauman16:10:34

"content_security_policy": "script-src 'self' http://localhost:3449 'unsafe-eval'; object-src 'self'",

darwin16:10:42

alternative 'hacky' approach would be to keep content script code running in the context of the page itself and move it into content-script context only for advanced/production build

darwin16:10:22

but that could introduce a whole new can of worms / bugs 😉

bhauman16:10:01

yeah and this method can be used uniformly in all contexts

bhauman16:10:07

Also just so you know I just added a figwheel.preload namespace that pulls its config from :external-config > :figwheel/config

darwin16:10:36

@bhauman great, I noticed it in my github feed

darwin16:10:00

btw. when you finish this content-script support I will be happy to test it and add it to chromex-sample

bhauman16:10:22

cool I'll keep you updated

darwin16:10:20

@bhauman just looking at your preload config code, not sure what protect-reload-hooks exactly does, but maybe consider quoting config data which will appear in generated cljs, this is what I had to do, when I wanted macro-emitted cljs config data be properly emitted: https://github.com/binaryage/dirac/commit/444cc1f37aa1d41bd5c6a2c1640007326bf3fac5

bhauman17:10:59

let me make sure that quoting is working correctly, it was originally but I'll check again

ThadIsNOTFood18:10:11

I'm sure this has been asked before and forgive my failure at searching: what is the best tutorial for getting up to speed on Clojurescript?

dnolen18:10:10

then take a look at Figwheel

ThadIsNOTFood18:10:42

the project I am joining already has that implemented but I will look it up to get a better understanding of it 🙂

dnolen18:10:01

@thaddeus.aid ah you’re joining an existing project? Are you familiar with Clojure?

ThadIsNOTFood18:10:43

vaguely, I've used it before but I would still classify myself as a noob

ThadIsNOTFood18:10:20

I've also worked in other functional languages

dhirensr18:10:38

fighwheel is only logging the file name in which i have changed code and it shows the logo but nothing changes

dhirensr18:10:43

can any one help?

dnolen18:10:14

@thaddeus.aid you might want to focus on Clojure and whatever framework the project is using then

dnolen18:10:28

the Quick Start makes very few assumptions about what you’ll be doing with ClojureScript

ThadIsNOTFood18:10:42

I guess what I am more looking at is presentation on the front end. The back end is set up to deliver the data I need in json/transit+json and that is all fine. But I need to totally rework the presentation on the webpage itself.

dnolen18:10:45

yes that just depends on what the project is using

dnolen18:10:08

Reagent, Om, different React wrapper, raw DOM etc.

ThadIsNOTFood18:10:48

looks like goog.dom and om.dom

dnolen18:10:57

ok yeah, then you should familiarize yourself with React & Om

dnolen18:10:12

goog.dom is mostly a cross-browser layer over native DOM facilities

ThadIsNOTFood18:10:02

cool, thanks for the help!

yury.solovyov19:10:55

seems like a typo in latest changelog good.object/getKeys -> goog.object/getKeys

pesterhazy19:10:54

if the new clojurescript release is required for compatibility with clojure 1.9 it may be good to note that in the changelog

rgm20:10:59

hi all, I have a question related to discovering resource paths in an SPA: what's the normal way to ... I guess "re-root-url" the resource paths in a WAR file?

rgm20:10:02

I'm using XHR after app boot (using re-frame) to pull some CSV hosted statically in /resources/public/csv/my.csv. In dev, using the string /csv/my.csv for the XHR uri works fine, but I want to put a war up on tomcat. In this case, the relative uri ends up as something like /my-war-file/csv/my.csv. I'm having trouble finding the right words to express this re-root-url'ing to find the right place in the docs. my ring handler seems OK (ie. a curl to feeds out the CSV as expected, but using something like csv/my.csv (no leading slash) seems to fail for the XHR call.

Roman Liutikov21:10:13

Where to check when compilation outputs the following error Duplicate input goog/base.js?

Roman Liutikov21:10:49

nvm, it was a require [goog :as goog]

Ertugrul Cetin21:10:50

Guys I created Clojurecademy I hope you like it, feel free to provide feedback

vikeri22:10:39

A question about mocking functions that are referenced in other namespaces: Say that I have the functions test.core/foo and test.helper/bar . test.core/foo is referencing test.helper/bar in its body. Then I want to test test.core. But I would like to mock out test.helper/bar to be something else. I can’t get with-redefs to work for this use case. It will only work for things I reference explicitly in the test file, the only way I got it working is to use set! test.helper/bar ... which is ugly and permanent for all the other tests. So my question is: Can I achieve the same effect as set! but without changing the global scope (like with-redefs)?

bostonaholic22:10:24

@vikeri maybe I’m misunderstanding, but shouldn’t (with-redefs [test.helper/bar ...] ...) work?

vikeri22:10:40

For me it doesn’t when I’m a testing ns where I’m testing the test.core ns

bostonaholic22:10:47

@vikeri?

cljs.user=> (in-ns 'test.helper)
nil
test.helper=> (defn bar [] "test.helper/bar")
#'test.helper/bar
test.helper=> (in-ns 'test.core)
nil
test.core=> (defn foo [s] (str (test.helper/bar) s))
#'test.core/foo
test.core=> (foo " in foo")
"test.helper/bar in foo"
test.core=> (test.core/foo " testing")
"test.helper/bar testing"
test.core=> (with-redefs [test.helper/bar (fn [] "mocked")] (test.core/foo " testing"))
"mocked testing"

vikeri22:10:40

Yeah it works in the REPL, trying to reproduce my case with real ns

bostonaholic22:10:44

:thinking_face:

vikeri22:10:01

@bostonaholic Hmm, I wonder if it has to do with my tests being async.

bostonaholic22:10:17

very well could be

vikeri22:10:21

Then probably the with-redef is redefining back the values before the async is completed.

ag23:10:36

does anyone know how using cljsjs to create a package that can be required like this:

(require '[cljsjs.foo :as foo])
(foo.bar)
instead of:
(require '[cljsjs.foo])
(js/foo.bar)

anmonteiro23:10:58

@ag use :global-exports, available since 1.9.854

anmonteiro23:10:58

maybe 1.9.908 actually

ag23:10:32

@anmonteiro some libs e.g. airbnb/enzyme cannot be consumed for browser directly from node_modules, they need to be bundled via webpack. So cljsjs in some cases still relevant

anmonteiro23:10:11

yes, that’s what :global-exports is for

ag23:10:07

hmm... so you're saying... alright... I think I got it... let me try

ag23:10:52

wait, so, how do I turn this es6:

import * as enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-15';

enzyme.configure({ adapter: new Adapter() });
to something that would work in browser and can be used as (require '[enzyme :as enzyme]) in a browser repl?

ag23:10:42

because (require '["enzyme" :as enzyme])works in node-cljs repl, but not in browser

ag23:10:56

so I've figured I'm gonna use cljsjs

anmonteiro23:10:59

depends what global variables the webpack build exports

ag23:10:56

which webpack build?

anmonteiro23:10:23

you just said you were going to bundle the package you want to use via webpack

anmonteiro23:10:33

I’m asking which global variables that bundle exports

ag23:10:35

yeah, using cljsjs

anmonteiro23:10:24

you wanna set {:global-exports '{cljsjs.enzyme enzyme}} or something

anmonteiro23:10:36

so that js/Enzyme can be used as cljsjs.enzyme

ag23:10:52

so, you see webpack consumes node_modules/enzyme/build/index.js and bundles it (all its dependencies) into a single file, are you saying I don't have to do that anymore?