来自clojure的clojurescript的命名空间是什么?

bmi*_*are 12 clojure clojurescript

我正在尝试理解clojurescript中的命名空间模型.我知道javascript不是内置的命名空间支持,所以它是通过谷歌闭包库添加的.但是,我不明白clojurescript如何处理这些差异.有人可以解释一下吗?

让我们说例如我想使用谷歌图表api,并尽可能使用高级编译.我在closure/build调用中使用了什么,ns表单的外观如何以及从代码中引用api的最佳方式是什么?我查看了https://github.com/sritchie/contour,但该示例不使用高级编译,我没有在project.clj文件中看到引用google api的选项.

sw1*_*1nn 12

无论您使用简单模式还是高级模式编译,名称空间声明都是相同的.不同之处在于,不通过文件明确引用goog.require('')并且goog.provide('')需要通过externs.js文件明确引用谷歌依赖关系管理的库.此文件传递给cljs编译器,提供所有变量和相关方法的存根.典型的externs.js看起来像:

// contents of externs.js
var externalLibrary = {}
var externalLibrary.method = function() {}
Run Code Online (Sandbox Code Playgroud)

因此,要引用谷歌闭包感知库,您的名称空间声明如下所示:

(ns my.namespace
  (:require  [goog.events.KeyCodes :as key-codes])
Run Code Online (Sandbox Code Playgroud)

这会发出以下javascript:

goog.provide("my.namespace");
goog.require("goog.events.keycodes");
Run Code Online (Sandbox Code Playgroud)

请注意,如果要从另一个javascript文件调用closurescript,则需要将方法标记为已导出,以便优化编译器知道保留名称.(例如,您可能在页面上有一个脚本标记,您可以从中调用从clojurescript生成的javascript函数)

看起来像这样:

(defn ^:export externallyCalled [])
Run Code Online (Sandbox Code Playgroud)

要注意的另一件事是你必须在clojurescript中以不同方式处理宏,这是因为在阅读器中"动态"处理它们的能力与clojure中的方式不同.

你这样做如下(请注意,您必须使用以下方式绑定宏:如本例所示)

(ns my.namespace
   (:require-macros [my.macros :as my]))
Run Code Online (Sandbox Code Playgroud)

如果您正在调用未参与Google依赖关系管理的代码,则可以通过js命名空间和javascript互操作来访问它...

(. js/nonGoogle (method args)) ; a method access

(. js/nonGoogle -p)  ; a property access 
Run Code Online (Sandbox Code Playgroud)

一切都很平常.变体也有效..