聊聊前端脚手架

一、许多团队在制定前端工程方案时会加入脚手架模块。虽然不同的团队对工程化的理解和实施有所差异,但是对于脚手架的定位基本是一致的:创建项目初始文件。这是一条看起来十分简单地准则,但是对于这条准则应该如何理解,如何实施却并不是一件很简单地事情。

二、在探索这条准则的深度之前,我们不妨看看类似的一些成熟方案,比如Eclipse。这个大名鼎鼎的IDE软件被很多Java和Android开发者使用。通过Eclipse创建一个新项目时,它提供了丰富的配置项,这些配置项可以归纳简化为以下流程:选择项目类型 -> 选择项目目录 -> 配置项目细节 -> 最终确认 -> 完成。这是脚手架最基本也是必须具备的流程。从这个流程中可以总结出脚手架的本质:方案的封装。

三、脚手架作用是创建项目的初始文件,本质是方案的封装。

1.脚手架在前端工程中的角色

1.1 “用完即弃”的脚手架
595796-20170330204649539-235709455.jpg

脚手架在前端工作流中负责项目起始阶段创建初始文件。与其他功能模块不同的是,脚手架是一个完全“启下”的模块,它没有任何前置依赖。创建完成项目初始文件之后,脚手架就再无用武之地了。
“用完即弃”的工作模式令脚手架的实现由很大的跃迁性。你可以用最简单的复制粘贴就能完成脚手架的工作,而一个完备、成熟的脚手架即使提供了非常丰富的交互配置,最终目的也“只”是创建了一堆初始的项目文件。既然结果一样,那为什么还要花费时间和人力成品去开发复杂的脚手架方案呢?

