Fork me on GitHub
#shadow-cljs
<
2020-05-12
>
lilactown03:05:47

have to say, I really love node-repl for experimenting. great job and thank you for that thheller!

💯 4
Shuai Lin07:05:50

Just curious, what's the difference with node-repl and connect to shadow-cljs from emacs? To me it's all the same ...

lilactown03:05:02

I'm trying to use a Closure JS file. currently, I see the file gets loaded in the page, but when I try and evaluate anything in the namespace it provides it can't find it

lilactown03:05:18

it's using goog.module instead of goog.provides, if that makes a difference

lilactown03:05:07

I originally had it nested lilactown.harmony and evaluating e.g. lilactown.harmony/ref would say "cannot find namespace lilactown"

lilactown03:05:20

I changed it to a single symbol, harmony and that symbol is just undefined

lilactown04:05:44

tried another thing: deleted goog.module and tried to just treat it as a commonjs module (since goog.module also uses exports.foo = ...) and importing it like ["../harmony.js" :as harmony]

lilactown04:05:54

doesn't work in node-repl, does work in browser-repl

lepistane06:05:54

Hello i am looking into shadow-cljs and react native development I've used re-natal to develop hoby project before so i've got some background. i'd like to try shadow out because i've heard many, many good things about it before this point. I have few questions about this. Is there a official template for this? Basically something that allows me to create project structure for me similar how re-natal does? Also google search provided me with few examples of shadow being used with Expo which i'd like to avoid. Is there template or project that uses shadow-cljs but only vanila react native?

lepistane06:05:32

so basically there is no 'template generation' this is the template to use and adopt. Thanks for the quick reply!

thheller08:05:38

I don't use react-native myself so I hope someone else creates proper templates 😉

lepistane10:05:43

to be honest i've never made a template 😄 but nice idea this might be the way to do it 😄 i will have a look if i come up with it i will share it here. thanks for suggestion 😄

thheller07:05:14

@lilactown importing via string only works for ESM modules, don't use commonjs exports.foo

thheller07:05:41

goog.module needs to call goog.module.declaryLegacyNamespace() to be usable (or whatever that was called)

thheller07:05:35

but I'm not sure this works with regular CLJS, might require :foreign-libs config

dima09:05:37

Hello!

Syntax error (NoSuchFieldError) compiling at (shadow/cljs/devtools/api.clj:1:1).
ES3
Have this error after upgrading to 2.9.1 from 2.8.90 Clojurescript version is 1.10.597

thheller09:05:08

@trybeee need to upgrade clojurescript if you update shadow-cljs. should be 1.10.758

dima09:05:11

Thanks, it works!

thheller09:05:42

or don't use deps.edn/project.clj to shadow-cljs can ensure you get the correct version 😛

dima09:05:21

we use shadow with clj-run so the shadow-clj version is set in deps

thheller09:05:11

thats what I mean. if you use deps.edn it is in charge of dependencies. there is nothing shadow-cljs can do to ensure you get the correct versions

thheller09:05:27

so you have to keep track of it yourself

folcon10:05:32

Is it possible for shadow to say that it expects a newer version of clojurescript?

thheller10:05:37

not in a clean way and I'd rather not put checks everywhere

4
pmooser11:05:00

How does hot CSS reloading work in shadow-cljs? Should it work even if I'm not using the dev http server?

thheller11:05:30

yes, but that requires extra configuration to tell it where to watch

pmooser11:05:44

Ok, trying it ... thank you!

pmooser11:05:20

That seems to have worked!

lilactown14:05:49

I tried three legacy namespace declaration and it still didn't seem to work

lilactown14:05:07

Lemme push a repo in a bit

wcohen14:05:29

@loganpowell i’ve been working on https://github.com/Factual/geo/issues/69 Factual/geo to cljs the last few weeks — any comments you have about potential ways to integrate census-geojson would be appreciated! I made a (still very quiet!) #gis channel if you want to discuss there!

lilactown14:05:15

okay, so re: Closure JS. after clearing my build cache, adding goog.module and declareLegacyNamespace, it does require successfully

lilactown14:05:40

however, it's now failing on part of my code due to ReferenceError: $jscomp is not defined

lilactown14:05:38

I'm running a node-repl and then loading this namespace: https://github.com/Lokeh/melody/blob/master/src/melody/core.cljs

lilactown14:05:47

loading the namespace works!

lilactown14:05:20

but evaluating the forms in the comment at the bottom of the file, fails at the last one: (send ,,,)

lilactown14:05:10

specifically the line it seems to fail on (compiled) is:

