Uploaded image for project: 'ClojureScript'
  1. CLJS-2870

Wrong provides/requires for ES6 modules with index.js

    Details

    • Type: Bug
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects versions: None
    • Fix versions: None
    • Labels:
      None
    • Environment:

      macOS 10.13.6, java 1.8.0_161

      Description

      This is related to CLJS-2205 Closed and CLJS-2836 Open , 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:

      build_opts.edn
      {:npm-deps {:react "16.2.0"
                  :react-dom "16.2.0"
                  :semantic-ui-react "0.82.2"}
       :install-deps true}
      
      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 installing locally as 1.10.394.

      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:

      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":

      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 Closed ), 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:

      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.

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              alex+import import
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated: