boot-clj / boot-cljs

Boot task to compile ClojureScript programs.
Eclipse Public License 1.0
176 stars 40 forks source link

compiling: cljsjs/<some-lib>.inc.js is not a relative path #168

Open lwhorton opened 7 years ago

lwhorton commented 7 years ago

Has anyone been able to compile bleeding edge clojurescript 1.9.854 (with the global-exports feature) when compiling with dependencies from cljsjs?

Iā€™m getting a stack error of

/Users/.../.boot/cache/tmp3s9/d54ps8/main.out/cljsjs/development/moment.inc.js is not a relative path {:from :boot-cljs}

Per the alpha recommendation of reagent 0.8, I have added a foreign-lib config to my :compiler-options:

;; note this is improper -- moment should be /cljsjs/moment/moment.file--, but
;; it's packaged incorrectly on cljsjs as /cljsjs/moment.file
{:foreign-libs [
{:file "cljsjs/development/moment.inc.js"
 :file-min "cljsjs/production/moment.min.inc.js"
 :provides ["moment"]
 :global-exports '{moment moment}]}

I know the clojure version is still a release candidate, but I'm not really sure where to start digging. We have one suspect here at issue CLJS-2152. Did this release fix a "problem" on which boot-cljs was depending?

lwhorton commented 7 years ago

After looking at the jira ticket for the cljs fix it seems like there's some weird behavior with :lib that I don't fully understand. An example of a "solved" cljsjs library is here. When I apply this solution to my current issue with momentjs, I get another similar issue that's cljsjs/create-react-class/development/create-react-class.inc.js is not a relative path, so it seems like maybe this is a problem that's going to need fixing on a larger scale?

Deraen commented 7 years ago

I did see this exception in some configuration, but don't remember what caused this. Now I have several projects working with Cljs 1.9.854, Boot-cljs and Cljsjs packages.

Deraen commented 7 years ago

Are you using :modules?

lwhorton commented 7 years ago

I've been wracking the compiler options, cljs-jira and my boot file for anything that might be connected. No luck yet. No, i'm not using :modules... really nothing out of the ordinary except 1) using :checkouts from boot (should have no effect), 2) I'm using :repositories to fetch from an artifactory instance (again, probably no effect) and 3) a compiler options override of:

(cljs :compiler-options (merge foreign-libs
                               {
                                :closure-defines {"goog.DEBUG" true}
                                :source-map-timestamp true
                                :preloads '[preloads.core
                                            devtools.preload]
                                :external-config {
                                                  :devtools/config {
                                                                    :features-to-install [:formatters :hints :async]
                                                                    }
                                                  }
                                :compiler-stats true
                                }))

The foreign-libs map is more library configs like the above moment config:

