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

Missing/Incorrect provides for node module required from ES6 module

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Completed
    • Affects versions: None
    • Fix versions: None
    • Environment:

      Linux 4.16.2 #23 SMP Mon Apr 30 11:01:40 AEST 2018 x86_64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz GenuineIntel GNU/Linux

    • Patch:
      Code

      Description

      Affects: 1.10.271 with CLJS-2402.patch

      I have a minimal repro repo here: https://github.com/au-phiware/cljs-in-js-in-cljs

      Description of problem

      The compiler appears to know node modules that are required from foreign libs by two different names, but the cljs_deps.js file only uses one of them. In the repro case below, unique-random is referenced as both module$unique_random and module$usr$src$cljs_in_js_in_cljs$node_modules$unique_random$index in the compiled output of the foreign lib (}target/main.out/es6/hello.js}), but {{cljs_deps.js only specifies module$usr$src$cljs_in_js_in_cljs$node_modules$unique_random$index as its provides.

      Steps to reproduce the problem

      Consider the following source files:

      src/hello/core.cljs
      (ns hello.core (:require [unique-random]
                               [hello :refer [greet]]))
      
      (greet "test")
      
      es6/hello.js
      import random from "unique-random";
      export var greet = function(m) {
          document.write("Hello, " + m + random(1, 100)());
      };
      
      build.clj
      (require 'cljs.build.api)
      
      (cljs.build.api/build
        "src"
        {:main 'hello.core
         :output-to "target/main.js"
         :output-dir "target/main.out"
         :asset-path "main.out"
         :foreign-libs [{:file "es6"
                         :module-type :es6}]
         :install-deps true
         :npm-deps {:unique-random "latest"}})
      

      Execute cljs:

      java -cp cljs.jar:src clojure.main build.clj
      

      Expected outcome

      cljs should produce nothing to the standard output, exit cleanly and write the following files (approximately).

      target/main.js
      var CLOSURE_UNCOMPILED_DEFINES = {};
      var CLOSURE_NO_DEPS = true;
      if(typeof goog == "undefined") document.write('<script src="main.out/goog/base.js"></script>');
      document.write('<script src="main.out/goog/deps.js"></script>');
      document.write('<script src="main.out/cljs_deps.js"></script>');
      document.write('<script>if (typeof goog == "undefined") console.warn("ClojureScript could not load :main, did you forget to specify :asset-path?");</script>');
      document.write('<script>goog.require("process.env");</script>');
      document.write('<script>goog.require("hello.core");</script>');
      
      target/main.out/cljs_deps.js
      goog.addDependency("base.js", ['goog'], []);
      goog.addDependency("../cljs/core.js", ['cljs.core'], ['goog.string', 'goog.Uri', 'goog.object', 'goog.math.Integer', 'goog.string.StringBuffer', 'goog.array', 'goog.math.Long']);
      goog.addDependency("../process/env.js", ['process.env'], ['cljs.core']);
      goog.addDependency("../node_modules/unique-random/index.js", ['module$unique_random', 'module$usr$src$cljs_in_js_in_cljs$node_modules$unique_random$index'], []);
      goog.addDependency("../es6/hello.js", ['module$usr$src$cljs_in_js_in_cljs$es6$hello'], ['module$unique_random']);
      goog.addDependency("../hello/core.js", ['hello.core'], ['cljs.core', 'module$usr$src$cljs_in_js_in_cljs$node_modules$unique_random$index', 'module$usr$src$cljs_in_js_in_cljs$es6$hello']);
      
      target/main.out/es6/hello.js
      goog.provide("module$usr$src$cljs_in_js_in_cljs$es6$hello");
      goog.require("module$unique_random");
      var greet$$module$usr$src$cljs_in_js_in_cljs$es6$hello=function(m){document.write("Hello, "+m+module$usr$src$cljs_in_js_in_cljs$node_modules$unique_random$index["default"](1,100)())};var module$usr$src$cljs_in_js_in_cljs$es6$hello={};module$usr$src$cljs_in_js_in_cljs$es6$hello.greet=greet$$module$usr$src$cljs_in_js_in_cljs$es6$hello
      
      target/main.out/hello/core.js
      // Compiled by ClojureScript 1.10.272 {}
      goog.provide('hello.core');
      goog.require('cljs.core');
      goog.require('module$usr$src$cljs_in_js_in_cljs$node_modules$unique_random$index');
      goog.require('module$usr$src$cljs_in_js_in_cljs$es6$hello');
      module$usr$src$cljs_in_js_in_cljs$es6$hello.greet("test");
      

      Caveat

      The expected outcome was derived from the actual outcome with the minimal set of changes required to produce the desired outcome (i.e. working in the browser without error).

      Alternatively, all references to module$unique_random could be replaced with module$usr$src$cljs_in_js_in_cljs$node_modules$unique_random$index, for the same desired outcome.

      Actual outcome

      The cljs_deps.js file is missing the module$unique_random provides name for the node module.

      target/main.out/cljs_deps.js
      goog.addDependency("base.js", ['goog'], []);
      goog.addDependency("../cljs/core.js", ['cljs.core'], ['goog.string', 'goog.Uri', 'goog.object', 'goog.math.Integer', 'goog.string.StringBuffer', 'goog.array', 'goog.math.Long']);
      goog.addDependency("../process/env.js", ['process.env'], ['cljs.core']);
      goog.addDependency("../node_modules/unique-random/index.js", ['module$usr$src$cljs_in_js_in_cljs$node_modules$unique_random$index'], []);
      goog.addDependency("../es6/hello.js", ['module$usr$src$cljs_in_js_in_cljs$es6$hello'], ['module$unique_random']);
      goog.addDependency("../hello/core.js", ['hello.core'], ['cljs.core', 'module$usr$src$cljs_in_js_in_cljs$node_modules$unique_random$index', 'module$usr$src$cljs_in_js_in_cljs$es6$hello']);
      

      The following is the diff output for clarity.

      diff --git a/target/main.out/cljs_deps.js b/target/main.out/cljs_deps.js
      index dd4df1f..de77e67 100644
      --- a/target/main.out/cljs_deps.js
      +++ b/target/main.out/cljs_deps.js
      @@ -1,6 +1,6 @@
       goog.addDependency("base.js", ['goog'], []);
       goog.addDependency("../cljs/core.js", ['cljs.core'], ['goog.string', 'goog.Uri', 'goog.object', 'goog.math.Integer', 'goog.string.StringBuffer', 'goog.array', 'goog.math.Long']);
       goog.addDependency("../process/env.js", ['process.env'], ['cljs.core']);
      -goog.addDependency("../node_modules/unique-random/index.js", ['module$unique_random', 'module$usr$src$cljs_in_js_in_cljs$node_modules$unique_random$index'], []);
      +goog.addDependency("../node_modules/unique-random/index.js", ['module$usr$src$cljs_in_js_in_cljs$node_modules$unique_random$index'], []);
       goog.addDependency("../es6/hello.js", ['module$usr$src$cljs_in_js_in_cljs$es6$hello'], ['module$unique_random']);
       goog.addDependency("../hello/core.js", ['hello.core'], ['cljs.core', 'module$usr$src$cljs_in_js_in_cljs$node_modules$unique_random$index', 'module$usr$src$cljs_in_js_in_cljs$es6$hello'])
      

      Furthermore, if optimisations is turned on (e.g. :optimizations :simple) the following error is observed from cljs.

      stderr
      May 01, 2018 5:50:49 PM com.google.javascript.jscomp.LoggerErrorManager println
      SEVERE: /usr/src/cljs-in-js-in-cljs/target/main.out/es6/hello.js:2: ERROR - required "module$unique_random" namespace never provided
      goog.require("module$unique_random");
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      
      May 01, 2018 5:50:49 PM com.google.javascript.jscomp.LoggerErrorManager printSummary
      WARNING: 1 error(s), 0 warning(s)
      ERROR: JSC_MISSING_PROVIDE_ERROR. required "module$unique_random" namespace never provided at /usr/src/cljs-in-js-in-cljs/target/main.out/es6/hello.js line 2 : 0
      Exception in thread "main" java.lang.Exception: Closure compilation failed, compiling:(/usr/src/cljs-in-js-in-cljs/build.clj:3:1)
      	at clojure.lang.Compiler.load(Compiler.java:7526)
      	at clojure.lang.Compiler.loadFile(Compiler.java:7452)
      	at clojure.main$load_script.invokeStatic(main.clj:278)
      	at clojure.main$script_opt.invokeStatic(main.clj:338)
      	at clojure.main$script_opt.invoke(main.clj:333)
      	at clojure.main$main.invokeStatic(main.clj:424)
      	at clojure.main$main.doInvoke(main.clj:387)
      	at clojure.lang.RestFn.applyTo(RestFn.java:137)
      	at clojure.lang.Var.applyTo(Var.java:702)
      	at clojure.main.main(main.java:37)
      Caused by: java.lang.Exception: Closure compilation failed
      	at cljs.closure$report_failure.invokeStatic(closure.clj:389)
      	at cljs.closure$optimize.invokeStatic(closure.clj:1422)
      	at cljs.closure$optimize.doInvoke(closure.clj:1382)
      	at clojure.lang.RestFn.applyTo(RestFn.java:139)
      	at clojure.core$apply.invokeStatic(core.clj:659)
      	at cljs.closure$build.invokeStatic(closure.clj:2866)
      	at cljs.build.api$build.invokeStatic(api.clj:207)
      	at cljs.build.api$build.invoke(api.clj:189)
      	at cljs.build.api$build.invokeStatic(api.clj:195)
      	at cljs.build.api$build.invoke(api.clj:189)
      	at user$eval34.invokeStatic(build.clj:3)
      	at user$eval34.invoke(build.clj:3)
      	at clojure.lang.Compiler.eval(Compiler.java:7062)
      	at clojure.lang.Compiler.load(Compiler.java:7514)
      	... 9 more
      

        Attachments

          Activity

            People

            • Assignee:
              dnolen David Nolen
              Reporter:
              phiware Corin Lawson
            • Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: