Fork me on GitHub
#shadow-cljs
<
2022-02-08
>
byrongibby09:02:13

Hi. I am trying to use d3.js, but I can't seem to import it correctly

(ns tech.coderaanalytics.d3test.views
  (:require ["d3" :as d3]))
Returns the following in the browser console

thheller09:02:09

what is the rest of the error?

thheller09:02:44

(chrome displays these errors better than safari/firefox)

byrongibby09:02:49

From Chromium:

thheller09:02:33

ok the regeneator stuff is the cause

thheller10:02:13

you need to add a "regenerator-runtime/runtime" to your ns :require just before requiring the d3 stuff

thheller10:02:41

(ns tech.coderaanalytics.d3test.views
  (:require ["regenerator-runtime/runtime"]
            ["d3" :as d3]))

thheller10:02:09

maybe npm install regenerator-runtime

byrongibby10:02:26

Yep that solved it! Thank you very much for your time, shadow-cljs is awesome

thheller09:02:26

hmm thats werid. which shadow-cljs version is this?

thheller09:02:48

hmm yeah upgrade that. that error message should be better, or just go away 😉

byrongibby09:02:40

Will try this, thanks!

byrongibby09:02:16

Same error with [email protected] I am going to try create a new project from scratch and see if I can reproduce this problem.

thheller09:02:24

the error didn't get better?

thheller09:02:57

the error message at least should have changed?

thheller09:02:25

nvm, other thread

byrongibby10:02:41

No change as far as I can see

byrongibby10:02:17

Solved the problem

wombawomba13:02:40

Is there a way to output multiple builds with different conditionals/reader features to the same directory?

wombawomba13:02:15

AFAICT it's not possible to specify per-module compiler options, nor to specify a specific output path for a module without renaming it.

wombawomba13:02:47

The only option I can think of would be to have duplicate build targets where the module names are different; but that'd mean I'd have to duplicate all (non-module) config, which seems a bit ugly (and also I'd run into problems with the different targets overwriting one anothers' manifest.edn files).

stask14:02:42

Hi Trying to use :karma target and getting Uncaught ReferenceError: global is not defined if i use npx shadow-cljs compile test && npx karma start --single-run works fine if i use release: npx shadow-cljs release test && npx karma start --single-run Am i missing anything? The relevant part of shadow-cljs.edn is :

:test    {:target           :karma
            :output-to        "out/karma-test.js"
            :compiler-options {:source-map true}
            :autorun          true}}
Thanks

thheller18:02:01

depends on where the global access is coming from. if code you use uses global then you need to change that I guess

stask21:02:25

thanks @U05224H0W any idea how to debug it? the full error i’m getting if i use npx shadow-cljs compile test is

❯ npx karma start --single-run
08 02 2022 23:13:39.899:INFO [karma-server]: Karma v6.3.15 server started at 
08 02 2022 23:13:39.902:INFO [launcher]: Launching browsers ChromeHeadless with concurrency unlimited
08 02 2022 23:13:39.906:INFO [launcher]: Starting browser ChromeHeadless
08 02 2022 23:13:41.448:INFO [Chrome Headless 98.0.4758.80 (Mac OS 10.15.7)]: Connected on socket 63bK4JwP5wscOyTgAAAB with id 826372
Chrome Headless 98.0.4758.80 (Mac OS 10.15.7) ERROR
  Uncaught ReferenceError: global is not defined
  at karma-test.js:8:15

  ReferenceError: global is not defined
      at karma-test.js:8:15
So it happens in the very beginning of the karma-test.js, the relevant part is:
1   │ var shadow$provide = {};
   2   │ var $jscomp = {};
   3   │ var CLOSURE_NO_DEPS = true;
   4   │ var CLOSURE_BASE_PATH = 'js/cljs-runtime/';
   5   │ var CLOSURE_DEFINES = {"goog.DEBUG":true,"goog.LOCALE":"en","goog.TRANSPILE":"never","goog.ENABLE_DEBUG_LOADER":false};
   6   │ var COMPILED = false;
   7   │ var goog = goog || {};
   8 * │ goog.global = global;
   9   │ goog.global.CLOSURE_UNCOMPILED_DEFINES;
  10   │ goog.global.CLOSURE_DEFINES;
Basically before it gets to my code

thheller21:02:55

hmm odd. haven't looked at karma in years. maybe it used to have global but no longer?

stask07:02:50

Will try to debug it, thanks What framework would you recommend for CI tests nowadays? Something that works well with shadow-cljs?

thheller07:02:38

personally I run tests in node. but I don't do any tests for frontend ui code

stask12:02:40

Just to close the loop: Setting :output-feature-set to :es6 helps:

{:target           :karma
 :output-to        "out/karma-test.js"
 :compiler-options {:source-map         true
                    :output-feature-set :es6}
 :autorun          true}

thheller15:02:45

that is the default nowadays? which shadow-cljs version do you use?

stask15:02:39

Judging by the code in shadow.build.targets.karma/configure it’s set to :es8 unless explicitly specified. So, i just specified :es6 in my config and it worked.

thheller15:02:03

did you try again without setting that? I don't see how that has any effect on what global is?

stask15:02:52

Not sure what was going on there. Removed the :output-feature-set key and it still works, Line 8 looks different from the time when it didn’t work

