好文推荐系列---------(4)使用Yeoman自动构建Ember项目

好文原文地址:http://segmentfault.com/a/1190000000368881

我决定学习前端开发的效率工具Yeoman。本文将首先介绍Yeoman的基本情况,接着我们会使用Yeoman开发一个Ember应用。

Yeoman是什么?

Yeoman按照官方说法,它不只是一个工具,还是一个工作流。它其实包括了三个部分yo、grunt、bower,分别用于项目的启动、文件操作、包管理。

  1. Yo: Yo是一个项目初始化工具,可以生成一套启动某类项目必需的项目文件。
  2. GruntJS: GruntJS是基于JavaScript的命令行构建工具,它可以帮助开发者们自动化重复性的工作。阅读day 5获取更多信息。
  3. 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应用,自动使用bowernpm安装依赖。

现在让我们看看Yeoman生成的Ember应用。应用有三个顶层目录:appnode_modulestest。还有一些配置文件:.bowerrc.gitignore.jshintrcGruntfile.jspackage.json。目录结构如下所示。

所有的应用相关代码都在app目录下。目录结构遵循Ember的最佳实践。

  1. bower_components目录包括了客户端依赖,例如Ember、Twitter Bootstrap,等等。Bower在所有文件夹内安装所有依赖。
  2. image目录包括了应用相关的图像。Yeoman会优化image目录内的图片。
  3. index.html包含了所有的ember.js依赖,所有的bootstrap依赖,以及build注释(Gruntfile.js可以据此替换或移除引用的未优化的脚本和样式表)。
  4. scripts目录包含了Ember应用的controller、view、model和route。
  5. styles目录包含了应用相关的css文件。
  6. 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

今天就这些。保持反馈。

时间: 2024-10-20 02:47:00

好文推荐系列---------(4)使用Yeoman自动构建Ember项目的相关文章

使用Yeoman自动构建Ember项目

Yeoman是什么? Yeoman按照官方说法,它不只是一个工具,还是一个工作流.它其实包括了三个部分yo.grunt.bower,分别用于项目的启动.文件操作.包管理. Yo: Yo是一个项目初始化工具,可以生成一套启动某类项目必需的项目文件. Grunt: Grunt是基于JavaScript的命令行构建工具,它可以帮助开发者们自动化重复性的工作. Bower: Bower是一个客户端技术的软件包管理器,它可用于搜索.安装和卸载如JavaScript.HTML.CSS之类的网络资源. 安装

Yeoman自动构建js项目(转)

从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发.Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎.chrome浏览器就基于V8,同时打开20-30个网页都很流畅.Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低.非常适合小型网站,个性化网站,我们自己的Geek网站!! 前言有一种技术可以提高我们的工作效率,可以让我们专心做我们擅长的事,

gradle学习系列之eclipse中简单构建android项目

看不到图片可以去访问这个网址看看:http://pan.baidu.com/s/1o6FrFkA 一.什么是Gradle 官网www.gradle.org上介绍Gradle是升级版(evolved)的自动化构建工具.它可以自动构建,测试,发布,部署,同时使更多的软件包或其他类型诸如生成静态网站,文档等项目自动化. Gradle 将Ant的功能和伸缩性与Maven的依赖管理及约定结合成一种更加高效的方式去完成构建.它采用了Groovy 特定领域语言和诸多创新方法,提供了一种声明式的方式用合理的默认

配置Jenkins自动构建打包项目

需求说明 1.给A项目配置jenkins每2小时无条件自动构建一次,无论是否有代码提交.2.给B项目配置jenkins每15分钟检查一次是否有代码提交,如果有,就自动构建一次:如果没有commit,就不构建 配置操作 1 配置每15分钟检查更新,有更新就构建 1.1 创建一个测试项目iot-new-Dev 根据项目实际情况,选择的是pipeline 1.2 配置"构建触发器" 在"构建触发器" ==> 选择"Poll SCM" ==>

好文推荐系列--------(1)bower---管理你的客户端依赖

好文原文地址:http://segmentfault.com/a/1190000000349555 编者注:我们发现了比较有趣的系列文章<30天学习30种新技术>,准备翻译,一天一篇更新,年终礼包.以下是第一天技术的译文. 我决定将第一天的学习主题选为Bower. 什么是Bower? Bower是一个客户端技术的软件包管理器,它可用于搜索.安装和卸载如JavaScript.HTML.CSS之类的网络资源.其他一些建立在Bower基础之上的开发工具,如YeoMan和Grunt,这个会在以后的文章

好文推荐系列--------(3)GruntJS 在线重载 提升生产率至新境界

好文原文地址:http://segmentfault.com/a/1190000000354555 本文将首先介绍grunt-markdown插件如何配合HTML模板使用,接着我将介绍如何使用grunt-watch插件将工作效率提升至新层次.如果你不熟悉GruntJS,请先阅读我关于GruntJS的文章. Github仓库 今天的示例代码可以从github: day7-gruntjs-livereload-example中获取. 配合模板使用GruntJS的Markdown插件 在我上一篇Gru

好文推荐系列--------(2)GruntJS——重复乏味的工作总会有人做(反正我不做)

GruntJS 是基于JavaScript的命令行构建工具,它可以帮助开发者们自动化重复性的工作.你可以把它看成是JavaScript下的Make或者Ant.它可以完成诸如精简.编译.单元测试.lint检查等工作.由于越来越多的开发移到了客户端,帮助开发者更高效地工作的工具就更有用了.本文中,我将展示我如何使用GruntJS来精简javascript文件.我们也将使用GruntJS的markdown插件来将markdown文档转换为HTML5文档.让我们开始吧! 为什么开发者要关心GruntJS

Ubuntu系统下使用Jenkins进行项目的自动构建还是项目回滚方法

上面虽然实现了项目的自动部署,但是有时部署失败的时候我们需要回滚到指定版本的构建,这样才能更灵活的进行项目的构建部署.我们可以选择"参数化的构建过程"进行传递不同的参数来选择是进行新的构建还是回滚 如果要在实现回滚,一定要在构建后将,构建完成的文件进行存档,方便以后回滚的时候使用. 如果要在实现回滚,一定要在构建后将,构建完成的文件进行存档,方便以后回滚的时候使用 构建后存档 使用参数化构建过程,让后面的脚步可以根据不同的变量执行不同的操作.添加"Choice"参数

CentOS 7.2安装Jenkins自动构建Git项目

1.环境 本文使用VMWare虚拟机进行实验. 最终实现目标,在Jenkins服务器上新建构建任务,从Git服务器上拉取master HEAD(不编译,仅演示),部署到"目标服务器",再执行一个脚本. Jenkins服务器 2核CPU,4GB内存,20GB硬盘,IP:192.168.118.145(要求能上网,装插件) CentOS 7.2最小安装(CentOS-7-x86_64-Minimal-1511.iso) Git远程库服务器 IP: 192.168.118.148 已经存在一