我经常发现自己在clojurescript中定义名称空间,其中只包含通过def或defn创建的单个var,我将在该名称空间之外使用。
这在使用reagent时尤其常见,我在单独的文件/命名空间中定义我的组件,我只在命名空间之外使用这些单个组件。
(ns project.components.component-name)
(defn component-name ...)
所以我以这种方式导入它们,我发现它非常重复且不清楚,因为命名空间和组件都有一个名称:
project.components.component-name :as [component-name]
component-name/component-name
或inferior:refer(因为var来自另一个名称空间不太明显)
project.components.component-name :refer [component-name]
component-name
我知道在ECMAScript中有一个有用的模式:
export default function () { ... };
在Clojure中有这样的东西吗?或许也有一些既定的惯例?
以下是我最近开始使用的惯例,我对此非常不确定。
(ns project.components.component-name)
(defn _ ...)
project.components.component-name :as [component-name]
然后将其用作
component-name/_
答案 0 :(得分:1)
下划线通常用于您在Clojure中不关心的值,因此我强烈建议您避免使用_
作为函数名称。例如,您经常会看到如下的代码:
;; Maybe when destructuring a let. Kinda contrived example.
(let [[a _ _ d] (list 1 2 3 4)]
(+ a d 10))
;; Quite often in a protocol implementation where we don't care about 'this'.
(defrecord Foo []
SomeProtocol
(thing [_ x]
(inc x)))
在命名空间中使用单个var没有任何问题,尽管我可能只会在有合理的功能块时引入命名空间。您可以尝试使用像my-app.components
这样的命名空间,在那里保留所有小位,直到它们足够大以保证专用空间。有点像这样:
(ns my-app.components
;; The profile stuff is really big lets say.
(:require [my-app.components.profile :as profile]))
(defn- items->ul
[items]
[:ul (map #(vector :li (:text %)) items)])
(defn- render-nav
[state]
[:nav (-> state deref :nav-items items->ul)])
(defn- render-footer
[state]
[:footer (-> state deref :footer-items items->ul)])
(defn render-layout
[state]
[:html
[:head [:title (:title @state)]]
[:body
[:main
(render-nav state)
(profile/render-profile (-> state deref :current-user))
(render-footer state)]]])
答案 1 :(得分:1)
我不确定每个命名空间中的一个组件是最好的方法。这将导致 在大量的命名空间和相当多的重复。但是,这是 clojure和每个人都有不同的风格。我的方法是使用命名空间 分解功能。随着变化最简单 组件,我发现一个组件也不会使用其他组件 组件。我倾向于将所有使用的组件组合在一起 特定功能和用于大多数情况下的各种低级组件 其他组件,有/ utility /或/ base / namespace。例如,我可能 有类似的东西
project --|
src --|
my-app --|
core.cljs
interface --|
base.cljs
navbar.cljs
sidebar.cljs
tabber.cljs
在每个名称空间中,可能有多个组件。其中一些可能 被定义为该命名空间的私有,其他是其中的入口组件 由core.cljs引用。我发现名称空间要求部分也不会得到 大或重复,我不需要在不同的文件中跳转 因人而异。