summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreltrac <hi@eltr.ac>2026-10-01 09:59:17 +0800
committereltrac <hi@eltr.ac>2026-10-01 09:59:17 +0800
commit8573f45423236c3c93373f2ebb8ad106617b36b7 (patch)
tree2e759e3ab64079321fe72132659893dadc45d1bc
parentf468b65d371f35578d79dcada0ab4344a8bac987 (diff)
[draft] update
-rw-r--r--content/article/clj5.md93
-rw-r--r--content/weekly/101.md6
2 files changed, 97 insertions, 2 deletions
diff --git a/content/article/clj5.md b/content/article/clj5.md
index cb65ae1d..bdaff300 100644
--- a/content/article/clj5.md
+++ b/content/article/clj5.md
@@ -11,7 +11,7 @@ toc = true
在[第一篇](/article/clj1/)我们安装了 Leiningen,当时只是用它启动了 REPL 和 nREPL 服务器,现在我们要用它来干点重活儿了。顺带一提,Leiningen 的名字取自短篇故事《[莱宁根大战蚂蚁](https://en.wikipedia.org/wiki/Leiningen_Versus_the_Ants)》,故事情节…… 就是一个叫莱宁根的男人大战蚂蚁。
-## 创建项目并引入依赖
+## 创建项目
在终端输入 `lein new -h` 命令查看帮助,可以看到这些模板:
@@ -25,4 +25,95 @@ app An application project template.
模板只是提供了预先配置好的项目描述文件和项目结构,选哪个都不影响开发。简单来说,如果要写个 Clojure 库就用 `default`,如果要写应用程序就用 `app`。下文用 `app` 做示范。
+创建一个名叫 `antfighter` 的应用。
+
+```sh
+lein new app antfighter
+cd antfighter
+```
+
+```
+❯ tree
+.
+├── CHANGELOG.md
+├── doc
+│   └── intro.md
+├── LICENSE
+├── project.clj
+├── README.md
+├── resources
+├── src
+│   └── antfighter
+│   └── core.clj
+└── test
+ └── antfighter
+ └── core_test.clj
+
+7 directories, 7 files
+```
+
+项目默认生成的 `LICENSE` 是 [Eclipse Public License](https://en.wikipedia.org/wiki/Eclipse_Public_License),和 Clojure 一样。如果是写着玩儿的应用,可以直接删掉;如果要发布的话,建议考虑更换授权协议。
+
+除了 `.md` 文档,剩下的目录就和典型的 Java 项目非常像了。
+
+- `src/`:源代码,其中每一个目录下的文件都对应一个 Clojure 命名空间
+- `test/`:测试代码,可以用 `lein test` 执行里面的测试
+- `resources/`:代码使用的静态资源,包括 Web 资源,也可以是嵌入到软件里的其他程序,比如编译好的 WebAssembly
+
+说实话,我觉得这是 Clojure 从 Java 那里学来的*陋习*,不如 Go 的[标准布局](https://github.com/golang-standards/project-layout)。`src/` 目录只能让项目的最外层看起来整洁。除非是包含多个项目的 Monorepo,否则我不觉得 `src/` 这类目录有存在的必要。
+
+值得注意的是 `project.clj`,这是项目描述文件:
+
+```clojure
+(defproject antfighter "0.1.0-SNAPSHOT"
+ :description "FIXME: write description"
+ :url "https://example.com/FIXME"
+ :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
+ :url "https://www.eclipse.org/legal/epl-2.0/"}
+ :dependencies [[org.clojure/clojure "1.12.2"]]
+ :main ^:skip-aot antfighter.core
+ :target-path "target/%s"
+ :profiles {:uberjar {:aot :all
+ :jvm-opts ["-Dclojure.compiler.direct-linking=true"]}})
+```
+
+`defproject` 的第一个参数是项目名,第二个参数是版本号,`SNAPSHOT` 表示快照,正式发布时改成自己习惯的命名就好,比如 [Semantic Versioning](https://semver.org/)。
+
+余下的是可变长度的参数,要求是偶数个且以键值对的形式出现,就是映射的结构。除去 `:description`、`:url` 和 `:license` 这些顾名思义的选项,上述选项的意思分别是:
+
+- `:dependencies`:依赖项,应该是包含所有依赖声明的向量。向量的元素通常是长度为 `2` 的向量,第一个元素是依赖名,第二个元素是版本号。默认都应该加载 `org.clojure/clojure` 依赖项。
+- `:main`:项目的入口,即运行项目应该在哪个**命名空间**里找 `-main` 函数。
+- `:target-path`:和 Java 一样,`target` 就是编译产物存放的目录。
+- `:profiles`:可以为不同的运行环境和命令指定选项、参数和依赖项。
+ - `:uberjar`:Uberjar 也叫 Fat Jar。Clojure 和 Java 一样,最终编译为 `.jar` 文件,而 Uberjar 就是把所有依赖项都打包在内,可以独立运行的 `.jar`。这个 Profile 是执行 `lein uberjar` 编译命令时会用到的参数。
+
+更多的选项会在后文提及,也可以查看官方提供的 [sample.project.clj](https://codeberg.org/leiningen/leiningen/src/branch/stable/sample.project.clj)。
+
+## 核心
+
+```clojure
+(ns antfighter.core
+ (:gen-class))
+
+(defn -main
+ "I don't do a whole lot ... yet."
+ [& args]
+ (println "Hello, World!"))
+```
+
+```clojure
+(ns antfighter.core-test
+ (:require [clojure.test :refer :all]
+ [antfighter.core :refer :all]))
+
+(deftest a-test
+ (testing "FIXME, I fail."
+ (is (= 0 1))))
+```
+
+## 引入依赖
+
+## Leiningen 插件
+
+## 只给测试用的依赖
diff --git a/content/weekly/101.md b/content/weekly/101.md
index 0cf79fe5..8296b193 100644
--- a/content/weekly/101.md
+++ b/content/weekly/101.md
@@ -17,7 +17,7 @@ I say random stuff here.
## 吾仅悉落
-{{< music cover="" title="" artist="" bandcamp="" neodb="" >}}
+{{< music cover="https://img.eltr.ac/geedeapro/weekly/101/chapter1.jpg" title="chapter 1" artist="girl in red" neodb="https://neodb.social/album/4f7Vc6d42sapluwBrM86x6" >}}
---
@@ -103,6 +103,10 @@ He has a website: https://www.vernunft.org/
## 鸡头蛇尾
+### 市场真的有辨别力吗?
+
+https://akk.eltr.ac/notice/BAjowmDLStHbrRb8To
+
### WebAssembly in Anubis
https://anubis.techaro.lol/blog/2026/anubis-wasm/