早的时刻我尝试过用 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 的缩进
我的个人项目现在已大批运用 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))
改成缩进的时刻会是如许的, 注重单行的 b
跟 f2
由于换行是有括号的:
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.