Yeoman 学习笔记
yoeman 简介:http://www.infoq.com/cn/news/2012/09/yeoman
yeoman 官网: http://yeoman.io/
yeoman 是快速创建骨架应用程序的WEB前端工具,实际由 yo, grunt, bower 三个组建而成。
-
Yo scaffolds out a new application, writing your Grunt configuration and pulling in relevant Grunt tasks that you might need for your build.
-
Grunt is used to build, preview and test your project, thanks to help from tasks curated by the Yeoman team and grunt-contrib.
-
Bower is used for dependency management, so that you no longer have to manually download and manage your scripts.
简单来说就是 Yo 是配置 Grunt 的 task 的工具,Grunt 是一个部署、预览和测试前端项目的工具,而 Bower 是一个包的管理工具,可以下载 jquery, backbone 等库。
PS: 要运行 yeoman 首先需要配置环境,配置好 node.js 、git 环境。
下面开始写一个 todo-list demo 作为例子
一、首先安装 yo,这会自动安装 grunt, bower
npm install -g yo
npm install -g generator-webapp
PS: yo 是命令开头,webapp 是 另外一个参数. yo 可以生成其他各种应用配置。如 backbone, angularjs等,前提首先安装 generator-backbone,即
yo webapp
此时可以看到
webapp 默认带有 Sass 版的 bootstrap库,等到下载完毕后可以看到以下文件:
app 为项目主目录,是部署的根目录
node_modules 为 nodejs的包文件
test 为测试目录,专门用于单元测试,用的是 mocha 来测试
Gruntfile.js 是配置 grunt 自动化任务的配置文件,具体配置可以参考下 Grunt官网
二、添加JS库,这里添加 backbone,bower 会自动下载 underscore.
bower install backbone
三、运行
grunt server
它将运行应用,并监控文件的变化,一旦有改变,就会自动刷新浏览器。
文件又这几个,用的是
- HTML5 Boilerplate 模板(默认)
- RequireJS (可选)
四、开始写应用
index.html
<!doctype html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
<!-- build:css(.tmp) styles/main.css -->
<link rel="stylesheet" href="styles/bootstrap-2.3.2.min.css">
<link rel="stylesheet" href="styles/main.css">
<!-- endbuild -->
<!-- build:js scripts/vendor/modernizr.js -->
<script src="bower_components/modernizr/modernizr.js"></script>
<!-- endbuild -->
</head>
<body>
<div class="container">
<div class="todo-container">
<div class="header">
<h2>Todo List</h2>
<div class="todo-input">
<div class="controls">
<input type="text" placeholder="Enter to save" class="todo-input-text" autofocus>
</div>
</div>
</div>
<div class="content">
<div class="todo-item-list todo-undone-list clearfix">
<p>Things to do:</p>
</div>
<div class="todo-item-list todo-done-list clearfix">
<p>Done Things:</p>
</div>
</div>
<div class="footer">
</div>
</div>
</div>
<script type="text/template" id="todo-input-template">
</script>
<script type="text/template" id="todo-item-template">
<span class="order"><%= order%></span>
<a href="javascript:void(0);" class="done-<%= done%>">
<b><%= title%></b>
<button title="删除" class="btn btn-mini pull-right todo-item-remove"><i class="icon-remove"></i></button>
<% if (done) { %>
<button title="撤销" class="btn btn-mini pull-right todo-item-undone"><i class="icon-repeat"></i></button>
<% } else { %>
<button title="完成" class="btn btn-mini pull-right todo-item-done"><i class="icon-ok"></i></button>
<% } %>
</a>
</script>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<!-- build:js scripts/main.js -->
<script data-main="scripts/main" src="bower_components/requirejs/require.js"></script>
<!-- endbuild -->
</body>
</html>
main.coffee
require.config
baseUrl : './scripts/'
shim :
underscore :
exports : '_'
backbone :
deps : [
'underscore'
'jquery'
]
exports : 'Backbone'
backboneLocalStorage :
deps : [
'backbone'
]
app :
deps : [
'underscore'
'jquery'
'backbone'
]
paths :
jquery : '../bower_components/jquery/jquery'
underscore : '../bower_components/underscore/underscore'
backbone : '../bower_components/backbone/backbone'
backboneLocalStorage: '../bower_components/backbone/examples/backbone.localStorage'
require ['app'], (app) ->
app.init()
app.coffee
define 'app', ['jquery', 'underscore', 'backbone', 'backboneLocalStorage'], ($, _, Backbone) ->
TodoModel = Backbone.Model.extend
defaults : () ->
title : 'Untitle',
done : false,
order : Todos.length+1
initialize : () ->
this.save()
TodoList = Backbone.Collection.extend
model : TodoModel
localStorage : new Backbone.LocalStorage 'todos-backbone'
done : () ->
this.where done : true
Todos = new TodoList # todo 集合
TodoView = Backbone.View.extend
tagName : 'div' # 外容器
template : _.template $('#todo-item-template').html() # 模板HTML
# 初始化,坚听对象
initialize : () ->
this.listenTo this.model, 'change', this.render
this.listenTo this.model, 'destroy', this.remove
# 事件绑定
events :
'click button.todo-item-done' : 'done'
'click button.todo-item-remove' : 'clear'
'click button.todo-item-undone' : 'undone'
done : () ->
if this.model.get('done') == false # 本身是未完成状态的
this.model.set done : true
this.remove()
undone : () ->
if this.model.get('done') == true # 本身是完成状态的
this.model.set done : false
this.remove()
clear : () ->
this.model.destroy()
render : () ->
this.$el.html this.template this.model.toJSON()
return this
AppView = Backbone.View.extend
# 初始化保存DOM对象
initialize : () ->
this.$input = this.$('.todo-input-text').focus()
this.$todoList = this.$('.todo-undone-list')
this.$todoDoneList = this.$('.todo-done-list')
this.listenTo Todos, 'add', this.addOne
this.listenTo Todos, 'change:done', this.addOne
Todos.fetch()
events :
'keypress input.todo-input-text' : 'createOnEnter'
# Enter 时保存
createOnEnter : (e) ->
if e.keyCode != 13
return
if !this.$input.val()
return;
Todos.create title: this.$input.val()
this.$input.val('')
addOne : (todo) ->
view = new TodoView model : todo
if todo.get('done')
# 已经完成的加入已完成列表
this.$todoDoneList.append(view.render().el);
else
# 未完成的加入未完成列表
this.$todoList.append(view.render().el);
# Todos.each (todo) ->
todo.save()
App = new AppView el : $('.todo-container') # 主应用UI
return init : () ->
Backbone.history.start()
main.css
.todo-container {
margin: 50px auto 0 auto;
300px;
}
.todo-item-list {
margin-top: 20px;
}
.todo-item-list > div {
float: left;
90%;
margin-top: 10px;
padding-left: 5%;
}
.todo-item-list > div a:hover {
text-decoration: none;
}
.todo-item-list > div button {
margin: 0 3px;
}
.todo-item-list > div span.order {
margin-right: 10px;
color: #B6B6B6;
font-style: italic;
}
.todo-item-list > p {
font-weight: bold;
margin-top: 1em;
}
效果图
补充:
这里用的是 coffeescript,yeoman会自动转成js。关于todo-list,可以上官网参考下,我这里简化了部分代码。