Share your thoughts in the 2024 State of Clojure Survey!

Welcome! Please see the About page for a little more info on how this works.

0 votes
in ClojureScript by
This is related to CLJS-2205 and CLJS-2836, though I believe it is slightly different and I have additional (hopefully useful) information to provide.

The "semantic-ui-react" node module, when used as an npm-deps, produces code that fails to load. Minimal reproducing case I could come up with:

{noformat:title=build_opts.edn}
{:npm-deps {:react "16.2.0"
            :react-dom "16.2.0"
            :semantic-ui-react "0.82.2"}
 :install-deps true}


{noformat:title=deps.edn}
{:deps {org.clojure/clojurescript {:mvn/version "1.10.339"}}}


Note: I see exactly the same issue with current master, which at the time of writing is commit [81a1ea12|https://github.com/clojure/clojurescript/tree/81a1ea127974d43a6166fbdae33bcaa296fe9156] installing locally as 1.10.394.

{noformat:title=src/hello_world/core.cljs}
(ns hello-world.core
  (:require semantic-ui-react))
 
(println "Hello world!")


Files organized as:


$ tree
.
├── build_opts.edn
├── deps.edn
└── src
    └── hello_world
        └── core.cljs


Running:

clj -m cljs.main -co build_opts.edn -c hello-world.core


produces code that fails to load in the following way. First, modules that have an {{index.js}} file seem to be missing a provide statement; for example:

{noformat:title=out/node_modules/semantic-ui-react/dist/es/addons/Confirm/index.js}
goog.provide("module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm$index");
goog.provide("module$semantic_ui_react$dist$es$addons$Confirm$index");
goog.provide("module$semantic_ui_react$dist$es$addons$Confirm");
goog.require("module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm$Confirm");
var module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm$index={get default(){return module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm$Confirm["default"]}}


gets required elsewhere as the "full path" without the final "index":

{noformat:title=out/node_modules/semantic-ui-react/dist/es/index.js (elided)}
...
goog.require("module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm");
...


which produces an error saying that nameToPath cannot find the module {{"module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm"}}. I managed to fix that by patching the ClojureScript compiler (adding the additional {{goog.provides}} to {{cljs.closure/add-converted-source}} if the current source ends in {{index}}, mirroring the patch in CLJS-2205), only to find out that there is a second problem (which makes me doubt my approach is the proper way to fix this) in that the code produced actually then goes and tries to use the module with its full name, including the index part:

{noformat:title=out/node_modules/semantic-ui-react/dist/es/index.js (elided)}
...
goog.require("module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm");
...
var module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$index={get Confirm(){return module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm$index["default"]},
...


which throws an error saying that the variable {{module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm$index}} is not defined.

I am completely unfamiliar with all of the ClojureScript compiler, the Google Closure compiler or the ES6 module system, which makes it very hard for me to investigate further. I have verified that at the point of generating the requires and provides calls ({{cljs.closure/add-converted-source}}) the Closure object representing the dependencies _does not_ contain the {{index}} part at the end, which is consistent with the {{goog.requires}} calls that are generated. The {{goog.provides}} calls seem to be generated independently of the Closure compiler, based on analysis of the js files done in {{src/main/cljs/cljs/module_deps.js}}. What I cannot figure out (and therefore where I am blocked) is what piece of code generates the JS code that tries to access the "wrong" variable name. Maybe this is a bug in ClojureScript not generating the right {{goog.requires}} calls, or maybe this is a bug in Closure not using the same name for the JS variables as the symbols it generates on its {{Require}} objects.

1 Answer

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJS-2870 (reported by alex+import)
...