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

欢迎!请参阅 关于 页面以了解更多关于此工作的信息。

0
ClojureScript

(def a 3)

`
$ clj -Srepro -m cljs.main
java.lang.IllegalArgumentException: /var/folders/gx/nymj3l7x4zq3gxb97v2zwzb40000gn/T/out6255758032123683761473031144485066/cljs/user/userAE725FA.js 是一个绝对路径,不是相对路径

at clojure.java.io$as_relative_path.invokeStatic(io.clj:414)
at clojure.java.io$file.invokeStatic(io.clj:426)
at clojure.java.io$file.invoke(io.clj:418)
at cljs.closure$compile_file.invokeStatic(closure.clj:633)
at cljs.closure$compile_file.invoke(closure.clj:625)
at cljs.closure$fn__5175.invokeStatic(closure.clj:721)
at cljs.closure$fn__5175.invoke(closure.clj:715)
at cljs.closure$fn__5088$G__5081__5095.invoke(closure.clj:543)
at cljs.closure$compile.invokeStatic(closure.clj:595)
at cljs.closure$compile.invoke(closure.clj:592)
at cljs.repl$load_file$fn__6454.invoke(repl.cljc:601)
at cljs.repl$load_file.invokeStatic(repl.cljc:600)
at cljs.repl$load_file.invoke(repl.cljc:592)
at cljs.repl$repl_STAR_$maybe_load_user_file__6612.invoke(repl.cljc:958)
at cljs.repl$repl_STAR_$fn__6621$fn__6622.invoke(repl.cljc:989)
at cljs.repl$repl_STAR_$fn__6621.invoke(repl.cljc:982)
at cljs.compiler$with_core_cljs.invokeStatic(compiler.cljc:1289)
at cljs.compiler$with_core_cljs.invoke(compiler.cljc:1278)
at cljs.repl$repl_STAR_.invokeStatic(repl.cljc:979)
at cljs.repl$repl_STAR_.invoke(repl.cljc:855)
at cljs.cli$repl_opt.invokeStatic(cli.clj:305)
at cljs.cli$repl_opt.invoke(cli.clj:292)
at cljs.cli$main.invokeStatic(cli.clj:638)
at cljs.cli$main.doInvoke(cli.clj:625)
at clojure.lang.RestFn.invoke(RestFn.java:410)
at clojure.lang.AFn.applyToHelper(AFn.java:154)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.core$apply.invokeStatic(core.clj:659)
at clojure.core$apply.invoke(core.clj:652)
at cljs.main$_main.invokeStatic(main.clj:61)
at cljs.main$_main.doInvoke(main.clj:52)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.lang.Var.applyTo(Var.java:702)
at clojure.core$apply.invokeStatic(core.clj:657)
at clojure.main$main_opt.invokeStatic(main.clj:317)
at clojure.main$main_opt.invoke(main.clj:313)
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)

ClojureScript 1.10.339
cljs.user=>
`

如果您指定了一个输出目录(通过 {{-d}}),则一切都会正常。

7 答案

0

评论者:uosl

由于在未使用临时输出目录的情况下运行时,cljs.closure/compile-file 被传递了一个包含绝对路径的 File 对象作为输出文件,因此发生了错误。compile-file 只与输出文件是相对路径字符串或 File 对象一起工作,因此我已经将其修改为同时支持绝对路径 File 对象。这样,您就可以使用 cljs.closure/src-file->target-file 与它一起使用。

0

评论者:mfikes

请注意,Herald 通过私人 Slack 消息告诉我,CA 已被签署。

0
_评论者:mfikes_

如果您使用默认的浏览器 REPL,则补丁对于票据描述有效,但是在 macOS 上如果指定 Node REPL,您将看到与临时目录路径规范相关的失败。


