Clojure 构建工具 boot 粗略

粗略记录一些过去一天看 boot 的资料的一些感想, 但不会深入
大致的内容可以看一下官网和一篇比较热门的博客

http://boot-clj.com/
http://blog.michielborkent.nl/blog/2015/06/06/from-leiningen-to-boot/

关于

大致的情况我介绍下, 如果有刚学 Clojure 的同学, 虽然我也算新手...
Clojure 是基于 Java 的, 按照 jar 的方式打包成二进制文件
细节不准确, 但大致是把 classpath 的资源全映射到 target/ 目录然后打包的
Clojure 用 Maven 和 Clojars 两个官方仓库, 后者主要是用户贡献的模块

此前 Leiningen 一直是首选, 所有的教程都是 lein 什么 lein 什么
但是最近有看到 boot 热门起来, 包括在下面这份 ClojureScript 的教程上换了
https://github.com/magomimmo/modern-cljs
熟悉 JavaScript 生态的同学, 我想说这两者区别很像 Grunt 和 Gulp
一个是定义好了任务, 只要写配置就好了, 另一个可以定义任务组合任务
我是出于组合任务的原因, 需要切换到 boot 以便我在 Gulp 中的习惯可以继续

但是呢, boot 生态现在远没有 Leiningen 丰富, 可以对比一下
https://github.com/boot-clj/boot/wiki/Community-Tasks
https://github.com/technomancy/leiningen/wiki/Plugins
包括一些 boot task 估计也正在完善当中. 有点被 npm 文化入侵的感觉, 快而乱

文档

Leiningen 的文档如果有人看过, 大概看吐了...我的意思是太长了
一个建构工具文档长得不得了, 没心思看. boot 的文档也很长, 只能说还好
https://github.com/boot-clj/boot/wiki
大致上要明白一些概念吧, 虽然和 Gulp 相似度不小, 但是术语是新的:

  • task 对应任务

  • fileset 对应 Gulp 里的 file stream

  • middleware 中间件, 其实和 task 差不多的

boot 的架构图看上去就和 Koa 的架构图一样, 洋葱形架构 - -!
好吧我不清楚是谁借鉴谁的, ring 似乎要早一点, 毕竟是 Java

Clojure 构建工具 boot 粗略_第1张图片

https://github.com/boot-clj/boot/wiki/Tasks

Boot adopts a model based on another architecture that has proven to be flexible, powerful, and modular in demanding real-world use: Ring middleware.

所以写过服务器的同学对这种东西应该比我熟悉了, 自行想象

boot 当中用 fileset 来表示文件, 数据类型是 Set, 集合.
具体在文档有示例, 主要是文件信息, 倒没有把文件带进来
我看现成的插件上总使用临时目录来处理中间过程, 感觉就跟我写变量一样随意
fileset 是基于不可变数据的, 不能修改, 只是通过函数返回新的数据
但是临时文件是可以操作的, 大量的文件复写操作.
一个不作任何事情的 task 写起来是这样的, 注意 next-task 这个中间件的写法:

(deftask null-task
  "Does nothing."
  []
  (fn [next-task]
    (fn [fileset]
      (next-task fileset))))

我写的生成 HTML 的 task, 思路大概是这样的:

  • 从 task 的参数当中获取配置信息

  • 从 filset 当中读取对应的文件

  • 生成临时目录, 把我的 HTML 写进临时目录

  • boot/add-resource 方法把临时目录进入到 fileset

  • boot/commit! 方法把文件从 fileset 写到 target/ 目录当中

它的参数自定义了一套 DSL, 有点繁琐, 需要照着现成的例子结合文档看
另外 fileset 操作方法很多, 我还没有掌握几个, 略复杂

task

关于编译 cljs 以及代码热替换的事情, 可以看下这两篇:
https://github.com/magomimmo/modern-cljs/blob/master/doc/second-edition/tutorial-01.md
https://github.com/magomimmo/modern-cljs/blob/master/doc/second-edition/tutorial-02.md
说实在的, 配置这么写, 真的已经到了 Gulp 编译 CoffeeScript 的程度了
而且, 热替换就这么容易搞定了... 只是替换一下资源就好了

不多解释了, 贴一个我练习时用的配置. 不能直接用, 我主要想说明真的很短:

(set-env!
 :source-paths #{"src/cljs"} ; 源代码目录

 :dependencies '[[adzerk/boot-cljs "1.7.170-3"] ; 依赖, 跳过
                 [adzerk/boot-reload "0.4.6"]
                 [mvc-works/boot-html-entry "0.1.1" :scope "provided"]
                 [cirru/boot-cirru-sepal "0.1.1"    :scope "provided"]])

(require '[adzerk.boot-cljs :refer [cljs]] ; 依赖的引用, 跳过
         '[adzerk.boot-reload :refer [reload]]
         '[html-entry.core :refer [html-entry]]
         '[cirru-sepal.core :refer [cirru-sepal]])

(deftask build []
  (comp
    (cljs :optimizations :advanced))) ; 编译, 就这么短!

(deftask dev []
  (comp
    (cirru-sepal :paths ["cirru-src"] :watch true) ; Cirru, 我的, 跳过
    (watch) ; 内建的 watch task
    (reload :on-jsload 'modern-cljs.core/on-jsload) ; reload 就这么写了
    (cljs))) ; 也是 cljs 编译

(defn html-dsl [] ; 我的 HTML 内容
  [:div "demo"])

(deftask gen-html []
  (html-entry :dsl (html-dsl) :html-name "entry.html")) ; 我的 HTML task

而且出于两个原因, 一个是没有同文件流不需要写 pipe,
另一是 Clojure 语法抽象程度高, 这个配置的代码量实际上比 Gulp 还少, 除了括号多

社区

也算是准备比较充分了, 一个构建工具, 各种反馈渠道已经搭建好了
Duscourse http://hoplon.discoursehosting.net/
Slack https://clojurians.slack.com/messages/boot/
IRC 也有, 但估计没有人, 我昨天发了两次问题都没人理我
不过 Slack 上反应很快, 当时有个报错, 贴了配置就帮忙找到问题了

顺带看 Slack 的时候觉得挺惊人的, Clojure 的 Slack 上分组很多
基本上每天都有大量的消息, 而且比起 IRC 也活跃很多
我扫了一下聊天记录, 某些社区大牛也是混在 Slack 上的, 难能可贵
国内 Clojure 也就 QQ 群上大家热闹热闹, 然而水得也挺多的

想想 boot 作者那帮人也挺牛逼的, 能把这样的东西设计实现出来
国内很少有能把这种程度的平台给搞出来的人, FIS 好像挺牛逼但是没那么开放
之前 seajs 看着厉害, 后面 Webpack 一来似乎也趴下了
我朋友做打包工具但现在看情况也就是追赶 Webpack 的份, 跟国外不能比
要提高社区整体效率, 显然是要统一成限定的几个方案, 然后集中力量
但我很不觉得国内 Web 开发社区有这个实力可以把开发工具链给统一起来.. 观望

你可能感兴趣的:(boot,clojure)