- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个函数库,我想让用户在浏览器中使用它。
所以我想设置这样的情况:
我正在使用 figwheel 和 devcards 进行开发。
在主core.cljs中我require
我的库中的各种功能,所以它们都在范围内。
现在我想让用户输入一些调用该库的代码。
我知道如何使用 eval 运行该代码,但我看不到如何使我的库函数对正在评估的代码可见。
我对我看到的大多数文档感到困惑(例如 How can I make functions available to ClojureScript's eval? )
是否可以?如果是这样,有没有人有一个简单的例子来完成它?
干杯
菲尔
最佳答案
是的,可以提供对评估代码使用的环境/预编译库的访问。
首先,您必须确保库中的函数在 JavaScript 运行时可用。换句话说,避免 :advanced
优化,因为这将消除在编译时 (DCE) 未调用的函数。自托管 ClojureScript 兼容 :simple
.
其次,您需要将分析元数据提供给将在浏览器中运行的自托管编译器(使用 cljs.js/load-analysis-cache!
或 cljs.js/empty-state
的可选参数)。
说明如何执行此操作的最小项目如下(也在 https://github.com/mfikes/ambient ):
项目代码src/main/core.cljs
:
(ns main.core
(:require-macros [main.core :refer [analyzer-state]])
(:require [cljs.js]
[library.core]))
(def state (cljs.js/empty-state))
(defn evaluate [source cb]
(cljs.js/eval-str state source nil {:eval cljs.js/js-eval :context :expr} cb))
(defn load-library-analysis-cache! []
(cljs.js/load-analysis-cache! state 'library.core (analyzer-state 'library.core))
nil)
src/main.core.clj
:
(ns main.core
(:require [cljs.env :as env]))
(defmacro analyzer-state [[_ ns-sym]]
`'~(get-in @env/*compiler* [:cljs.analyzer/namespaces ns-sym]))
src/library/core.cljs
:
(ns library.core)
(defn my-inc [x]
(inc x))
main.core
提供
evaluate
的命名空间函数,此示例将展示如何在环境/预编译
library.core
中调用函数命名空间。
clj -m cljs.main
(require 'main.core)
(main.core/evaluate "(+ 2 3)" prn)
{:ns cljs.user, :value 5}
main.core
需要
library.core
,我们可以调用该命名空间中的函数。在 REPL 上进行评估将产生
11
:
(library.core/my-inc 10)
(main.core/evaluate "(library.core/my-inc 10)" prn)
WARNING: No such namespace: library.core, could not locate library/core.cljs, library/core.cljc, or JavaScript source providing "library.core" at line 1
WARNING: Use of undeclared Var library.core/my-inc at line 1
{:ns cljs.user, :value 11}
library.core.my_inc
在 JavaScript 环境中可用,并且确实可以被调用,产生正确的答案,你会收到来自自托管编译器的警告,它对这个命名空间一无所知。
main.core/state
中。原子。 (自托管编译器有自己的分析状态,保存在 JavaScript 环境中的原子中,与 JVM 编译器分析状态分开,通过 Java 环境中的 Clojure 保存。)
Note: If we instead had the source for
library.core
compiled by the self-hosted compiler (by perhaps by usingmain.core/evaluate
to eval"(require 'library.core)"
, along with properly defining acljs.js/*load-fn*
that could retrieve this source, things would be good, and the compiler analysis metadata would be inmain.core/state.
But this example is about calling ambient / pre-compiled functions inlibrary.core
.
cljs.js/load-analysis-cache!
来解决这个问题。加载与
library.core
关联的分析缓存命名空间。
(main.core/analyzer-state 'library.core)
(main.core/load-library-analysis-cache!)
(main.core/evaluate "(library.core/my-inc 10)" prn)
{:ns cljs.user, :value 11}
libraray.core
的分析元数据。 ,它可以正确警告 arity 错误,例如
(main.core/evaluate "(library.core/my-inc 10 12)" prn)
WARNING: Wrong number of args (2) passed to library.core/my-inc at line 1
cljs.js/load-analysis-cache!
修复它。 .如果你知道你总是想在启动时加载缓存,你可以简单地使用
cljs.js/empty-state
的可选参数。在初始化时加载这个缓存:
(defn init-state [state]
(assoc-in state [:cljs.analyzer/namespaces 'library.core]
(analyzer-state 'library.core)))
(def state (cljs.js/empty-state init-state))
关于namespaces - 如何在 ClojureScript 中运行 eval 并访问调用 eval 的命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51573858/
如何从 clojurescript 程序中获取我所在的 Clojurescript 命名空间?我想这样做确实提供了某些调试信息(它只需要在开发模式下工作) 最佳答案 命名空间在 ClojureScri
我正在考虑使用 ClojureScript 构建一个网站。在客户端和服务器端都编写 ClojureScript 是否有意义,就像 node.js 一样? 最佳答案 这是可能的,但绝对没有理由不在服务器
我正在与Om合作,但我不完全理解以下表达式: (.. e -target -checked) 在这里,“ e”是一个JavaScript事件,“-target -checked”是一种访问属性的方式
我想在 ClojureScript 中前向声明一个函数。种 (defn a [] (b)) ... (defn b [] ...) 我觉得在用法(b)前面放一个(def b nil)是个什么样的作品,
我想在 ClojureScript 中前向声明一个函数。种 (defn a [] (b)) ... (defn b [] ...) 我觉得在用法(b)前面放一个(def b nil)是个什么样的作品,
我不知道像 this 这样的“自托管”clojurescript 实现如何和 this被实现。 但是,鉴于 clojurescript 编译器是用 clojure 编写的并将 clojure 编译为
考虑以下假设的无意义的 ClojureScript 函数: (defn tmp [] (def p 0) (set! p (inc p)) (set! p (inc p)) (set!
我在生产构建部分遇到问题 ClojureScript quickstart .具体来说,当我运行时:java -cp "cljs.jar;src" clojure.main release.clj我得
我正在尝试使用 defmacro在 ClojureScript 中,但出现控制台错误: TypeError: 'undefined' is not an object (evaluating 'crd
我正在寻找一种在 clojureScript 中根据字符串名称调用函数的方法。 就像是: (call "my-fun" args) 欢迎任何帮助 最佳答案 一个应该有效的非常hackish的解决方案:
在 Ubuntu 10.04.1 LTS 上的 FireFox 5.0 中运行的 ClojureScript 程序中,当抛出异常时,我得到一条神秘的线。 '错误:没有为类型对象定义协议(protoco
我正在努力工作 FormidableLabs/radium · GitHub与 reagent-project/reagent · GitHub ,但我已经走到了死胡同。 我能够通过“破解”试剂功能使
是否可以将 Google Closure Templates 与 Clojurescript 一起使用? 我环顾四周,但没有找到任何有关此的信息。 最佳答案 由于 Soy 模板已编译为 JavaScr
我想从 clojurescript 设置 element.style.height 属性,但不幸的是这段代码失败了: (set! (-> (sel1 tr :.ragslide) .-style .-
我正在使用 ClojureScript 编写一些原子(编辑器)包。我遇到了依赖加载问题。 编译后的 ClojureScript 生成如下文件 (main.js): goog.addDependency
我正在为 clojurescript 库编写一些 cljs.test 测试,并且有一些我想加载的 JSON 测试数据。 我不确定我可以使用什么函数来从项目的本地文件加载数据。 我正在使用 lein-d
我有一个从 Leiningen 启动的 ClojureScript 应用程序。我如何在应用程序启动时将环境变量传递给应用程序(可能是它构建时) 最佳答案 有两个构建时间选项: 使用宏 CLJS 宏是
如何在 ClojureScript 中获取时间戳,类似于 Unix 的时间戳,即表示当前时间和日期的单个数字,作为数字。我知道: if (!Date.now) { Date.now = fun
我需要使用 ClojureScript 打开一个新选项卡。 (js/window.open "http://localhost/go/somewhere") 我收到以下错误:未捕获类型错误:windo
我已经阅读了 David Nolen 的基本 Om 教程,但我仍然对应用程序状态和组件本地状态之间的区别感到有些困惑。当引用游标时,它是否也引用了其中之一或两者? 最佳答案 据我了解: 应用程序状态是
我是一名优秀的程序员,十分优秀!