这与 CLJS-2205 和 CLJS-2836 有关,尽管我认为它略有不同,并且我还提供了额外的(希望是有用的)信息。
当作为 npm-deps 使用时,"semantic-ui-react" 节点模块生成的代码无法加载。我能够想出的最小复制案例
{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"}}}
注意:我看到了与当前 master 版本完全相同的问题,当时为提交 [81a1ea12|
https://github.com/clojure/clojurescript/tree/81a1ea127974d43a6166fbdae33bcaa296fe9156] 安装本地为 1.10.394。
{noformat:title=src/hello_world/core.cljs}
(ns hello-world.core
(:require semantic-ui-react))
(println "Hello world!")
文件组织结构如下
$ tree
.
├── build_opts.edn
├── deps.edn
└── src
└── hello_world
└── core.cljs
执行
clj -m cljs.main -co build_opts.edn -c hello-world.core
生成的代码无法以以下方式加载。首先,对于那些具有 {{index.js}} 文件的模块似乎缺少提供语句;例如
{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"]}}
在其他地方以“全路径”形式要求,不包含最后的“index”
{noformat:title=out/node_modules/semantic-ui-react/dist/es/index.js (省略)}
...
goog.require("module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm");
...
这导致了一个错误,表示 nameToPath 无法找到模块 {{"module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm"}}。我通过修改 ClojureScript 编译器(如果当前源文件以 {{index}} 结尾,则在 {{cljs.closure/add-converted-source}} 中添加额外的 {{goog.provides}}),从而解决了这个问题,但后来发现存在第二个问题(这让我怀疑我的方法是否是正确的修复方式),因为生成的代码实际上尝试使用带有索引部分的完全合格的模块名称
{noformat:title=out/node_modules/semantic-ui-react/dist/es/index.js (省略)}
...
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"]},
...
这抛出了一个错误,说明变量{{module$Users$gary$sparrho$cljs_bug_report$node_modules$semantic_ui_react$dist$es$addons$Confirm$index}}没有定义。
我对ClojureScript编译器、Google Closure编译器或ES6模块系统完全不熟悉,这对于我进一步调查来说非常困难。我已经证实,在生成requires和provides调用({{cljs.closure/add-converted-source}})时,表示依赖关系的Closure对象在结尾处不包含{{index}}部分,这与生成的{{goog.requires}}调用一致。{{goog.provides}}调用似乎是根据在{{src/main/cljs/cljs/module_deps.js}}中完成的js文件分析独立生成的。我无法确定的是(因此我遇到了阻碍),是哪段代码生成尝试访问“错误”变量名的JS代码。这可能是ClojureScript未生成正确的{{goog.requires}}调用的一个错误,或者可能是Closure没有在其{{Require}}对象上生成与JS变量相同的名称的错误。