用 CirruScript 衬着 HTML

早的时刻我尝试过用 Cirru 语法直接天生 HTML
后边也尝试过用 Cirru 语法天生 JavaScript 的模板
效果勉勉强强, 主如果进修的作用, 厥后有了 React 就痛快不必了
不过将来加载静态资本, 照样须要有 HTML, 就以为贫苦, 搞出点东西来

stir-template

这个模块经由频频演化, 终究定型成为 React 很类似的写法
https://github.com/mvc-works/stir-template
代码是用低版本的 CirruScript 写的, API 也能在 CoffeeScript 里挪用

stir = require :stir-tempate
html = stir.html
head = stir.head
body = stir.body
div = stir.createFactory :div

renderPage = (data) ->
  stir.render
    stir.doctype()
    html null,
      head null,
      body null,
        div name: 'a', 'empty'
        div()

能够看到模拟了 React, 衬着函数的第一个参数是属性, 后边是子元素
也供应了类似的辅佐函数 render, createElement, createFactory
如许写出来的作风, 跟 CoffeeScript 里写 React 组件也就差不多了
本身须要天生个标签的话, 能够尝试如许的语法:

newTag = stir.createFactory 'new-tag'

别的 <!DOCTYPE html> 算是个特别的标签, React 当中不供应
那末 stir-template 就轻易合营 React 用在后者不轻易的处所

Cirru 的缩进

http://script.cirru.org/

我的个人项目现在已大批运用 CirruScript.. 算是刷排名吧
https://github.com/mvc-works/webpack-workflow
CirruScript 起首是编译到 ES5 的代码天生器, 其次才当作模板言语用
我以为 CoffeeScript 里逗号太多, 缩进有 bug, 不高兴一向用
CirruScript 合营 stir-template 跟 React 能够如许用:

var
  stir $ require :stir-template
  React $ require :react

var
  Page $ React.createFactory $ require :./src/page

var
  ({}~ html head title body meta script link div a span) stir

var
  line $ \ (text) (div ({} (:className :line)) text)

= module.exports $ \ (data)
  return $ stir.render
    stir.doctype
    html null
      head null
        title null ":Coffee Webpack Starter"
        meta $ object (:charset :utf-8)
        link $ object (:rel :icon)
          :href :http://tp4.sinaimg.cn/5592259015/180/5725970590/1
        link $ {} (:rel :stylesheet)
          :href $ cond data.dev :src/main.css data.style
        script $ object (:src data.vendor) (:defer true)
        script $ object (:src data.main) (:defer true)
      body null
        div ({} (:class :intro))
          div ({} (:class :title)) ":This is a demo of Webpack usage."
          line ":Open Console to see how it loads."
          div null
            span null ":Read more at "
            a
              {} (:href :http://github.com/teambition/coffee-webpack-starter)
              , :github.com/teambition/coffee-webpack-starter
            span null :.
        div ({} (:class :demo))
          React.renderToString (Page)

起首 HTML 的构造也许照样能看到的, 接着就是语法了…

  • 缩进

Cirru 起首不是靠许多语法发挥作用的言语, 而是靠的缩进
全部代码会先被剖析成一棵树, 这棵树才是后边实行的重点
最少我在写代码的时刻, 每时每刻脑补他的树是如何的, 能够看 Demo:
http://repo.cirru.org/parser/

  • 美圆标记 $

美圆标记是为了处置惩罚一类缩进而引入的, 比如说下边如许的代码:

(set a (f1 (f2 (f3 x))))

缩进今后想一想都以为很累, 会是如许的, 还不如用括号

set a
  f1
    f2
      f3 x

那末我引入 $ 以后题目就轻松了, 直接就能够如许写:

set a $ f1 $ f2 $ f3 x
  • 逗号 ,

然后逗号也是为了处置惩罚一类状况引入的, 意义也许和 $ 相反, 如许的代码

(set a (f1 a) (b) (f2))

改成缩进的时刻会是如许的, 注重单行的 bf2 由于换行是有括号的:

set a
  f1 a
  b
  f2

那末题目就来了, 有如许的代码怎样示意, 这里的 b 没有括号了啊:

(set a (f1 a) b (f2))

所以我引入了 ,, 作用就是去掉一层缩进, 也许就是如许:

(set a (f1 a) (, b) (f2))

然后再用缩进的写法, 就不会剖析出错了:

set a
  f1 a
  , b
  f2

依据上边 3 条划定规矩, Cirru 语法的缩进能示意绝大部分编程需求
除了表达式第一个操作符里狂用括号的… 放哪一个言语里都没平常的方法

CirruScript 的操作符

CirruScript 的编译器是经由过程辨认表达式第一个操作符来转换 AST 的
比如说 var return 会被辨认成对应的表达式或许语句的 AST
别的的 div 如许的, 没有对应的操作符, 就会被处置惩罚为函数挪用

object 操作符, 用来天生对象, 它的参数都是键值对
它有个 alias 是{}, 我以为看起来更习气一些, 毕竟花括号照样很眼熟的
array 操作符一样的意义, 用来天生数组, 它的参数就是元素了
它有个 alias 是 []. 空数组可能会写成 ([]) 示意为表达式了

字面量另有标识符我做了一些处置惩罚, 轻易写代码用
这里边的 null true 都是回自动辨认的, 数字也做了处置惩罚
别的 data.main 这类, 也经由过程成员表达式的 AST 进行了处置惩罚

这里边另有些挺新鲜的比如说 {}~, 实际上是 object~
然则然则, 这类准确的称号应当是: **解构赋值**, 只是新鲜了点
新鲜的语法照样到 http://script.cirru.org 看吧, 能够看详细 AST 是什么

CirruScript 的字符串

字符串是个新鲜的事变, 由于 Cirru 是从图形编辑器退步而来的..
退步嘛… 天然有的东西, 本来图形很平常, 用文本示意就怪怪怪怪了的
Cirru 的语法里 a"a", 带不带引号, 实际上是一样的
不一样的是 "a1 a2"a1 a2, 没有引号就是两个节点, 有就是一个
所以… 引号实际上是为了特别字符的转义用的, 另有这类呢 "a1\" a2"
你在 <textarea> 里打字的时刻不必转义, 图形界面嘛, 那是平常的时刻

然后为了示意字符串, 我动起来歪脑筋, 对, 用冒号 :
冒号开首的就是字符串了, 没有特别字符的时刻还能够少一个字符
:utf-8":utf-8" 示意的是一个意义, 编译的效果也是一样的
必需加引号的是 ":hello world" 如许的有特别字符的节点
看多了 Clojure 的话实在冒号你是会习气的…

总结

最新版的 Gulp 应当是能辨认 gulpfile.cirru 如许的后缀的
我也写了插件, 应当题目不大, CoffeeScript 这么难用都用下来了
https://github.com/Cirru/gulp-cirru-script

平常我会写个 template.cirru 文件, 从 Gulp 里援用
末了实行一下函数, 就能从数据衬着出 HTML 来了:

require('cirru-script/lib/register')

gulp.task 'html', (cb) ->
  html = require'./template.cirru' # <-- 援用看这里
  fs = require 'fs'

  if not env.dev
    assets = require './build/assets.json'
    env.main = "./build/#{assets.main}"
    env.vendor = "./build/#{assets.vendor}"
  fs.writeFile 'index.html', (html env), cb # <-- 挪用看这里

愿望你有兴致用 CirruScript 天生 HTML. 早日镌汰手写 HTML.

    原文作者:题恭弘=叶 恭弘
    原文地址: https://segmentfault.com/a/1190000003114949
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