Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miraculously disappearing dependencies when using lein cljsbuild auto. #493

Open
art-solopov opened this issue Jul 26, 2018 · 2 comments
Open

Comments

@art-solopov
Copy link

I'm trying to write my first ClojureScript project using NPM dependencies.

Here's my project.clj file:

(defproject cljsplay "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [
                 [org.clojure/clojure "1.8.0"]
                 [org.clojure/clojurescript "1.10.339"]
                 ]
  :plugins [[lein-cljsbuild "1.1.7"]]
  :main ^:skip-aot cljsplay.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}}
  :cljsbuild {
              :builds [{
                        :source-paths ["src-cljs"]
                        :compiler {
                                   :output-to "target/cljs/bundle.js"
                                   :pretty-print true
                                   :optimizations :whitespace
                                   :install-deps true
                                   :npm-deps {:moment "2.22"}
                                   }
                        }]}
  )

And here is my src-cljs/core.cljs file:

(ns cljsplay.core
  (:require [moment])
  )

(defn -getApp []
  (.getElementById js/document "app")
  )

(defn -updTime []
  (let [app (-getApp)]
    (set! (.-innerText app) (.format (moment) "YYYY-MM-DD || HH:mm:ss"))
    )
  )

(defn -main
  []
  (.setInterval js/window -updTime 100)
  )

(.addEventListener js/window "load" -main)

When I compile it with lein cljsbuild once, everything seems okay. However, when I try running lein cljsbuild auto, it loses the momentjs. I get this error:

Error: goog.require could not find: module$home$art_solopov$Projects$cljsplay$node_modules$moment$moment

And indeed, when I check the resulting bundle, there is no trace of actual moment.js library.

@leblowl
Copy link

leblowl commented Jun 12, 2019

@art-solopov I ran into something similar, except I get a different error, like invalid nameToPath or something. On first compilation, the dependency is required in cljs_deps.js. Second compilation, it's missing. I haven't tracked down where in lein-cljsbuild the error is. The code looks pretty simple, but there is also quite a bit of logic. I tested using run-compiler from this library directly (in support subproject), everything works well. I tested using the ClojureScript compiler directly, everything works well. So not sure what's going on just yet.

This isn't a fix for this exact problem, but as an alternative to Leiningen/cljs-build, you can use deps.edn and the ClojureScript compiler directly. The ClojureScript compiler appears to offer the same auto functionality as this plugin. Here is a basic example I drafted:

(require '[cljs.build.api :as cljs])
(require '[cljs.closure :as closure])
(cljs/watch (closure/compilable-input-paths ["src" "src-cljs" "env/dev/cljs"])
         {:asset-path "/js"
          :output-to    "target/cljsbuild/public/js/app.js"
          :output-dir   "target/cljsbuild/public/js"
          :main         'my.app
         
          :install-deps true
          :npm-deps {:moment "2.22"}

          :source-map   true
          :pretty-print true
          :verbose      true})

Update 2019-07-14
@art-solopov Thanks for the simple sample project, I have been using it for testing this issue.

I believe I've narrowed down the issue to the use of cljs.env/*compiler* here https://github.com/emezeske/lein-cljsbuild/blob/master/plugin/src/leiningen/cljsbuild.clj#L137... If I comment the binding, it works. I found cljs.env/*compiler* here https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/env.cljc

I am not very familiar with Clojurescript or lein-cljsbuild code but my guess is that the compiler depends on cljs.env/*compiler* internally and cljsbuild re-binds it to an initial value for each run of the compiler, thus messing up the compiler. The compiler env is defined here for each build: https://github.com/emezeske/lein-cljsbuild/blob/master/plugin/src/leiningen/cljsbuild.clj#L109 and then for each loop of the compiler, it looks like the same immutable compiler env is used: https://github.com/emezeske/lein-cljsbuild/blob/master/plugin/src/leiningen/cljsbuild.clj#L122 ... Maybe the compiler is expecting different state in cljs.env/*compiler*

Related initial commit:
4fb2670

Related update:
8bd20c9

These are from 5-6 years ago. It says Clojurescript was version 0.0-2197 in one commit message...
The initial commit says it was added to support incremental compilation. I thought the Clojurescript incremental compilation just works without the environment binding now.

@abradley2
Copy link

This has bit my as well. I can't quite figure out how to move of leiningen and achieve this same configuration with deps.edn

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants