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 "some error"))

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


当我使用优化 `none` 编译并运行时,日志会显示

$ clj -m cljs.main -v -O none -t node -c foo
$ node out/main.js
 [  0.002s] [app] some error


当我使用 `simple`(或 `advanced`)优化编译并运行时,日志不会显示。

期望:优化 simple 应该对 Node 上的日志显示没有影响(就像编译浏览器一样)。

h2. 各种信息(仅供参考)

在 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

关于{{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 报告)
...