1   │ var shadow$provide = {};
   2   │ var $jscomp = {};
   3   │ var CLOSURE_NO_DEPS = true;
   4   │ var CLOSURE_BASE_PATH = 'js/cljs-runtime/';
   5   │ var CLOSURE_DEFINES = {"goog.DEBUG":true,"goog.LOCALE":"en","goog.TRANSPILE":"never","goog.ENABLE_DEBUG_LOADER":false};
   6   │ var COMPILED = false;
   7   │ var goog = goog || {};
   8 * │ goog.global = this || self;
   9   │ goog.global.CLOSURE_UNCOMPILED_DEFINES;
  10   │ goog.global.CLOSURE_DEFINES;

stask15:02:07

Anyway, sorry for false alarm

Simon15:02:30

Shadow-cljs optimizes the keys from this object. So that when i send this object to the backend it has key names like “Pq” instead of “success_url”

Simon15:02:06

payment.js

const docRef = await db
    .collection('customers')
    .doc(firebaseapp.auth().currentUser.uid)
    .collection('checkout_sessions')
    .add({
      price: 'price_XXXXXXX',
      success_url: window.location.origin,
      cancel_url:
        window.location.origin + '/logout',
    });

Simon15:02:19

I include the JS file like this: index.cljs

(ns app.components.user.index
  (:require
   ["antd" :refer (Avatar Button Dropdown Menu Skeleton Spin)]
   ["@ant-design/icons" :refer (LoadingOutlined)]
   [reagent.core :as r]
   ["firebase/compat/app" :default firebase]
   [app.helpers.macros :refer [if-let-n]]
   ["./payment" :refer (onAuth openCheckout openCustomerPortal onActiveSubscription)] <---- imports
   [re-frame.core :as rf]
   [cljs.core.match :refer [match]]))

Simon15:02:52

Options: 1. don’t do optimizations on the payment.js file. How? 2. don’t do optimizations on the keys of this specific object. How?

Simon15:02:36

Problem solved: Use string keys, since they don’t get optimized. payment.js

const docRef = await db
    .collection('customers')
    .doc(firebaseapp.auth().currentUser.uid)
    .collection('checkout_sessions')
    .add({
      "price": 'price_XXXXXXX',
      "success_url": window.location.origin,
      "cancel_url":
        window.location.origin + '/logout',
    });

thheller18:02:24

yeah, string keys or externs

1
Simon12:02:31

I am having more problems with this file getting minified renaming things. Defining externs doesn’t help. I tried :infer-externs and :externs:

:builds
 {:app {:target :browser
        :asset-path "/js"
        :modules {:main {:init-fn app.core/main}}
        :output-dir "public/js"
        :devtools {:http-root   "public"
                   :http-port   3001
                   :preloads    [day8.re-frame-10x.preload]}
        :compiler-options {:externs ["/app/components/user/payment.js"]
                           :infer-externs :auto}
        :dev
        {:compiler-options
         {:closure-defines
          {re-frame.trace.trace-enabled?        true
           day8.re-frame.tracing.trace-enabled? true}}}
        :release
        {:build-options
         {:ns-aliases
          {day8.re-frame.tracing day8.re-frame.tracing-stubs}}}
        :js-options {:ignore-asset-requires true}}

ag19:02:10

I need to contain all the front-end dependencies inside shadow-cljs.edn (to separate them from other lein deps), but I still want to call shadow.cljs.devtools.server and shadow.cljs.devtools.api from Clojure REPL. I tried leaving all the front-end deps in shadow-cljs.edn, and added only thheller/shadow-cljs to project.clj. But it doesn't compile my stuff. It keeps complaining about missing dependencies. What I am missing?

ag19:02:32

It works when I do it outside of REPL i.e., npx shadow-cljs compile :app, but when I do it from within the REPL, like so:

(require '[shadow.cljs.devtools.api :as shadow])
(require '[shadow.cljs.devtools.server :as server])
(server/start!)
(shadow/compile :app)
it fails to find required namespaces

thheller19:02:57

dependencies are managed in the process you are launching shadow-cljs in

thheller19:02:08

so if you use lein to start you REPL then your dependencies are managed there

thheller19:02:17

shadow-cljs.edn dependencies don't apply then

ag20:02:32

Yah, this makes sense now. I guess I'm gonna have to start cljs REPL in a separate process now

Simon12:02:31
replied to a thread:yeah, string keys or externs

I am having more problems with this file getting minified renaming things. Defining externs doesn’t help. I tried :infer-externs and :externs:

:builds
 {:app {:target :browser
        :asset-path "/js"
        :modules {:main {:init-fn app.core/main}}
        :output-dir "public/js"
        :devtools {:http-root   "public"
                   :http-port   3001
                   :preloads    [day8.re-frame-10x.preload]}
        :compiler-options {:externs ["/app/components/user/payment.js"]
                           :infer-externs :auto}
        :dev
        {:compiler-options
         {:closure-defines
          {re-frame.trace.trace-enabled?        true
           day8.re-frame.tracing.trace-enabled? true}}}
        :release
        {:build-options
         {:ns-aliases
          {day8.re-frame.tracing day8.re-frame.tracing-stubs}}}
        :js-options {:ignore-asset-requires true}}