Zonda
Zonda——Degas自家用的前端框架。
感谢和我一起建造Zonda的朋友们,亲爱的Niko,leohgbs,bronze1man。
BUG还很多,发现一个修复一个。已在几个项目中使用,不断更新,不断学习~
Zonda行车手册
目前正在对整车进行重构,处于无法发动状态,技师正在紧张的修复中。
依赖
- Linux/Unix/Mac OS X
- NodeJs v0.8.21
- SPM v1.8.0-dev
- Less v1.3.3
- CoffeeScript v1.6.1
点火,起步!
git clone https://github.com/smallsmallwolf/Zonda.git
将Zonda拉到Web服务的文件根目录(Web服务器/
的位置,放到这里主要是为了方便),然后执行:
cd Zonda/tool
./setup.sh
执行完毕后,Zonda会根据Zonda/project-template
创建一个前端项目模板,目录结构大致是这样的:
assets/ # 前端项目根目录
etc/ # 项目配置文件
vendor/ # 第三方组件
Zonda/
src/ # 你的应用程序源代码
ui/ # 你的应用程序的UI文件
less/
config.less
mixin.less
responsive.less
images/
ie/
ie.css
test/ # 测试你的应用程序
dist/ # 线上版本的应用程序代码
dist-dev.css
framework-dev.js
app-dev.js
tool/ # 工具(打包应用程序,Less编译工具等等)
页面上将要引入的CSS和Javascript文件如下:
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Let's Rock!</title>
<link rel="stylesheet" href="/assets/dist/dist-dev.css" />
</head>
<body>
...
<script src="/assets/dist/framework-dev.js" id="seajsnode" data-main="/assets/dist/app-dev.js" ></script>
</body>
</html>
Nice,Zonda现在已经发动了,驾驶着它在前端的赛道上驰骋吧~
CSS/Less & Images
Less dir: assets/ui/less
,放置你的项目的样式
Images dir: assets/ui/images
,你项目中用到的图片文件
Bootstrap dir: assets/vendor/Zonda/ui/less
,Zonda默认提供使用Bootstrap作为UI基础,在assets/ui/less/config.less
中,@import
了Bootstrap的Less源文件,如果不需要Bootstrap,可以在config.less
将该行注释,但真心不建议这么做,Bootstrap可是个好东西。
Less实时编译工具,这个工具可能有点小Bug,欢迎Issue:
cd assets/tool
./less-compile.sh
执行上面的命令将会开始监听assets/ui/less
目录,如果文件有修改,则会编译,并将所有@import
的Less编译成一个CSS文件(包括Bootstrap和Font Awesome)输出到assets/dist/dist-dev.css
,也就是页面上引入的那个CSS文件。
Less编译工具使用NodeJs(v0.8.21)和Lessc(v1.3.3),源文件在tool/module/lessCompiler.coffee
。它目前只能提供简单的监听文件改变并编译的功能,并且将所有的Less文件编译成一个CSS。
lessCompiler.coffee
默认会将Less中的注释去掉,如果需要保留注释以便调试,则将文件中的:
lessc_command = "lessc -x"
# 去掉 -x,改成下面这样即可
lessc_command = "lessc"
lessCompiler.coffee
缺少一个不将Less合并成一个CSS的功能,还缺少将dist-dev.css
压缩的功能,以后会尝试实现的,欢迎Issue~
JavaScript/CoffeeScript
Javascript dir: assets/src
,这里放置你的项目源代码。如果使用CoffeeScript,那么直接将Coffee文件编译到当前目录下就行了,推荐一个Vim-CoffeeScript插件vim-coffee-script
Zonda dir: assets/vendor/Zonda
,这里是Zonda的框架代码,框架里已经包含了一些必要的库,都已做成seajs module,包括:
SeaJs v2.0.0pre
jQuery v1.9.1
Underscore v1.4.4
Backbone v0.9.10
Bootstrap(jQuery plugins) v2.3.1
Modernizr v2.6.2
Mustache
开发模式(dev)与线上模式(prod)
cd assets/tool/
# 切换至开发模式:生成 framework-dev.js,app-dev.js
./build.sh dev
# 切换至线上模式:生成 framework-version.js,app-version.js
./build.sh prod
DEV模式
期望实现的目标:不压缩合并任何应用代码和第三方模块。
/assets/dist/framework-dev.js
实现思路:
在开发模式下(dev),该文件就是 SeaJs 源码 + SeaJs plugin(没有加入 combo,flush插件);
SeaJs 的配置文件为 env.js (以后有时间了可以考虑使用 Yaml,或者直接 CoffeeScript ),用工具将 assets/vendor/Zonda/vendor
以及 assets/vendor/
读取一遍,生成出 env.js 需要使用的 SeaJs 的 alias
,然后将生成好的 env.js cat 到 SeaJs 源代码底部,当有第三方模块更新,或者 SeaJs 更新时,只需要重新执行 ./build.sh dev
即可。
env.js 应该大概是这个样子:
seajs.config({
base: "/assets",
alias: {
"jquery" : "vendor/Zonda/vendor/jquery/1.9.1/jquery/src/jquery"
},
charset: "utf-8"
});
assets/dist/app-dev.js
实现思路:
在开发模式下(dev),该文件只有一行:
seajs.use("/assets/src/app");
PROD模式
期望实现的目标:将 SeaJS,jQuery 等第三方模块压缩合并到framework-version.js
,将src
下应用程序源码压缩合并到app-version.js
,最终将 Javascript 文件的连接数优化为2个,并且带有文件MD5值的版本号,以便控制其发布。
assets/dist/framework-version.js
实现思路:
在线上模式(prod),该文件包含了framework-dev.js
,vendor/
下的各个第三方模块。
assets/dist/app-version.js
实现思路:
在线上模式(prod),该文件为assets/src/app-version.js
将其src
内的依赖打包合并后的文件,需要在最后一行加上:
seajs.use("/assets/dist/app.js");
以便 SeaJS 将它视作应用入口。
spm build
这里使用spm
工具来实现 prod 模式,但是 spm 没有实现这里"将第三方模块与应用程序代码分别打包"的需求,所以目前只能手动解决,那就是配置package.json
:
{
"name" : "Zonda-Project",
"version" : "",
"root": "/assets/dist",
"dependencies" : {
"jquery" : "jquery"
},
"output" : {
"app.js" : "."
},
"sources": ["http://module.zonda.dashu.us:22221"]
}
这里对require("jquery")
这样的第三方依赖没有做处理,是因为jquery
模块已经打包压缩到framework-version.js
中了,并且其模块ID为env.js
中配置的alias
所指明的ID。所以app-version.js
中调用require("jquery")
时会根据seajs.config
中alias
的配置去调用,这里就没有问题了。
需要注意的是这里将第三方模块打包到framework-version.js
是由Zonda的工具来完成的,并不是由spm,所以framework-version.js
里到底 combo 了哪些第三方模块,已经这些模块的顺序,全部都由etc/package.json
中的dependencies
决定的。
调用框架模块
Util = require "util"
Util.base64.encode "床前明月光"
Base64 模块 (stable)
Usage
Util = require "util"
Util.base64.encode "疑是地上霜"
# return "eyJjb25kaXRpb24iOiJcdTc1OTFcdTY2MmZcdTU3MzBcdTRlMGFcdTk3MWMiLCJiYXNlX2lkIjoiMSJ9"
Util.base64.decode "eyJjb25kaXRpb24iOiJcdTRlM2VcdTU5MzRcdTY3MWJcdTY2MGVcdTY3MDgiLCJiYXNlX2lkIjoiMSJ9"
# return "举头望明月"
State Machine (stable)
功能:
Util.StateMachine 返回状态机构造器,stateMachine = new Util.StateMachine,获得状态机实例,每个状态机实例相互独立;
每个状态机里可以存储多个“视图状态”,假设有一个列表视图list_view
,为这个视图状态申明两个动作:
- 激活动作:这个动作触发时,
list_view
视图将被激活,我们要为这个视图状态呈现哪些DOM; - 关闭动作:当
list_view
视图被关闭时,我们将要隐藏哪些DOM;
状态机中的“视图状态”都是互斥的,比如list_view
是在登陆之后可见,那么login_view
和list_view
比如是互斥的。所以在激活某一个状态机中一个视图状态时,该状态机中的其他视图将被关闭。
实现:
基于Backbone的Event实现,先申明某一个视图状态及其“激活”和“关闭”动作,然后将它加入到某个状态机中(或某几个状态机中),在使用时直接调用该视图状态的active
方法即可。
Usage
Util = require "Util"
mainStateMachine = new Util.StateMachine()
list_view =
activate: ->
$("#main-list").show()
$("#main-list-nav").show()
deactivate: ->
$("#main-list").hide()
$("#main-list-nav").hide()
mainStateMachine.add list_view
module.exports =
list: list_view