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

欢迎!请参阅关于页面了解如何使用本网站更多信息。

0
ClojureScript
h2. 复现步骤

给定

{code:title=deps.edn}
{:paths
 ["."]

 :deps
 {org.clojure/clojurescript {:mvn/version "1.10.339"
                             #_#_:git/url "https://github.com/clojure/clojurescript.git"
                             #_#_:sha "6eedd0a08c49f7b0d4dcb30977b2fb38c90577bd"}}}


{code:title=foo.cljs}
(ns foo
  (:require [goog.log :as glog])
  (:import goog.debug.Console))

(def logger
  (glog/getLogger "app"))

(def console (goog.debug.Console.))

(defn workaround! []
  (.setConsole goog.debug.Console js/console))


(defn -main [& args]
  (.setCapturing console true)
  (.setLevel logger goog.debug.Logger.Level.FINEST)

  (when args
    (workaround!))
  (glog/error logger "某些错误"))

(set! *main-cli-fn* -main)


当以`none`优化编译并运行时,日志可见

$ clj -m cljs.main -v -O none -t node -c foo
$ node out/main.js
 [  0.002s] [app] 某些错误


当以`simple`(或`advanced`)优化编译并运行时,日志不可见。

预期:simple优化不应影响在Node上的日志可见性(类似于浏览器编译)。

h2. 一些其他情况(FWIW)

在simple中,`goog.debug.Console.console_`最终为nil,因为`goog.global['console']`为nil (https://github.com/google/closure-library/blob/master/closure/goog/debug/console.js#L169)。

`println`在none和simple中都有效。

当针对浏览器时,none和simple都显示日志。

一个解决方案是设置Console: `(.setConsole goog.debug.Console js/console)`

2 个答案

0

评论由:thheller发布

FWIW在{{node}}中问题在于{{goog.global}}没有被正确分配。

在 {{goog/base.js}} 中,它被分配给 {{goog.global = this;}},但是在 {{node}} 中 {{this}} 是当前的 {{Module}} 实例,而不是通常的 {{window}}。{{module.console}} 不存在,所以没有正确分配。在开发过程中,由于 nodejs bootstrap 明确加载了带有 {{global}} 作为 {{this}} 的代码(链接:1),所以它的工作方式不同。在生产中不会这样做,因此“默认”的 {{this}} 成为 {{module}} 并破坏了优化的代码。

我认为仅仅总是使用 workaround! 是完全可以的,因为它不会破坏任何东西。

(链接:1) https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/bootstrap_nodejs.js#L114

0
参考: https://clojure.atlassian.net/browse/CLJS-2930(由 alex+import 报告)
...