好文推荐系列---------(4)使用Yeoman自动构建Ember项目
好文原文地址:http://segmentfault.com/a/1190000000368881
我决定学习前端开发的效率工具Yeoman。本文将首先介绍Yeoman的基本情况,接着我们会使用Yeoman开发一个Ember应用。
Yeoman是什么?
Yeoman按照官方说法,它不只是一个工具,还是一个工作流。它其实包括了三个部分yo、grunt、bower,分别用于项目的启动、文件操作、包管理。
Yo: Yo是一个项目初始化工具,可以生成一套启动某类项目必需的项目文件。
GruntJS: GruntJS是基于JavaScript的命令行构建工具,它可以帮助开发者们自动化重复性的工作。阅读day 5获取更多信息。
Bower: Bower是一个客户端技术的软件包管理器,它可用于搜索、安装和卸载如JavaScript、HTML、CSS之类的网络资源。阅读day 1获取更多信息。
我为什么关心Yeoman
如果你需要说服自己学习Yeoman,你可以读读Yeoman网站上的whyyeoman。
安装
使用npm
安装:
npm install -g yeoman
安装Yeoman Ember生成器
Yeoman依赖生成器为web项目提供支架。所有的现代JavaScript MV* 框架都有相应的生成器。本文使用Ember:
npm install -g generator-ember
我们将开发一个社交化书签应用,允许用户提交和分享链接。你可以在这里查看这个应用。这个应用和我们day 19开发的一样。
Github仓库
今天的示例应用代码可从Github取得。
创建Ember应用
现在开始应用开发。首先创建项目目录,接着运行yo ember
命令,它会询问你是否使用Twitter Bootstrap。我习惯在自己的项目中使用Bootstrap,所以我选了是。
; mkdir getbookmarks
; cd getbookmarks
; yo ember
_-----_
| |
|--(o)--| .--------------------------.
--------- | Welcome to Yeoman, |
( __ ) | ladies and gentlemen! |
/___A___\ '__________________________'
| ~ |
__'.___.'__
[?] Would you like to include Twitter Bootstrap for Sass? Yes
之后Yeoman会创建一个Ember应用,自动使用bower
和npm
安装依赖。
现在让我们看看Yeoman生成的Ember应用。应用有三个顶层目录:app
、node_modules
和test
。还有一些配置文件:.bowerrc
、.gitignore
、.jshintrc
、Gruntfile.js
和package.json
。目录结构如下所示。
所有的应用相关代码都在app
目录下。目录结构遵循Ember的最佳实践。
bower_components
目录包括了客户端依赖,例如Ember、Twitter Bootstrap,等等。Bower在所有文件夹内安装所有依赖。image
目录包括了应用相关的图像。Yeoman会优化image
目录内的图片。index.html
包含了所有的ember.js
依赖,所有的bootstrap依赖,以及build
注释(Gruntfile.js可以据此替换或移除引用的未优化的脚本和样式表)。scripts
目录包含了Ember应用的controller、view、model和route。styles
目录包含了应用相关的css文件。templates
目录包含了应用的handlebar模板。
现在我们可以启动预览服务器了:
grunt server
这会使用系统默认浏览器打开应用:
生成Story Model
我们在day19中开发的GetBookmarks应用中创建了一个Ember Model:Story。Yeoman的次级生成器可以用来构建项目的部分,包括model。运行如下命令生成Story model:
yo ember:model Story
命令的输出如下:
create app/scripts/models/story_model.js
invoke ember:controller:/usr/local/lib/node_modules/generator-ember/model/index.js
create app/scripts/controllers/stories_controller.js
create app/scripts/controllers/story_edit_controller.js
create app/scripts/routes/stories_route.js
create app/scripts/routes/story_route.js
create app/scripts/routes/story_edit_route.js
invoke ember:view:/usr/local/lib/node_modules/generator-ember/controller/index.js
create app/scripts/views/story_view.js
create app/scripts/views/story_edit_view.js
create app/scripts/views/stories_view.js
create app/templates/story.hbs
create app/templates/story_edit.hbs
create app/templates/stories.hbs
create app/scripts/views/bound_text_field_view.js
invoke ember:router:/usr/local/lib/node_modules/generator-ember/controller/index.js
conflict app/scripts/router.js
[?] Overwrite app/scripts/router.js? overwrite
force app/scripts/router.js
这会在app/scripts/models
目录下生成story_model.js
,同时会生成相应的view、controller和route。
修改下story_model
:
Emberapp.Story = DS.Model.extend({
url : DS.attr('string'),
tags : DS.attr('string'),
fullname : DS.attr('string'),
title : DS.attr('string'),
excerpt : DS.attr('string'),
submittedOn : DS.attr('date')
});
重新启动Grunt server以便改动生效。
安装Ember LocalStorage适配器
我们将使用HTML 5 LocalStorage来存储数据。使用bower安装适配器。
bower install --save ember-localstorage-adapter
然后更新index.html
页面,添加依赖:
<script src="bower_components/ember-localstorage-adapter/localstorage_adapter.js"></script>
同时更新app/scripts/store.js
,配置应用使用LSAdapter:
Getbookmarks.Store = DS.Store.extend();
Getbookmarks.ApplicationAdapter = DS.LSAdapter.extend({
namespace: 'stories'
});
更新路由
修改router.js
:
Getbookmarks.Router.map(function () {
this.resource('index',{path : '/'});
this.resource('story', { path: '/story/:story_id' });
this.resource('story_edit', { path: '/story/new' });
});
提交新报道
我们首先添加用户访问#/story/new
后会出现的表单。修改app/templates/story_edit.hbs
:
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="title" class="col-sm-2 control-label">Title</label>
<div class="col-sm-10">
<input type="title" class="form-control" id="title" name="title" placeholder="Title of the link" required>
</div>
</div>
<div class="form-group">
<label for="excerpt" class="col-sm-2 control-label">Excerpt</label>
<div class="col-sm-10">
<textarea class="form-control" id="excerpt" name="excerpt" placeholder="Short description of the link" required></textarea>
</div>
</div>
<div class="form-group">
<label for="url" class="col-sm-2 control-label">Url</label>
<div class="col-sm-10">
<input type="url" class="form-control" id="url" name="url" placeholder="Url of the link" required>
</div>
</div>
<div class="form-group">
<label for="tags" class="col-sm-2 control-label">Tags</label>
<div class="col-sm-10">
<textarea id="tags" class="form-control" name="tags" placeholder="Comma seperated list of tags" rows="3" required></textarea>
</div>
</div>
<div class="form-group">
<label for="fullname" class="col-sm-2 control-label">Full Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="fullname" name="fullname" placeholder="Enter your Full Name like Shekhar Gulati" required>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success" {{action 'save'}}>Submit Story</button>
</div>
</div>
</form>
现在,访问 http://localhost:9000/#/story/new 可以看到提交报道的表单。
更新StoryEditController
,将数据持续化入本地存储:
Getbookmarks.StoryEditController = Ember.ObjectController.extend({
save: function(){
var url = $('#url').val();
var tags = $('#tags').val();
var fullname = $('#fullname').val();
var title = $('#title').val();
var excerpt = $('#excerpt').val();
var submittedOn = new Date();
var store = this.get('store');
console.log('Store .. '+store);
var story = store.createRecord('story',{
url : url,
tags : tags,
fullname : fullname,
title : title,
excerpt : excerpt,
submittedOn : submittedOn
});
story.save();
this.transitionToRoute('index');
}
});
列出所有报道
接下来我们要实现的功能是在侧边栏展示报道列表。
在application_route.js
,我们从本地存储获取所有的报道。
Getbookmarks.ApplicationRoute = Ember.Route.extend({
model : function(){
var stories = this.get('store').findAll('story');
return stories;
}
});
接着我们更新application.hbs
,为每个报道的标题添加链接:
<div>
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">GetBookmarks</a>
</div>
<div class="collapse navbar-collapse navbar-ex1-collapse">
<ul class="nav navbar-nav pull-right">
<li>{{#link-to 'story_edit'}}<span class="glyphicon glyphicon-plus"></span> Submit Story{{/link-to}}</li>
</ul>
</div>
</nav>
<div class="container" id="main">
<div class="row">
<div>
<div class="col-md-3">
<div class="well sidebar-nav">
<table class='table'>
<thead>
<tr><th>Recent Stories</th></tr>
</thead>
{{#each controller}}
<tr><td>
{{#link-to 'story' this}}
{{title}}
{{/link-to}}
</td></tr>
{{/each}}
</table>
</div>
</div>
<div class="col-md-9">
{{outlet}}
</div>
</div>
</div>
</div>
</div>
应用的用户界面会刷新。
查看单独的报道
最后要添加的功能是,用户访问 http://localhost:9000/#/story/:id 的时候可以查看单独的报道。:id
对应于story id
。修改story_routejs
。
Getbookmarks.StoryRoute = Ember.Route.extend({
model : function(params){
var store = this.get('store');
return store.find('story',params.story_id);
}
});
修改app/templates/story.hbs
:
<h1>{{title}}</h1>
<h2> by {{fullname}} <small class="muted">{{submittedOn}}</small></h2>
{{#each tagnames}}
<span class="label label-primary">{{this}}</span>
{{/each}}
<hr>
<p class="lead">
{{excerpt}}
</p>
为生产环境构建
最后,我们运行grunt build
命令创建一个可分发的应用。grunt build
命令将app
目录下的源文件转换成dist
目录下的可分发的应用。
grunt build
今天就这些。保持反馈。
好文推荐系列---------(4)使用Yeoman自动构建Ember项目的更多相关文章
- 使用Yeoman自动构建Ember项目
Yeoman是什么? Yeoman按照官方说法,它不只是一个工具,还是一个工作流.它其实包括了三个部分yo.grunt.bower,分别用于项目的启动.文件操作.包管理. Yo: Yo是一个项目初始化 ...
- Yeoman自动构建js项目
Aug 19, 2013 Tags: bowergruntJavascriptjsnodejsyeomanyo Comments: 10 Comments Yeoman自动构建js项目 从零开始nod ...
- 【转】Yeoman自动构建 Angularjs 项目
Yeoman是什么? Yeoman按照官方说法,它不只是一个工具,还是一个工作流.它其实包括了三个部分yo.grunt.bower,分别用于项目的启动.文件操作.包管理. Yo: Yo是一个项目初始化 ...
- Linux下Jenkins与GitHub自动构建Node项目(Vue)
根据上篇文章<Linux下Jenkins与GitHub自动构建NetCore与部署>,我们知道了Jenkins的强大功能,自动构建,部署了一个NetCore的Web,让开发人员专注于开发, ...
- [react001] 使用webpack自动构建react 项目
1.react 简介 React 是一个Facebook出品的前端UI开发框架.react官方的tutorials 为了让人容易上手,并没有给在平常工作使用react的详细配置,随意学习的深入,你为了 ...
- 小伙伴想学Jenkins自动构建发布项目,我:安排上了!!
写在前面 趁着十一长假,很多小伙伴都在悄悄学习,有些是为了能够顺利通过面试,进入大厂升职加薪.有些则是为了进一步巩固和提高自己的专业技能,希望有朝一日能过成为互联网架构师乃至技术专家.这不,就有小伙伴 ...
- jenkins自动构建前端项目(window,vue)
我们把一个多人协作的vue前端项目发布服务器,一般要经过以下步骤: git更新最新的代码 构建项目 把构建后的代码上传到服务器 如果用jenkins来构建的话,只需要点击一次构建按钮,就可以自动完成以 ...
- gradle学习系列之eclipse中简单构建android项目
看不到图片能够去訪问这个网址看看:http://pan.baidu.com/s/1o6FrFkA 一.什么是Gradle 官网www.gradle.org上介绍Gradle是升级版(evolved)的 ...
- Jenkins自动构建gitlab项目(jenkins+maven+giltlab+tomcat)
环境准备: System:CentOS 7.3 (最小化安装) JDK: 8u161 (1.8_161) tomcat: 8.5.29 Jenkins: Jenkins 2.107.1 Gitlab: ...
随机推荐
- java_11接口
1接口的概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”. 接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成.这样将功能的定义 ...
- mysql 数据库名称,中间带有中划线问题
插入数据时候,引用了数据库名,数据库名中有横线,会提示错误: You have an error in your SQL syntax; check the manual that correspon ...
- elastic5.4安装错误解决
首先,我们从官网下载:(官网:https://www.elastic.co/downloads/elasticsearch)(推荐下载deb或者rpm包,否则坑很多) 启动 (需要依赖java环境) ...
- JFinal Web开发学习(四)数据库连接与自动生成model
1.新建数据库jfinal_test,user表 /* Navicat MySQL Data Transfer Source Server : . Source Server Version : 50 ...
- 9.4-9.19 h5日记总结
总结: 1.标签 (1)单.双标签 (2)块级.行级标签 (3)标签的属性 2.CSS (1)选择器 *.id.class.标签.后代.子代.并集.交集.伪类.结构 (2)层叠性,即选择器权重的计算 ...
- JVM 体系结构概述 (一)
一.jvm运行在操作系统之上的,它与硬件没有直接交互: 二.JVM体系结构概览 JVM的基本结构:类加载器.执行引擎.运行时数据区.本地方法接口: 过程:class文件 ----> 类加载器 - ...
- XiaoKL学Python(C)__future__
__future__ in Python 1. from __future__ import xxxx 这是为了在低版本的python中使用可能在某个高版本python中成为语言标准的特性,从而 在将 ...
- Ant.OutputIsUnreadableCode
Ant在Mac OS X终端中的输出乱码的问题 1. 问题: 在用Ant脚本进行构建Android App时,在编译失败时,Ant 输出有乱码. 2. 环境: Mac OS X, 简体中文版.在Ter ...
- iOS.BackgroundTask
Background Task 的运行时间在iOS 6及以前有大约10分钟左右,在iOS 7中有180秒. Reference: 1. Multitasking in iOS 7 http://www ...
- 探索未知种族之osg类生物---呼吸分解之事件循环一
事件循环和更新循环 终于到了我们嘴里经常念叨的事件循环.更新循环以及渲染循环了.首先我们来区分一下事件循环和渲染循环,他们两个首先是两个不同顺序执行的过程,我们有时候会用到任意node的updateC ...