这是一个非常现实的问题,互联网产品迭代的快速节奏下,开发团队最注重的就是投入产出比,而脚手架的投入产出比“看上去”是最低的。环顾目前前端的工具生态,最多的是构建工具,当然我们不可否定构建确实是最复杂的功能。而脚手架工具是最少的,前端社区对脚手架的讨论也非常稀少。你可能听说过大名鼎鼎的yeoman,但是很难再想出第二个脚手架工具了。
单独来看,脚手架可能并不具备很高的“性价比”,但如果你的团队有一套完整的前端工程体系,脚手架的作用就会被放大。前端工程体系的功能涵盖范围广,封装的方案类型多,对应的配置项也非常复杂。而且,大多数前端工程体系的开发者并不是一线的业务开发者。对于业务开发者来说,这套工程体系就是一个黑盒,他们不需要了解其中的复杂原理,只需要知道如何配置即可。所以业务开发者的需求就是快速开发快速配置,并且生成的配置项跟项目要对应,既要满足项目的功能需求,又不能有“混淆视听”的冗余功能。
前端工程体系不是Vue、React这种开发框架,工程体系只是一种“服务”,是辅助性质的。学习曲线应该平缓,即使文档再清晰易懂,也不应该要求业务开发者去花时间学习各种细节。这就是脚手架要解决的切实问题,简单说就是:
- 快速生成配置;
- 降低框架学习成本。
随着前端工程体系越来越复杂,脚手架的角色会越来越重要。
######1.2 脚手架需要具备的要素
1.2.1 执行环境仅限本地
在讨论实现一个脚手架要考虑哪些要素之前,我们不妨先看看脚手架的执行环境。回顾前文提到的简易前端工作流,最简单的情形是:框架提供一套完整的本地工具链,脚手架、开发、开发服务器、构建和部署测试都是在本地环境执行,如下图:
![595796-20170330204704883-611380969.png](http://upload-images.jianshu.io/upload_images/6380152-a8b9d510490efe2b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
进一步的团队会搭建CI(持续集成)平台,将构建和部署功能迁移至云端,这样做便于工作流程控制和代码统一管理。如下图:
![595796-20170330204715086-1453851525.png](http://upload-images.jianshu.io/upload_images/6380152-91cf6b80ed43320e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
不论哪种工作流,脚手架始终是在本地执行。
1.2.2 模式不固定
前端脚手架之所以没有固定的模式,是由于不同的公司对于前端工程师的定位不固定。比如有些公司的前端仍然是“切图仔”;有些公司的前端负责浏览器端的所有逻辑开发但是html模板层仍然由服务端工程师维护;还有些比较前沿的团队提倡“大前端”,负责浏览器层与中间层(主要承载html的渲染功能)。前端工程师定位的不固定造成了前端项目模式的不固定,脚手架自然也具备了多样性。
不论是哪种工作模式,一个优秀的前端脚手架都应该具备以下几点要素:
      1.丰富但不繁琐的配置项;
      2.与其他功能模块联动,生成对应的基本配置项;
      3.自动安装依赖;
      4.底层的高度可扩展性;
      5.支持多种运行环境,比如命令行和Node.js API。
如何理解“丰富但不繁琐”呢?举个例子,假设构建功能支持自动生成css sprites,配置项有两个:
    1.是否启用css sprites;
    2.指定散列icon目录。
脚手架在实现针对css sprites的配置项时是不是应该将这两个配置都开放给用户配置呢?显然是不需要的,脚手架只要开放是否启用css sprites的配置项即可,因为这是影响这项功能最重要的一点,散列icon的目录即使用户不配置,使用默认的方案也不会造成任何不便。
另外,在实现脚手架时不应该只看到当前的需求,还应该考虑后续需求的变更和新增。所以一个优秀的脚手架应该具备高度的可扩展性,便于定制不同类型的方案。从这个角度来说,目前yeoman是做得最好的。

####2. 开源前端脚手架方案剖析
>明确了脚手架的基本工作模式,我们不妨看看目前业内有哪些可以借鉴的案例。我们在这里介绍三种形态的脚手架:
- [sails](http://sailsjs.com/)是一个Node.js fullstack框架,其使用的[sails generate](http://sailsjs.com/documentation/reference/command-line-interface/sails-generate)脚手架主要是针对服务端代码设计;
- 优酷PHP中间层框架是笔者前团队使用的开发框架,目前并未开源。其使用的脚手架相对sails来说比较简单,只能创建一个完整的webapp,包括Controller层和浏览器层代码;
- [yeoman](http://yeoman.io/)是广为人知的开源脚手架工具,它本身不提供任何直接创建文件的功能,而是一个脚手架底层框架,你可以定制自己的脚手架实现。
######2.1 sails - Node.js fullstack框架
sails是一个Node.js全栈框架,服务端使用MVC架构。[sails generate](http://sailsjs.com/documentation/reference/command-line-interface/sails-generate)是sails的脚手架模块,默认可以创建以下几种模块的初始代码:
- app - 创建一个新sails项目;
- api - 创建一对model和controller;
- model - 创建一个model;
- controller - 创建一个controller;
- adapter - 创建一个adapter;
- generator - 创建一个脚手架模板。
~~~sails框架中的[Adapter](http://sailsjs.com/documentation/concepts/extending-sails/adapters)可以简单理解为简化model操作API的映射适配器。
大家注意最后一种类型:generator。sails在默认的脚手架基础上,开放了自定义脚手架模板的[API](http://sailsjs.com/documentation/concepts/extending-sails/generators/custom-generators)。
sails默认的脚手架大都是针对服务端代码的,如果不借助其他脚手架模板,浏览器端的代码(JavaScript/CSS/Views)只能手动添加。
######2.2 优酷 - PHP中间层框架
优酷的PHP中间层框架并未开源,所以就粗略的介绍一下吧。
中间层框架不涉及Model层,不涉及数据库操作,只包括Controller和View层。这个框架的理念是:任何一个模块都被视为一个webapp,每个webapp都是一个SPA,比如登录/注册模块Passport、订阅模块Subscribe等。脚手架只能创建一种文件类型:一个完整的webapp。其中包括Controller文件、Resource文件(浏览器层)和路由配置文件。
由于每个模块webapp都是一个SPA,包含一个Controller文件,一个view入口文件、一个入口js文件和一个css文件,所以脚手架创建的初始文件就已经够用了,开发者只需要手动添加子模块文件即可。同时,技术栈统一,build功能封装完备,不需要额外配置。这种形态的脚手架基本满足了优酷PHP中间层框架的需求
######2.3 yeoman - 可能是最好的开源脚手架框架
提起脚手架这三个字就不得不提yeoman这名老将。Yeoman在2012年Google I/O上首次发布,至今已经5年的光景了。对于前端技术圈子来说,5年的时间可以让绝大部分的技术遭到淘汰,而yeoman坚持到了今天,且扔未现衰退之势。我们可以短暂回顾一下5年前的前端技术,你可能会想到Knockout和Backbone,也可能会想到YUI 3,甚至可能会想起被ExtJS所支配的恐怖。然后再看看这些在当时热火朝天的技术目前的市场状态,是否都已是昨日黄花垂垂老矣?而yeoman之所以能“活”这么久,得益于它明确的定位。
yeoman的slogan是“THE WEB'S SCAFFOLDING TOOL FOR MODERN WEBAPPS”-脚手架工具,但我个人认为称之为脚手架框架更为合适。yeoman不能直接创建项目文件,它提供了一套完整的开发脚手架API,你可以通过这些API定制符合自己业务需求的任意的脚手架方案。换句话说,yeoman不封装任何方案,它是完全开放、高度可扩展的。
yeoman的API具备了前文所列出的脚手架需要具备的所有要素,如果你需要开发一个属于自己的脚手架,yeoman是最好的选择。后续的博文会详细介绍如何使用yeoman提供的Node.js API将其集成到工程化框架中。

###3. 总结
虽然前端脚手架没有固定形态,但是有必须具备的要素。从功能实现的角度,要考虑与业务的高度匹配;从底层框架的角度,要具备高度的可扩展性和执行环境多样性支持。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容