(def foreign-libs
  {:foreign-libs [
                  ;; note this is improper -- moment should be /cljsjs/moment/moment.file--, but
                  ;; it's packaged incorrectly on cljsjs inside /cljsjs/moment.file
                  {:file "cljsjs/development/moment.inc.js"
                   :file-min "cljsjs/production/moment.min.inc.js"
                   :provides ["moment"]
                   :global-exports '{moment moment}
                   }
                  {:file "cljsjs/react-transition-group/development/react-transition-group.inc.js"
                   :file-min "cljsjs/react-transition-group/production/react-transition-group.min.inc.js"
                   :provides ["react-transition-group"]
                   :requires ["react" "react-dom"]
                   :global-exports '{react-transition-group ReactTransitionGroup}}
                  {:file "cljsjs/raven/development/raven.inc.js"
                   :file-min "cljsjs/raven/production/raven.min.inc.js"
                   :provides ["raven"]
                   :global-exports '{raven Raven}}
                  ]}
  )

Nothing seems out of ordinary. šŸ˜•

Deraen commented 7 years ago

Seems ordinary.

Do you have .cljs.edn file?

I just updated Saapas to use latest deps: https://github.com/Deraen/saapas, works for me. You could check that to validate if this is something with project, or something with env (OS X?)

lwhorton commented 7 years ago

I do not have a .cljs.edn file. In fact I had to go read what those were about. It doesn't seem necessary given that a main.cljs.edn is auto-generated by the boot-cljs task. Unless I'm missing something about what this really means, that is. I will tinker around with creating one manually and see if that gets me anywhere.

Deraen commented 7 years ago

Without .cljs.edn boot-cljs will compile ALL .cljs file in fileset, even those that are not needed by your :preloads or :main, which sometimes causes strange problems.

lwhorton commented 7 years ago

I've tinkered around with this for quite a while, but I'm still getting an error: /Users/.../.boot/cache/tmpeb7/-p772ji/js/main.out/cljsjs/create-react-class/development/create-react-class.inc.js is not a relative path {:from :boot-cljs}.

Here are the deps:

[cljsjs/react "15.6.1-1"]
[cljsjs/react-dom "15.6.1-1"]
[cljsjs/react-dom-server "15.6.1-1"]
[cljsjs/create-react-class "15.6.0-1"]

And the task:

...
    (cljs-repl :ids #{"js/main"})
    (cljs :ids #{"js/main"})
...

And the corresponding js/main.cljs.edn file:

{:compiler-options {
                    :main boot.core
                    :asset-path "js/main.out"
                    :source-map-timestamp true
                    :parallel-build true
                    :compiler-stats true
                    :closure-defines {"goog.DEBUG" true}
                    :preloads [preloads.core
                               devtools.preload]
                    :external-config {
                                      :devtools/config {
                                                        :features-to-install [:formatters :hints :async]
                                                        :disable-advanced-mode-check true
                                                        :silence-optimizations-warning true
                                                        }
                                      }
                    :foreign-libs [...as listed above]
                    }
 }

I've tried this with and without :compiler-options {:npm-deps ... my deps }, with and without a custom :foreign-libs { ... } declaration (as described above), and with various versions of "15.6.1-0/1/2 or 15.6.0-0/1/2".

I've been digging around the changes made to cljsjs/react* in the last week, as well as the reagent alpha and an example working repo for inspiration. I have not yet found what might be causing the problem.

I know that boot-cljs overrides the :output-to and :output-dir configuration for its filesystem management, which could be a culprit. Maybe it has to emit a relative path to satisfy a new compiler requirement in either of those configs?

** Im going to attempt to get a minimum case.

lwhorton commented 7 years ago

I was able to make a minimum case, and I think it has to do with preloads and maybe an out of date dependency.

;; preload
(ns preloads.core
 (:require [some.internal.dep :as dep])

;; .cljs.edn config
{:compiler-options {:preloads [preloads.core]}}

Compiling with boot-cljs generates the create-react-class.inc.js is not a relative path error seemingly when some.internal.dep has a dependency on an older version of reagent. Still digging.

lwhorton commented 7 years ago

After some further digging into mvn dependency resolution prompted by @Deraen , I retooled some of my :exclusions and :scope definitions. Here's a look at the updated boot show -d.

boot show -d | grep react
[cljsjs/create-react-class "15.6.0-1"]
[cljsjs/react-dom-server "15.6.1-1"]
[cljsjs/react-dom "15.6.1-1"]
[cljsjs/react-table "6.0.1-20170807.162917-11"] ;; deployed locally atm, not available on cljsjs
[cljsjs/react-transition-group "1.1.3-0"]
[cljsjs/react "15.6.1-1"]

Which looks proper to me -- there's no nested or conflicting versions. And the full dep list for posterity (edited to remove fluff):

[my-org/controls "0.0.1-SNAPSHOT"]
[my-org/logging "0.0.1-SNAPSHOT"]
[my-org/reframe "0.0.1-SNAPSHOT"]
ā”œā”€ā”€ [day8.re-frame/async-flow-fx "0.0.6"]
ā”‚   ā””ā”€ā”€ [day8.re-frame/forward-events-fx "0.0.4"]
ā””ā”€ā”€ [re-frame "0.9.4"]
    ā”œā”€ā”€ [net.cgrand/macrovich "0.2.0"]
    ā””ā”€ā”€ [org.clojure/tools.logging "0.3.1"]
[cljsjs/create-react-class "15.6.0-1"]
[cljsjs/moment "2.17.1-1"]
[cljsjs/raven "3.5.1-0"]
[cljsjs/react-dom-server "15.6.1-1"]
[cljsjs/react-dom "15.6.1-1"]
[cljsjs/react-table "6.0.1-20170807.162917-11"]
[cljsjs/react-transition-group "1.1.3-0"]
[cljsjs/react "15.6.1-1"]
[org.clojure/clojure "1.9.0-alpha16"]
ā”œā”€ā”€ [org.clojure/core.specs.alpha "0.1.10" :exclusions [[org.clojure/clojure] [org.clojure/spec.alpha]]]
ā””ā”€ā”€ [org.clojure/spec.alpha "0.1.94" :exclusions [[org.clojure/clojure]]]
[org.clojure/clojurescript "1.9.854"]
ā”œā”€ā”€ [com.google.javascript/closure-compiler-unshaded "v20170626"]
ā”‚   ā”œā”€ā”€ [args4j "2.33"]
ā”‚   ā”œā”€ā”€ [com.google.code.findbugs/jsr305 "3.0.1"]
ā”‚   ā”œā”€ā”€ [com.google.code.gson/gson "2.7"]
ā”‚   ā”œā”€ā”€ [com.google.errorprone/error_prone_annotations "2.0.18"]
ā”‚   ā”œā”€ā”€ [com.google.guava/guava "20.0"]
ā”‚   ā”œā”€ā”€ [com.google.javascript/closure-compiler-externs "v20170626"]
ā”‚   ā”œā”€ā”€ [com.google.jsinterop/jsinterop-annotations "1.0.0"]
ā”‚   ā””ā”€ā”€ [com.google.protobuf/protobuf-java "3.0.2"]
ā”œā”€ā”€ [org.clojure/google-closure-library "0.0-20170519-fa0499ef"]
ā”‚   ā””ā”€ā”€ [org.clojure/google-closure-library-third-party "0.0-20170519-fa0499ef"]
ā”œā”€ā”€ [org.clojure/tools.reader "1.0.3"]
ā””ā”€ā”€ [org.mozilla/rhino "1.7R5"]
[org.clojure/core.async "0.2.395"]
ā””ā”€ā”€ [org.clojure/tools.analyzer.jvm "0.6.10"]
    ā”œā”€ā”€ [org.clojure/core.memoize "0.5.9"]
    ā”‚   ā””ā”€ā”€ [org.clojure/core.cache "0.6.5"]
    ā”‚       ā””ā”€ā”€ [org.clojure/data.priority-map "0.0.7"]
    ā”œā”€ā”€ [org.clojure/tools.analyzer "0.6.9"]
    ā””ā”€ā”€ [org.ow2.asm/asm-all "4.2"]
[prismatic/schema "1.1.6"]
[reagent "0.8.0-alpha1"]

This also looks proper, as some my-org/<lib> libs have nested dependencies on reagent, for example, but maven properly pulls them out and only includes 1 version each dependency.

It's still confounding to me, though, that this compiles properly:

(ns preloads.core
  (:require
    ;[aft.reframe.core :refer [clear-subscription-cache!]]
    )
  )

And this does not

(ns preloads.core
  (:require
    [aft.reframe.core :refer [clear-subscription-cache!]]
    )
  )