Branch.prototype.flushNext = function() {
    var $jscomp$destructuring$var0 = $jscomp.makeIterator(this.unrealizedThunks);

thheller14:05:59

hmm I guess its yet another scoping issue for $jscomp. thought I got them all but guess not

thheller15:05:43

is this file generated from .ts or did you write it by hand?

thheller15:05:00

I have yet to see an example of tsickle output so I'm curious?

lilactown15:05:59

I generated it from tsickle

lilactown15:05:31

I commented out

var module = module || { id: 'src/index.ts' };

goog.require('_.tslib');

lilactown15:05:38

and added goog.module.declareLegacyNamespace();

lilactown15:05:43

but those are the only modifications I've made

thheller15:05:12

whats with all the if (false) {?

lilactown15:05:52

heh not completely sure. those were TS interfaces

lilactown15:05:23

best guess is it tells GCC what e.g. @implements {IRef} means?

thheller15:05:25

is anyone here aware that using deps.edn or project.clj in simple projects like this that make no use of any other particular feature of those will make shadow-cljs start about 50% slower?

thheller15:05:54

I see almost everyone using either these days and actually just using shadow-cljs.edn seems to become rather rare?

lilactown15:05:23

I was not aware of the slowness, but I am aware of the complexity. the reason I default to deps is that I often use local roots / git deps for experimenting

thheller15:05:33

well you can get the faster version by depending on thheller/shadow-cljs$aot but I'd generally advise staying away from using that in deps/lein projects

thheller15:05:50

too scary what happens with conflicts. shadow-cljs.edn can at least try to prevent some conflicts

Andy Heywood15:05:22

I did it (lein) without even thinking about it, coming from clj, but I think it helps the cursive integration? knowing this, I’ll try it without

thheller15:05:43

for cursive integration just run shadow-cljs pom and load the generated pom.xml in cursive

thheller15:05:31

well thats what I do ... project.clj is fine too. really its all fine just curious why nobody is using the fastest default 😛

lilactown15:05:05

I expect for this specific project, I won't need any dependencies so i can just keep the deps.edn around for external usage but use shadow-cljs.edn for dependency resolution in-project

lilactown15:05:20

thanks for the perf tip 👍

Filipe Silva15:05:40

I was trying to set a default resolve for everything so that using a certain lib wouldn't break the node-repl, then override it to self for the browser build (where it should work)

Filipe Silva15:05:49

so something like this

Filipe Silva15:05:51

;; Default all builds to resolving amplitude-js to the mock file. 
 ;; This way node-repl doesn't break when amplitude-js tries to use `window`.
 ;; 
 :build-defaults
 {:js-options {:resolve {"amplitude-js" {:target :file
                                         :file   "src/js/amplitude-mock.js"}}}}

 ;; On browser targets, resolve amplitude-js properly to the npm package instead.
 :target-defaults
 {:browser
  {:js-options {:resolve {"amplitude-js" {:target  :npm
                                          :require "amplitude-js"}}}}}

Filipe Silva15:05:16

turns out resolving to self is a no-no 😞

Filipe Silva15:05:18

[:app] Build failure:
can't resolve to self
{:require "amplitude-js", :other "amplitude-js"}
ExceptionInfo: can't resolve to self

Filipe Silva15:05:28

this looks like a perfectly reasonable error, so my question is whether there's some other way of doing this

Filipe Silva15:05:50

maybe resolving "src/js/amplitude-mock.js" to the npm target

thheller15:05:04

just repeat the config to the builds that actually need it ... I mean how many can there possibly be? 😛

Filipe Silva15:05:06

that's the thing though, I can't set the amplitude-js -> src/js/amplitude-mock.js resolve on the node-repl config because that config doesn't exist

Filipe Silva15:05:35

or at least that's what I got from our last conversation

thheller15:05:07

:node-repl is just a :node-script build so you can set it as a default for that?

Filipe Silva15:05:35

suppose I could, I never saw it as just a node-script

Filipe Silva15:05:50

should resolving the file to the node package also work though?

thheller15:05:42

I don't understand the question

Filipe Silva15:05:50

if I have a require such as (:require ["../../../amplitude-mock" :as amplitude], that refers to a js file in the source paths, should it be possible to use {:js-options {:resolve ... to resolve it to a npm package instead of the js file?

thheller15:05:10

at one point I'll write a proper post how you deal with this stuff cleanly. :resolve and hacks like it really should never ever be used. abstract it properly and you don't have to 😛

thheller15:05:35

kinda have to have it because JS is so messy but it should never leak over into CLJS projects 😛

Filipe Silva15:05:10

atm I'm trying to do a dynamic require in the js file instead

Filipe Silva15:05:33

that sounds nicer than the other options

Filipe Silva15:05:44

still not great, but confined to that single file

thheller15:05:27

I made a gist while ago but never really expanded on it https://gist.github.com/thheller/fa044450a6470fdd1afdbcf3f37a65e3

thheller15:05:04

sometimes messing with resolve/aliasing is the only way to do things but thats really rare

Filipe Silva15:05:28

so that approach is inverting the dep

thheller15:05:30

@lilactown so your issue is related to polyfills. it works fine when importing the file as ES6 but it fails when loading the file as a goog.module. not sure why yet.

lilactown15:05:37

yeah. it sounds like a similar issue that I ran into with helix

thheller16:05:43

I don't get why it works in the browser though 😛

lilactown16:05:44

I haven’t tried it using goog.module + legacy namespace in the browser

thheller16:05:30

well nevermind .. figured it out as I said it. might actually fix your issue too

thheller16:05:39

:compiler-options {:output-feature-set :es6}

thheller16:05:14

otherwise it adds polyfills for the let [thunk, ...rest] destructure you do

thheller16:05:33

that should still work though

lilactown16:05:16

that makes sense, but I would prefer to take advantage of closure’s polyfill-ability

thheller16:05:57

yeah polyfills are a constant nightmare

thheller16:05:21

really the least fun part of the entire tool

😭 4
thheller16:05:52

bonus effect: Error: Namespace "demo.js_class" already declared. can't hot-reload goog.module files ....

thheller16:05:08

you should really just use ESM, that works sooo much better

thheller16:05:15

goog.module is dead anyways

lilactown16:05:25

I thought it was goog.provide that was dead?

lilactown16:05:15

the problem with ESM is I don’t know if it’s as portable

lilactown16:05:19

this stuff is so complicated

lilactown16:05:15

I want to support shadow-cljs and vanilla cljs. vanilla cljs users have had issues with ESM in the past

lilactown16:05:23

maybe I’m not configuring things right

lilactown16:05:17

also, the idea of having a mixed TS + CLJS project is interesting 😄

thheller16:05:37

no clue how it works in regular CLJS. no clue how that even handles polyfills.

lilactown16:05:27

I suppose for building an app with TS + CLJS, it would be better to emit ESM and feed it into CLJS that way

lilactown16:05:50

the opportunity to DCE and other optimize was tantalizing but probably not a big deal for app code

lilactown16:05:16

for this use case, it’s a library so I need to support vanilla CLJS, support DCE, etc.

thheller16:05:18

well if you get it to work with regular CLJS let me know

thheller16:05:30

otherwise I don't think I want to spend more time sorting this mess

thheller16:05:29

I have no clue why it injects the polyfills for ESM files but not goog.module. they go through the same code path.

thheller16:05:34

hahahaha ... no they don't

thheller16:05:36

god dammit ...

❤️ 8
thheller16:05:16

@lilactown ok the main issue with the polyfills is that they are never injected dynamically. so for the node-repl they aren't there from the beginning so they are never added

thheller16:05:34

if you make a :node-script build that loads the ns from the beginning they would be there

thheller16:05:05

but I rewrote your source file to ESM. goog.module polyfill would still be missing.

lilactown16:05:34

for just node.js, or browser as well?

thheller16:05:42

polyfills are never loaded over the REPL

thheller16:05:19

I might switch to the strategy used by the closure compiler of just injecting all the polyfills all the time and letting :advanced remove them if not needed

thheller16:05:40

trying to keep them in sync is painful

lilactown17:05:00

but when talking about a user trying to use my lib in a project

lilactown17:05:26

will it work in :node-script , :browser and :react-native targets?

thheller17:05:40

if its ESM then that should work yes

thheller17:05:10

no clue how to deal with that yet

lilactown17:05:24

how does the closure lib get handled? special cased?

thheller17:05:43

goog-js but I don't think any of them require any polyfills so that never has been a problem

thheller17:05:20

how dare they use that name ... https://www.npmjs.com/package/@npmcli/arborist 😛

💢 8
lilactown17:05:35

I’m surprised that the class doesn’t cause any polyfill problems too

thheller17:05:17

well you can express that as vanilla ES3

lilactown17:05:08

okay, I guess I need to figure out how to get vanilla CLJS to use ESM

thheller18:05:07

try to get it working with goog.module

thheller18:05:23

I'm curious what it does about polyfills 😛

lilactown18:05:18

gotta go figure out how to start a vanilla cljs project 😂

knubie19:05:06

Just ran into an issue where I restarted my build and am now getting the Stale client! message. Checked that index.html is requiring the right javascript file (no changes were made to index.html or shadow-cljs.edn and not sure how to continue troubleshooting. Any help would be greatly appreciated!

knubie19:05:46

Just tried deleting the js files -> reloading the page (got error as expected) -> rebuilt using shadow -> refreshed and that seemed to work

knubie19:05:57

so maybe it was browser caching