Chasingsun 2019-06-20
现在搞前端开发,不用个什么框架都不好意思说自己是前端,什么React,angular,backbone,只用jquery都不好意思跟别人打招呼。比如说现在想搞一个小项目,选了一个框架,看完文档云里雾里,看别人的实践,更加迷惑,完全不知道他要干什么。
技术是为人服务的,不能为了用框架而用框架,学了半天感觉越学越不明白,究竟是我用框架还是框架用我?
假如有一种工具,一键生成相应框架的最佳实践,模块化等只要一件生成,就像软件开发的IDE,是不是很爽呢?
老外早就想到这个问题了,这个工具就叫做Yeoman。
忘掉框架本身,专注于模块化,和项目本身
一台装好node,git的lunix或者windows
npm install -g yo
-g
是global,意思是装到你电脑里了,而不是当前目录,并且为系统状态里添加了yo命令
这里以backbone为例 https://github.com/yeoman/generator-backbone
npm install -g generator-backbone
进入你预先准备好的项目目录下,输入
yo backbone
如果你的generator-backbone 没装好,yo会提示你没有相应的generator
yo的提示很友好,大多数问题都可以在shell里的英文文本里得到帮助
安装过程中会让你输入一些选项,比如
这个generator,可以自动生成sass写的bootstrap, coffeescript, requirejs,modernizr,很神奇有没有,省去了很多细节的关注,科技就是服务于生产的。
选择完成以后:
**翻译:除了选择的以外,我们还包含了html5模板,jquery 和 backbone.js,额外选择列出来 bootstrap,coffeescript,requirejs modernizr
创建的文件包括如上图所示,也就是yoeman给我们生成的项目的结构:**
package.json - npm 依赖配置
bower.json - bower 依赖配置
gruntfile.js - grunt打包配置
app/ - 项目根目录
test/ - 测试文件
完成以后,系统会自动跑npm install && bower install。
npm多数是node写的开发部署类工具库,包括bower,bower本身是在npm install里面安装的。而bower是前端项目用到的库安装工具,比如jquery,比如backbone,bower装出来的东西跟node没关系。
grunt是一个打包和部署工具,在项目里通常用来启动测试服务器,动态处理sass,coffeescript,livereload(动态将更新反映在浏览器上),等等等等。
yoeman里的grunt通常给你提供一个serve方法,同时你也可以用grunt build来打包,打包好的文件会生成在dist目录下。
使用
grunt serve
启动测试服务器,如图
目前空板项目文件是这样的:
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。
生成了一些东西以后,我们的项目大概是这个样子:
相应的模块,都被自动生成到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自动生成的模版,有利于学习国外一些新的技术,对理解框架有帮助。