使用 Yeoman 生成 backbone,requirejs 项目

背景

现在搞前端开发,不用个什么框架都不好意思说自己是前端,什么React,angular,backbone,只用jquery都不好意思跟别人打招呼。比如说现在想搞一个小项目,选了一个框架,看完文档云里雾里,看别人的实践,更加迷惑,完全不知道他要干什么。

技术是为人服务的,不能为了用框架而用框架,学了半天感觉越学越不明白,究竟是我用框架还是框架用我?
假如有一种工具,一键生成相应框架的最佳实践,模块化等只要一件生成,就像软件开发的IDE,是不是很爽呢?

老外早就想到这个问题了,这个工具就叫做Yeoman。

使用 Yeoman 生成 backbone,requirejs 项目

准备

  1. 忘掉框架本身,专注于模块化,和项目本身

  2. 一台装好node,git的lunix或者windows

搭建一个backbone + requirejs 的项目

第一步 安装yoeman

npm install -g yo

-g 是global,意思是装到你电脑里了,而不是当前目录,并且为系统状态里添加了yo命令

第二步 安装你想使用的项目模板

这里以backbone为例 https://github.com/yeoman/generator-backbone

npm install -g generator-backbone

第三步 创建backbone项目

进入你预先准备好的项目目录下,输入

yo backbone
  • 如果你的generator-backbone 没装好,yo会提示你没有相应的generator

  • yo的提示很友好,大多数问题都可以在shell里的英文文本里得到帮助

安装过程中会让你输入一些选项,比如

使用 Yeoman 生成 backbone,requirejs 项目

这个generator,可以自动生成sass写的bootstrap, coffeescript, requirejs,modernizr,很神奇有没有,省去了很多细节的关注,科技就是服务于生产的。

选择完成以后:

使用 Yeoman 生成 backbone,requirejs 项目

**翻译:除了选择的以外,我们还包含了html5模板,jquery 和 backbone.js,额外选择列出来 bootstrap,coffeescript,requirejs modernizr
创建的文件包括如上图所示,也就是yoeman给我们生成的项目的结构:**

  • package.json - npm 依赖配置

  • bower.json - bower 依赖配置

  • gruntfile.js - grunt打包配置

  • app/ - 项目根目录

  • test/ - 测试文件

完成以后,系统会自动跑npm install && bower install。

使用 Yeoman 生成 backbone,requirejs 项目

npm多数是node写的开发部署类工具库,包括bower,bower本身是在npm install里面安装的。而bower是前端项目用到的库安装工具,比如jquery,比如backbone,bower装出来的东西跟node没关系。

启动测试

grunt是一个打包和部署工具,在项目里通常用来启动测试服务器,动态处理sass,coffeescript,livereload(动态将更新反映在浏览器上),等等等等。

yoeman里的grunt通常给你提供一个serve方法,同时你也可以用grunt build来打包,打包好的文件会生成在dist目录下。

使用

grunt serve

启动测试服务器,如图

使用 Yeoman 生成 backbone,requirejs 项目

目前空板项目文件是这样的:

使用 Yeoman 生成 backbone,requirejs 项目

index.html是入口,通过require调用了main.js (不熟悉coffee还是用了js,如果采用coffee,这里是main.coffee)

main.js

/*global require*/
'use strict';

require.config({
  shim: {
    bootstrap: {
      deps: ['jquery'],
      exports: 'jquery'
    },
  },
  paths: {
    jquery: '../bower_components/jquery/dist/jquery',
    backbone: '../bower_components/backbone/backbone',
    underscore: '../bower_components/lodash/dist/lodash',
    bootstrap: '../bower_components/bootstrap-sass-official/assets/javascripts/bootstrap'
  }
});

require([
  'backbone'
], function (Backbone) {
  Backbone.history.start();
});

目前的main.js,做了简单的require配置,然后进行了一个require调用,载入了backbone,调用了backbone.history.start()。

增添血肉

现在这个项目可以说骨架已经有了,而且压根就没费什么脑细胞,很好,接下来的工作稍微要有费点脑细胞,就是添加模块,以及相应组件提供的一些东西。backbone里:

  • model:数据模块

  • view:页面组件

  • collection:模块组

  • route:路由模块,提供路由功能

用yoeman来生成这些模块和组件。我说要费点脑细泡,是因为这个时候你要根据你的项目,来做一些抽象,想好都需要哪些模块,哪些部分。

生成方法就是在命令行里输入

yo backbone:model foo

如果使用 yo backbone:all foo 就是生成一套从model到route。通常来说,backbone项目的model和collection都是成对出现的,view通常也对应到一个model。

生成了一些东西以后,我们的项目大概是这个样子:

使用 Yeoman 生成 backbone,requirejs 项目

相应的模块,都被自动生成到script里了,同时,views模块会自动生成配对的templates文件,默认的系统采用的是ejs html模板引擎,对应的views下面的js会调用自己的*.ejs,具体实践看代码就明白了。

自己要做的东西

各种模块抽象好了,生成好了,然后怎么把它们放在页面里,怎么进行路由?

其实这也是我开始苦恼的问题,后来经过一些研究,发现是这么调用的。

首先,backbone项目通常有一个最顶层的appView 的 view, 动态的页面主体。(静态的页面主体就写在index.html好了)。还有一个根据hash来页面定位的路由。所以,我们只要把这两个东西写在main.js里就好了,剩下的东西由require来处理。

代码如下:

require([
  'backbone',
  'views/appView',
  'routes/foo'
], function (Backbone, appView, routes) {
  new routes();
  Backbone.history.start();
  new appView();
});

国外比较流行这种AMD依赖前置的方法,将我们生成的appView和routes,直接放到入口调用里,这些返回的都是类方法,直接new 他们就好了。

new 一个 backbone view的时候,会调用它的intialize方法。

appView.js

/*global define*/

define([
  'jquery',
  'underscore',
  'backbone',
  'templates'
], function ($, _, Backbone, JST) {
  'use strict';

  var AppViewView = Backbone.View.extend({
    template: JST['app/scripts/templates/appView.ejs'],

    tagName: 'div',

    id: 'appView',
    el: '#appView',
    className: '',

    events: {},

    initialize: function () {
       // 初始化的时候,把template渲染到$el里
      this.$el.html(this.template());
    }
  });

  return AppViewView;
});

再来看一下router

/*global define*/

define([
  'jquery',
  'backbone',
  'views/appView'
], function ($, Backbone, app) {
  'use strict';

  var FooRouter = Backbone.Router.extend({
    routes: {
    // 这里的意思是#info 指向到info方法,info方法里,我们调用了appView的render方法,也可以trigger其他模块的事件,理论上应该都是通过trigger来完成页面切换的。
        'info': 'info'
    },
    info: function () {
        app.render();
    }

  });

  return FooRouter;
});

小结

当然,目前的项目也很简陋,很多backbone里模块之间的关联事件,都需要手动完成。但是对于前期一些重复性工作,用yeoman可以做到高效开发,而且对底层框架的原理和实现全都可以不用关心,把重点放在业务抽象上面。

  • 我觉得yoeman非常适合一些玩票性质的项目。

  • 如果想学习相应框架的实践应用,可以先看看yoeman 里generator是怎么做的。

  • 看yoeman自动生成的模版,有利于学习国外一些新的技术,对理解框架有帮助。

相关推荐