lambdaisland / kaocha-cljs

ClojureScript support for Kaocha
Eclipse Public License 1.0
40 stars 10 forks source link

Howto run with npm deps #36

Closed twashing closed 1 year ago

twashing commented 3 years ago

I'm trying to run Clojurescript tests with lambdaisland/kaocha-cljs. But the run fails when trying to run my mainline code, which calls the firebase-admin npm library. The compiler can't find the npm lib, even though I've done a yarn install, and specified it in either the (npm-deps or extra-npm-deps) of my alias.

And I know we can integrate with Node Modules (ref). But I haven't quite found the solution here or here either. Any hints?

deps.edn

{:aliases
 {:test/kaocha
  {:extra-paths ["dev" "test"]
   :main-opts   ["-m" "kaocha.runner" "--fail-fast"]
   :extra-deps  {org.clojure/clojure           {:mvn/version "1.10.0"}
                 org.clojure/clojurescript     {:mvn/version "1.10.520"}
                 lambdaisland/kaocha           {:mvn/version "1.0.732"}
                 lambdaisland/kaocha-cljs      {:mvn/version "0.0-71"}
                 lambdaisland/kaocha-cloverage {:mvn/version "1.0.75"}
                 lambdaisland/deep-diff2       {:mvn/version "2.0.108"}}

   :install-deps  true
   :npm-deps     {:firebase-admin     "9.4.2"}
   ;; :extra-npm-deps   {:firebase-admin "9.4.2"}
   ;; :cljs/precompile? true
   }}}

output

λ clj -M:test/kaocha

Randomized with --seed 1673397676
ERROR in unit-cljs (analyzer.cljc:4128)
Exception: clojure.lang.ExceptionInfo: null
#:clojure.error{:source nil, :line nil, :column nil, :phase :compilation}

 at cljs.analyzer$analyze.invokeStatic (analyzer.cljc:4128)
    ...
    kaocha.runner$_main.invokeStatic (runner.clj:183)
    kaocha.runner$_main.doInvoke (runner.clj:181)
    ...
Caused by: clojure.lang.ExceptionInfo: No such namespace: firebase-admin, could not locate firebase_admin.cljs, firebase_admin.cljc, or JavaScript source providing "firebase-admin" (Please check that namespaces with dashes use underscores in the ClojureScript file name) in file /Users/foo/bar/src/backend/firebase/firestore.cljs
{:tag :cljs/analysis-error}

 at cljs.analyzer$error.invokeStatic (analyzer.cljc:751)
    cljs.analyzer$error.invoke (analyzer.cljc:747)
    error.invokeStatic (analyzer.cljc:749)
    cljs.analyzer$error.invoke (analyzer.cljc:747)
    ...

1 tests, 1 assertions, 1 errors, 0 failures.
plexus commented 3 years ago

Hi @twashing ,

Start by taking kaocha out of the equation. Are you able to get a clojurescript REPL using vanilla clojurescript (cljs.main), where you can load said dependency? Kaocha-cljs uses a clojurescript REPL under the hood.

Those install-deps/npm-deps do not belong in deps.edn, they are clojurescript compiler options. You would have to put those in the right spot in tests.edn.

What clojurescript tooling are you using? If you are using shadow then kaocha-cljs will not work (because shadow diverges from vanilla cljs) and you have to use kaocha-cljs2, which uses a completely different approach so that it can support shadow.

plexus commented 3 years ago

Also keep in mind that while clojurescript has npm-deps support, it depends a lot on how that package was written. It assumes code that can safely pass through the Google closure compiler, which is far from always the case, which is why shadow has decided to handle these in a different way that is less likely to break.

twashing commented 3 years ago

Hey @plexus Thanks for responding.

Fair enough. The NPM dependency in question is firebase-admin (see here). And indeed, running a regular cljs repl with a stripped down deps.edn (no shadow), does not pull in firebase-admin.

So if the Clojurescript compiler options, install-deps and npm-deps do not belong in deps. edn, then where should they go? Ie, tests.edn doesn't seem like the right place, as I'll need to reference firebase-admin from mainline code and test code.

{:target :nodejs
 :paths ["src"]
 :deps {org.clojure/clojure       {:mvn/version "1.10.0"}
        org.clojure/clojurescript {:mvn/version "1.10.773"}}

 ;; :npm-deps      {:source-map-support "0.5.9"
 ;;                 :firebase-admin     "9.4.2"}
 ;; :install-deps  true
 ;; :extra-npm-deps {:ws "7.4.2"}

 :aliases
 {
  ;; clj -M:cljs
  :cljs {:main-opts ["-m" "cljs.main"]
         :npm-deps     {:firebase-admin     "9.4.2"}
         :install-deps  true
         }

  :test/kaocha
  {:main-opts   ["-m" "kaocha.runner"]
   :extra-paths ["dev" "test"]
   :extra-deps  {org.clojure/clojure           {:mvn/version "1.10.0"}
                 org.clojure/clojurescript     {:mvn/version "1.10.520"}
                 lambdaisland/kaocha           {:mvn/version "1.0.732"}
                 lambdaisland/kaocha-cljs      {:mvn/version "0.0-71"}}}}}

Here, the foobar.core namespace references firebase-admin. And it fails even when I try to add it through :npm-deps. So how then, do we add NPM dependencies, using deps.edn?

λ clj -M:cljs
ClojureScript 1.10.773

(require 'foobar.core)
Unexpected error (ExceptionInfo) compiling at (REPL:1).
No such namespace: firebase-admin, could not locate firebase_admin.cljs, firebase_admin.cljc, or JavaScript source providing "firebase-admin" (Please check that namespaces with dashes use underscores in the ClojureScript file name) in file /my/projects/foobar/src/foobar/core.cljs
cljs.user=>
cljs.user=>
humorless commented 1 year ago

Hi @twashing,

From the issue #25 you refer, the author (Mark) actually provided a repo, which may serve as an example to run with npm deps.

Mark provided that repo to demonstrate that there is a dead lock issue but the dead lock can be avoided by adding just a single line of code. I have created a PR to add that one line of code here.

I think you may try to run the test with npm deps leveraging the Mark's repo (reference how he arrange the code). If you also encounter the deadlock issue, try the PR #53.