2024 Clojure 状态调查!中分享您的想法。

欢迎!请在关于页面了解更多关于其工作方式的信息。

0 投票
ClojureScript
使用模块化处理(CJS/ES6)的 JavaScript 代码可以使用例如 {{goog.require("name.space")}} 或 {{import * from "goog:name.space";}} 来要求 ClojureScript 命名空间。但当前如果此命名空间只由 JS 模块使用而不是其他 ClojureScript 命名空间,则 Closure 优化会失败。

当 {{build}} {{source}} 是单个文件,或者当 {{:optimization}} 和 {{:main}} 被设置时,会发生此情况,因为在这种情况下,构建入口点是 {{:main}} 文件。

问题在于在构建管道中,在添加 {{:libs}} 中的 JS 文件(包括模块处理中的文件)后,不会将新的 ClojureScript 源代码添加到构建中:https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/closure.clj#L2809-L2819

使用 {{:optimization :none}},构建过程中不会显示错误,但会在运行时出现关于缺少模块的错误。使用优化,Closure 将抛出关于缺少模块的错误。


;; 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"
   :optimizations :simple
   :foreign-libs [{:file "src"
                   :module-type :es6}]})

;; 或者 "src/hello/core.cljs" 作为源文件,并且 :optimization :one

;; src/hello/core.cljs
(ns hello.core (:require [hello.es-module :refer [greet]]))

(greet "test")

;; src/hello/say.cljs
(ns hello.say)
(defn ^:export it [m]
  (str "Hello, " m))

;; src/hello/es_module.js
import it from "goog:hello.say";

export var greet = function(m) {
    document.write(hello.say.it(m));
};


Closure 错误

Mar 27, 2018 7:02:07 PM com.google.javascript.jscomp.LoggerErrorManager printSummary
WARNING: 1 error(s), 0 warning(s)
ERROR: JSC_MISSING_PROVIDE_ERROR. required "hello.say" namespace never provided at /home/juho/tmp/cljs-in-js-in-cljs/target/main.out/src/hello/es_module.js line 2 : 0
Exception in thread "main" java.lang.Exception: Closure 编译失败, compiling:(/home/juho/tmp/cljs-in-js-in-cljs/build.clj:3:1)

2 个回答

0 投票

评论由:deraen 创建

我认为我知道需要做什么。构建管道({{build}}和{{compile-inputs}} 函数)需要进行重构,以调用{{add-dependency-sources}},这属于{{handle-js-modules}}和{{add-js-sources}},直到没有新源被发现。JS模块处理需要分为两部分:一部分查找必需的JS模块及其依赖项的信息,另一部分处理所有JS模块。

0 投票
参考:https://clojure.atlassian.net/browse/CLJS-2709(由 deraan 提出)
...