This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-02-24
Channels
- # announcements (3)
- # babashka (47)
- # beginners (40)
- # biff (21)
- # calva (12)
- # cider (2)
- # clj-kondo (31)
- # cljsrn (8)
- # clojure (14)
- # clojure-berlin (2)
- # clojure-conj (1)
- # clojure-dev (24)
- # clojure-europe (84)
- # clojure-italy (8)
- # clojure-nl (1)
- # clojure-spec (1)
- # clojure-sweden (2)
- # clojure-uk (2)
- # clojurescript (34)
- # clr (3)
- # community-development (1)
- # cursive (14)
- # datalevin (8)
- # datomic (5)
- # defnpodcast (2)
- # dev-tooling (1)
- # etaoin (4)
- # events (3)
- # fulcro (26)
- # graphql (3)
- # honeysql (6)
- # hyperfiddle (45)
- # lsp (40)
- # malli (1)
- # missionary (1)
- # nbb (18)
- # podcasts-discuss (1)
- # reagent (8)
- # reitit (2)
- # releases (2)
- # ring-swagger (1)
- # scittle (78)
- # shadow-cljs (96)
- # vim (7)
- # xtdb (3)
I'm trying to use the library '@tanstack/router' which has some syntax that shadow-cljs/closure-compiler does not like. specifically this line
if (!this.#hasLoaders()) {
which I think is using the # to denote a https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields, causes the error
Errors encountered while trying to parse file
.../node_modules/@tanstack/router/build/esm/index.js
{:line 538, :column 14, :message "'identifier' expected"}
Is this a known issue? is there anything I can do to get it to work?that is the closure compiler yeah, only thing you can do is use the latest shadow-cljs/closure-compiler versions. if they don't like it your only option is using webpack via https://code.thheller.com/blog/shadow-cljs/2020/05/08/how-about-webpack-now.html#option-2-js-provider-external
ok thanks, just found this issue https://github.com/google/closure-compiler/issues/2731 > Getting this support completed is top of my mind for the coming quarter. Probably I'll just use a different router
A TS type check of all our code (which includes some TS) is failing because of this busted syntax in cljs_env.js
(dev mode):
addNewerLanguageTranspilationCheck("es_2019", function() {
return evalCheck('let r;try{r\x3d"
"}catch{};r');
});
that character in the double quotes is a 0x2029 paragraph separator. it's causing lots of problems in other places (eg. making NeoVim duplicate characters, Slack apparently renders it as a line break but vim doesn't, etc.)tsc
thinks it's a line break too, and fails with an unterminated string literal.
I think what evalCheck
is testing would still work if it were spelled "\u2029"
.
(I don't know if that cljs_env.js
is coming from shadow-cljs or upstream; sorry if this is misdirected.)
can't you configure tsc to just ignore all the cljs output? I mean its not gonna find anything useful there?
okay, that's what I suspected. perhaps I can tweak the TS config to do the right thing.
it complains about missing imports if I delete the CLJS. but perhaps I can make it there-but-don't-check-it. anyway, it's out of scope here.
I actually already have a thread sort of about this.
if you include CLJS output in a TypeScript build, tsc
will fail to parse cljs_env.js
.
• the checks for which JS version is in use eval little fragments of JS to check what the engine supports:
• the one for es_2019
uses a change to JS https://github.com/tc39/proposal-json-superset that added support for U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR as legal whitespace inside string literals, since JSON already does and JS is supposed to be a superset of JSON; this was a gap in that goal.
• the eval'd code in that test has a literal U+2029
character in it
addNewerLanguageTranspilationCheck("es_2019", function() {
return evalCheck('let r;try{r\x3d"
"}catch{};r');
});
notice that Slack can't handle it neatly either. it renders as a line break, invisible, or a space, or worse, depending on your editor. in my NeoVim it's a space but it makes the rest of the line buggy.
• TypeScript also claims to be a superset of JS, but it doesn't parse those characters in strings, at least as of 4.7.2. if this issue can be a "bug" anywhere, it's a TS bug, but that's a long road to fix.
changing the code in cljs_env.js
to use \u2029
instead of the literal character fixes the TS issue without damaging the test for ES2019, since by the time the eval
is running the inner string literal contains a real U+2029 character. (also worth pointing out this makes the cljs_env.js
file itself ES2019+, which seems to ruin the point of these input language checks!)https://gist.github.com/bshepherdson/75353e47a89c1f845da9a6021fae296b line 718
I couldn't find where we got these checks from either.
but it is in the version currently used by cljs. so a bump in the closure library would take care of it I guess
ah, so this was patched by Closure?
yes, unfortunately bumping the closure library version has been less than reliable and often comes with a bunch of breaking changes
not sure we can seamlessy get a newer version. but this is something for #C07UQ678E I guess
maybe do start that question there again but mentioning goog/base.js
instead of cljs_env.js
https://github.com/google/closure-library/commit/468188f4dc0d6fd756a142f2c7b72777fc0ebcb4
I mean if you want an immediate fix you can probably take this file https://github.com/google/closure-library/blob/master/closure/goog/base.js and put it in your classpath
hm. is there a clean way to force the version of the Closure compiler/library used by CLJS?
well, its just a maven dep. but there is no newer release as of yet as David does them.
I see. well, okay. this is definitely an obscure corner case, so a hack in the meantime seems appropriate. I'm tempted to just put a little script into our type-check command to change the character.
I asked if he can make a new release. shouldn't take long, until then manually copying is your ownly option
I mean why is this running through tsc
in the first place? its never gonna do anything useful with it?
we're using tsc --noEmit
to type-check the TS + JS + CLJS (output) codebase.
but what does that give you for the CLJS output? ever got anything useful from doing that?
if I exclude or delete the CLJS output it fails because there are imports in the JS and TS for things that don't exist. it doesn't really examine the JS files, but it does parse them.
I agree it's dumb, and that's why I'm fine with some hack like editing the file.
as I say, using the \u2029
escape fixes the outer parse without breaking the check it's trying to do inside eval
, so that seems safe enough.
for sure. I'll follow the update and delete this hack once it lands.
give org.clojure/google-closure-library 0.0-20230227-c7c0a541
a shot. maybe that works out of the box. I'm deep in something else right now, so will be a bit before I test myself
ah, cool.
it works. thanks! also as a bonus I realized this is probably why the line numbers and breakpoints have been weird and off-by -one in the devtools for this build.
because this literal paragraph break character confuses ~everything, including editors and Slack.
hehe. I don't know why it was there either or why the compiler replaces the \u variant. good that it is gone, it was useless code anyways
oh, I hadn't even spotted that in the commit. several parts of this code are encoded weirdly by the time it reaches the cljs_env.js
on disk. it turns the =
signs into \x2d
or whatever the right ASCII code is.
@thheller these warnings print on every re-compilation step obfuscating whether the built was successful. I think it’s sensible to show a warning once for every redef during a watch process.
fixing warnings is usually the best thing to do but I guess these libs might not be super maintained given https://github.com/thi-ng/math/pull/3
not like you are able to fix them anyways without restarting and changing the dependency
window.SLLogger = logger; // default global logger
This ^ is code from sumo-logger package from npm. What should I do if I want to use it from shadow-cljs ? Require and js/SLLogger.config
?how do you use it in JS? what is logger
in that example above? why is it set as a global? do you do that or does the library do that?
in JS:
SLLogger.log({
"userType": "silver",
"referralSource": referralSource,
"campaignId": campaignId
});
I mean I'd expect (:require ["sumo-logger" :as sumo])
and (sumo/log #js {...})
to work
(:require ["sumo-logger" :as sumo])
(def logger (sumo. opts))
(.log logger "event message to log", ...)
var sumoLogic = require('sumo-logger');
var opts = {
endpoint: 'your HTTP Source endpoint',
clientUrl: '' // NODE version only,
// ... any other options ...
};
// Instantiate the SumoLogger
var sumoLogger = new SumoLogger(opts);
// Push a message to be logged
sumoLogger.log('event message to log', {
sessionKey: 'your session key value',
url: ''
});
// Flush any logs, typically this line would be in your shutdown code
sumoLogger.flushLogs();
var sumoLogic = require('sumo-logger');
I'm guessing thats just a mistake in the docs
> Add <script src="path/to/sumologic.logger.min.js"></source> or <script src="path/to/sumologic.logger.js"></source> to your pages.
code is here https://github.com/SumoLogic/js-sumo-logger/blob/master/src/sumologic.logger.js
(:require ["sumo-logger/src/sumologic.logger.min.js"])
and then just the global js/SLLogger
I guess