<< Back to previous view

[CLJS-2763] cljs.core/resolve fails under :advanced compilation (regression) Created: 01/Jun/18  Updated: 06/Jun/18  Resolved: 06/Jun/18

Status: Resolved
Project: ClojureScript
Component/s: None
Affects Version/s: 1.10.238
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Pieter du Toit Assignee: Unassigned
Resolution: Not Reproducible Votes: 0
Labels: None

Approval: Screened

 Description   

The macro cljs.core/resolve does not produce sufficient information to invoke (when using :advanced compilation) a function across module boundaries under certain conditions.

With :advanced compilation, the attempt of module A to invoke the function in module B after load then fails at runtime. The issue occurs when using 1.10.238, but does not occur when using 1.9.946.

A minimal repro is provided below:

deps.edn
{:deps {org.clojure/clojurescript {:mvn/version "1.10.238"}}}
build.edn
{:output-dir "out"
 :optimizations :none
 :modules
 {:a {:output-to "out/a.js"
      :entries [demo.a]}
  :b {:output-to "out/b.js"
      :entries [demo.foo.b]
      :depends-on #{:a}}}
 :verbose true}
src/demo/a.cljs
(ns demo.a)

(resolve 'demo.foo.b/bar)
src/demo/foo/b.cljs
(ns demo.foo.b)

(defn bar [] :bar)
index.html
<html>
    <body>
        <script src="out/cljs_base.js"></script>
        <script src="out/a.js"></script>
    </body>
</html>

The repro can be compiled by running clj -m cljs.main -co build.edn -c



 Comments   
Comment by David Nolen [ 01/Jun/18 1:24 PM ]

See CLJS-2764, it's now no longer clear what the issue in this ticket is. The above case was simply demonstrating failing exists?.

Comment by Pieter du Toit [ 01/Jun/18 11:57 PM ]

I have narrowed the minimal repro down to React v16 being specified as a foreign lib dependency in the target module. Under :advanced compilation and with React v16, the module's compiled js function definitions are not available after the module is loaded. The attempt by the calling module to then invoke the function in the target module fails with the error "Uncaught TypeError: Cannot read property '$cljs$core$IFn$_invoke$arity$0$' of null" .

A minimal repro that produces the error is provided below:

deps.edn
{:deps {org.clojure/clojurescript {:mvn/version "1.10.238"}
        cljsjs/react {:mvn/version "16.3.2-0"} }}
src/demo/a.cljs
(ns demo.a
  (:require [cljs.loader]))

(cljs.loader/set-loaded! :a)

(cljs.loader/load :b (fn [e]
                       (.log js/console "Invoking b from a")
                       ((resolve 'demo.foo.b/bar))))
src/demo/foo/b.cljs
(ns demo.foo.b
  (:require [cljsjs.react]
            [cljs.loader]))

(defn bar [] (.log js/console "B has been loaded"))

(cljs.loader/set-loaded! :b)
index.html
<html>
    <body>
        <script src="out/cljs_base.js"></script>
        <script src="out/a.js"></script>
    </body>
</html>
build.clj
(require '[cljs.build.api :as cljs]
         '[cljs.repl :as repl]
         '[cljs.repl.browser :as browser])

(cljs/build
  "src"
  '{:output-dir "out"
    :optimizations :advanced
    :pseudo-names true
    :pretty-print true 
    :modules {:a {:output-to "out/a.js"
                  :entries [demo.a]}
              :b {:output-to "out/b.js"
                  :entries [demo.foo.b]
                  :depends-on #{:a}}}
    :verbose true})

(repl/repl (browser/repl-env)
  :output-dir "out")

It can be launched by running clj build.clj , once it is launched, observe the error message in the browser's console.

React v16's use of a global scope "use strict" directive seems to be the cause. The minimal repro can also be narrowed down further by removing the React dependency and prepending "use strict"; to out/b.js after compilation.

Comment by David Nolen [ 06/Jun/18 3:53 PM ]

See CLJS-2768 for the actual issue.

Generated at Thu Apr 18 21:30:23 CDT 2019 using JIRA 4.4#649-r158309.