使用以下命令:$ clj -Sdeps '{:deps {:org.clojure/clojurescript {:local/root "/Users/mfikes/Projects/clojurescript"}}}' -m cljs.main -re node -r
cljs.user=> 在线程 "main" 中发生异常 java.lang.AssertionError: 断言失败:输出文件/private/tmp/cljs-2917/cljs/core.js 不在输出目录 /var/folders/gx/nymj3l7x4zq3gxb97v2zwzb40000gn/T/out5998260788018592691311499618489419
(string/starts-with? (util/path output-file) out-dir)
    在 closure.clj:636 处调用 cljs.closure$compile_file.invokeStatic(closure.clj:636)
    在 closure.clj:625 处调用 cljs.closure$compile_file.invoke(closure.clj:625)
    在 closure.clj:730 处调用 cljs.closure$eval7272$fn__7273.invoke(closure.clj:730)
    在 closure.clj:543 处调用 cljs.closure$eval7175$fn__7176$G__7164__7183.invoke(closure.clj:543)
    在 closure.clj:739 处调用 cljs.closure$eval7278$fn__7279.invoke(closure.clj:739)
    在 closure.clj:543 处调用 cljs.closure$eval7175$fn__7176$G__7164__7183.invoke(closure.clj:543)
    在 closure.clj:595 处调用 cljs.closure$compile.invokeStatic(closure.clj:595)
    在 closure.clj:592 处调用 cljs.closure$compile.invoke(closure.clj:592)
    在 node.clj:164 处调用 cljs.repl.node$setup$fn__9880.invoke(node.clj:164)
    在 node.clj:131 处调用 cljs.repl.node$setup.invokeStatic(node.clj:131)
    在 node.clj:124 处调用 cljs.repl.node$setup.invoke(node.clj:124)
    在 node.clj:236 处调用 cljs.repl.node.NodeEnv._setup(node.clj:236)
    在 repl.cljc:951 处调用 cljs.repl$repl_STAR_$fn__8878.invoke(repl.cljc:951)
    在 compiler.cljc:1416 处调用 cljs.compiler$with_core_cljs.invokeStatic(compiler.cljc:1416)
    在 compiler.cljc:1405 处调用 cljs.compiler$with_core_cljs.invoke(compiler.cljc:1405)
    在 repl.cljc:949 处调用 cljs.repl$repl_STAR_.invokeStatic(repl.cljc:949)
    在 repl.cljc:861 处调用 cljs.repl$repl_STAR_.invoke(repl.cljc:861)
    在 cli.clj:314 处调用 cljs.cli$repl_opt.invokeStatic(cli.clj:314)
    在 cli.clj:301 处调用 cljs.cli$repl_opt.invoke(cli.clj:301)
    在 cli.clj:646 处调用 cljs.cli$main.invokeStatic(cli.clj:646)
    在 cli.clj:635 处调用 cljs.cli$main.doInvoke(cli.clj:635)
    在 RestFn.java:139 处调用 clojure.lang.RestFn.applyTo(RestFn.java:139)
    在 core.clj:659 处调用 clojure.core$apply.invokeStatic(core.clj:659)
    在 core.clj:652 处调用 clojure.core$apply.invoke(core.clj:652)
    在 main.clj:61 处调用 cljs.main$_main.invokeStatic(main.clj:61)
    在 main.clj:52 处调用 cljs.main$_main.doInvoke(main.clj:52)
    在 RestFn.java:137 处调用 clojure.lang.RestFn.applyTo(RestFn.java:137)
    在 Var.java:702 处调用 clojure.lang.Var.applyTo(Var.java:702)
    在 core.clj:657 处调用 clojure.core$apply.invokeStatic(core.clj:657)
    在 main.clj:317 处调用 clojure.main$main_opt.invokeStatic(main.clj:317)
    在 main.clj:313 处调用 clojure.main$main_opt.invoke(main.clj:313)
    在 main.clj:424 处调用 clojure.main$main.invokeStatic(main.clj:424)
    在 main.clj:387 处调用 clojure.main$main.doInvoke(main.clj:387)
    在 RestFn.java:137 处调用 clojure.lang.RestFn.applyTo(RestFn.java:137)
    在 Var.java:702 处调用 clojure.lang.Var.applyTo(Var.java:702)
    在 main.java:37 处调用 clojure.main.main(main.java:37)


我认为这个问题可以通过断言来修复


(same-or-subdirectory-of? out-dir output-file)


代替


(string/starts-with? (util/path output-file) out-dir)


关于补丁的另一件事情让我感到担忧,{{output-file}} 可能是一个 _相对_ 的 {{File}},在这种情况下


(io/file out-dir output-file)


是一个合法的构造,代码应该处理那个分支。在我看来,只有当 {{out-file}} 是 _绝对_(要么是一个字符串,要么是 {{File}})时,它应该“原样”处理,而不是相对于 {{out-dir}}。换句话说,条件可能不是它满足 {{util/file?}},而是 {{absolute-path?}}。

如果我们考虑这两个更改(使用 {{absolute-path?}} 触发逻辑,以及使用 {{same-or-subdirectory-of?}} 进行断言),这可能涵盖所有情况。(这两个函数都需要在 {{compile-file}} 之后声明为 {{declare}}。)
0

评论者:uosl

再次感谢,Mike。我成功在 Linux 上重现了您的错误,对逻辑和断言都做了您建议的更改,并确认问题已修复。我还将 {{output-file}} 返回的 {{if}} 布尔分支包裹在了一个 {{io/file}} 调用中,否则如果提供了一个绝对路径字符串,我担心它将继续失败 {{(.exists out-file)}} 表达式进一步下。

0

评论者:mfikes

最新的补丁已通过 LGTM,表现正常,并通过了 CI 测试。

0

评论者:uosl

在修复 CLJS-2753 补丁的过程中,我发现该补丁还解决了这个问题。如果不想在 compile-file 中支持绝对路径,则可以弃用该补丁,改用 CLJS-2753 补丁。关于 CLJS-2917.patch 中的 my commit messages tocljs.repl.rhino... 的描述是错误的;这些文件从 opts 中移除了 :output-dir,因此它们最终将相对路径传递给了 cljs.closure/compile-file。这没有为 cljs.repl/load-file 做过,从而导致了这两个问题。

0
参考:https://clojure.atlassian.net/browse/CLJS-2917 (由 mfikes 报告)
...