generator-clam

0.1.86 • Public • Published

Clam - 航旅前端基础工具集

〇,背景 & 设计原理

背景知识

1. 航旅 H5 的多宿主环境

航旅 H5 页面的多种宿主环境示意,同一份源码通过 Clam 面向多终端构建不同的目标代码,目标代码有三类:

  1. 线上 URL 访问的 Wap 页面
  2. 带有虚拟域的 H5 离线包容器
  3. 不带虚拟域的 H5 离线包容器

Clam 为每个项目生成构建脚本本地环境,并最大程度保持开发和线上环境的一致性。开发、调试、测试、发布 过程均在命令行即可完成。

2. Clam 工具与线上环境的关系

普通发布为 Wap 页的模式和传统的开发和发布一样,我们首先要区分:

  1. 项目源码线上目标代码,两者有一一对应关系
  2. 因为前后端完全解耦、所以套页面完全由前端负责
  3. grunt-combohtmlgrunt-flexcombo一个负责构建、一个负责服务,原则上两者同构
  4. HTML覆盖式发布、js、css非覆盖发布,即时发布即时生效
  5. 性能需要考虑
    1. 资源请求数
    2. 懒惰加载
    3. DomReady 时间提前

3. Clam 工具与离线包环境的关系

客户端容器以虚拟域形式加载离线包(在离线容器加载页面所用URL和线上地址完全一样),clam 在构建完成build_offline.zip后,所有资源文件均以相对目录存放。前端将zip包更新到CDN上(非覆盖),由QA或者推包管理员更新config.json配置,完成对客户端的推包操作。

性能考虑除了请求数量、懒惰加载和DomReady时间之外,还需要考虑zip包的大小。

一,工具安装

安装 TNPM(阿里工程师必备)

npm install tnpm -g --registry=http://registry.npm.alibaba-inc.com

安装 clam

tnpm install -g generator-clam grunt-cli yo bower generator-kpm awpp

配置AWP平台的用户名和token

awpp config

根据提示输入用户名(花名)和token(从AWP平台中可查找到)

获取帮助(重要

yo clam:h

Done!

二,初始化一个 H5 项目结构

由于 assets 发布依赖 git,html 发布依赖 awp,请务必保证拥有两者的权限

在gitlab中新建项目(比如h5-test),并在本地checkout出目录,进入到h5-test目录中,执行

yo clam

根据提示完成初始化任务:

初始化完成后默认没有安装node_modules,需要手动执行命令补全npm包,立即执行

tnpm install

H5项目架子初始化完成(注意:这时只有结构,没有页面),目录结构如下:

.h5-test
	├── build/
	├── docs/
	├── Gruntfile.js
	└── src/
	    ├── config.js
	    ├── map.js
	    ├── widgets/ 
	    ├── mods/
	    │   └── def
	    │       ├── demo.html
	    │       ├── index.css
	    │       ├── index.html
	    │       └── index.js
	    └── pages/
	        └── abc/
	            ├── img/
	            ├── index.scss
	            ├── index.html
	            ├── mock.tms.html
	            └── index.js

其中widgets存放组件,pages存放页面,mods存放抽象出来的业务模块

H5项目以工程为单位,而非页面为单位,比如机票H5用工程h5-flight表示

三,新建页面

进入到src/pages

cd src/pages

新建H5页面

yo clam:h5

根据提示完成

新建PC的页面使用yo clam:page命令 初始化页面时会提示安装依赖的包文件,通常选择Yes

四,H5 项目的本地包和离线包构建

h5-test中执行

grunt build

自动进行构建操作,如果是在gitlab的daily/x.y.z的分支上,则可以直接执行

grunt

如果在创建项目的时候设定是H5项目,则grunt会自动构建离线包,会生成目录build_offlinebuild_offline.zip

五,离线包构建需手动配置的参数

grunt build命令会构建好build_offline离线文件,为了减少H5容器读写本地文件的压力,clam 也多做了两件事情

  1. 生成cache_info.json
  2. kmc 合并 js 文件

这两件事需要项目开发者手动配置

生成cache_info.json时需要手动指定项目的首页地址,需要手动修改abc.json里的basePathbaseUrl,比如

...
"basePath": "pages/search/index.html",
"baseUrl": "/trip/test/search/index.html",
...

合并js文件需要手动指定,修改abc.json中的kmcOffline字段,比如

"kmcOffline": [
	"search/index.js",
	"searchlist/index.js"
],

六,Assets 的预发和上线

航旅H5项目是完全前后端解耦,所有页面都是静态的,动态数据都是异步拉取。一个完整的项目包含两部分内容,资源文件HTML文件

  • 资源文件(CSS、JS)使用gitlab来推送发布
  • html使用awp平台来推送发布。

这两类推送和发布实质上是通过git(若干)命令和awpp命令完成的,为了简化git的发布,clam 所携带的 gruntfile.js 对 git 命令做了封装。

首先,gitlab的发布必须基于daily/x.y.z的分支,第一步我们新建新的分支,如果新建或升级小版本(x.y.z中的z)则可以使用命令

grunt newbranch

预发操作

发布之前必须先构建

grunt

构建会生成build目录,build目录里的资源文件都会被发布,再执行

grunt prepub

这时会将当前分支代码push到线上仓库,这会自动触发预发,命令行提示中会给出预发地址

上线操作

在分支里执行

grunt publish

这时会基于当前代码分支生成名为publish/x.y.z的tag,并推送到线上 CDN,这会自动触发发布操作,发布操作会将远程daily/x.y.z分支删除,并将代码合并到master,发布完成后命令行提示会给出线上地址

如何获得资源文件线上地址

当Git代码仓库名称确定后,线上地址也随之确定,如果仓库名为h5-test,那么资源文件线上路径是:

http://g.tbcdn.cn/trip/h5-test/x.y.z/

其中x.y.z是分支中daily/x.y.z版本

七,H5 项目中的 HTML 的预发和上线

执行grunt后生成的build目录里包含构建完成的js、css和html文件,如果当前的这个工程是一个H5工程(abc.json中的isH5是否为true),则可以通过awpp命令来发布build/pages里的html

在gitlab仓库的根目录下执行

awpp

在提示下选择发布类型和文件:

如果git仓库名是h5-test,那么 HTML 的线上根路径是:

http://h5.m.taobao.com/trip/test/

只有在pages里的html文件才会被发布,比如src/pages/search/index.html会发布到http://h5.m.taobao.com/trip/test/search/index.html

TIP: 如果选择日常或者预发,需要注意,html里对线上资源文件的引用http://g.tbcdn.cn都应当修改成对预发资源的引用http://g.assets.daily.taobao.net,在执行awpp走预发流程之前,先执行grunt daily

八,开发模式、调试模式、离线模式服务的启动

Clam 工具提供一套本地调试环境,这套环境跟随代码一同携带,共有三个环境

1). Demo 环境启动,是基于src/目录启动服务

grunt demo

浏览器绑定本机8080端口后,访问demo.com即可

2). Debug 环境启动,是基于build/目录启动服务

grunt debug

浏览器绑定本机8080端口后,访问线上路径

3). 离线包环境启动,是基于build_offline/目录启动服务

grunt offline

绑定8080端口后,访问线上路径,同debug模式

三种模式都必须由浏览器、或者手机设备绑定IP:8080端口的代理,然后访问demo.com或者命令行提示中给出的几个域名,比如在手机端设代理的方法:

如果是调试线上页面,则需要开启grunt debug模式,然后修改src里的js文件,打断点后会立即被构建到build,刷新线上文件即可所见即所得的debug

线上URL映射到本地文件

在Gruntfile.js中给flexcombo配置项增加了filter配置,比如

proxyHosts:['demo','demo.com','h5.m.taobao.com'],
filter:{
	'-min\\.js':'.js',
	// 访问 h5.m.taobao.com/trip/h5-trains/search/index.html
	// 将重定向到 ./build/pages/search/index.html
	// Example: '(.+)/trip/h5-train/\(.+\\.\)html':'$1/pages/$2html'
	'(.+)/trip/[^\/]+/\(.+\\.\)html':'$1/pages/$2html'
}

执行grunt debug后,访问h5.m.taobao.com下的文件,都将转发请求到本项目文件,比如我访问

http://h5.m.taobao.com/trip/h5-trains/search/index.html

将实际访问我本机的这个文件

./build/pages/search/index.html

其中h5-trains是项目名称。如果想针对某个项目(比如h5-car)进行转发,可以这样

filter:{
	'(.+)/trip/h5-car/\(.+\\.\)html':'$1/pages/$2html'
}

如果想根据我们的命名替换规则,来做映射,可以这样写

filter:{
	'(.+)/trip/car/\(.+\\.\)html':'$1/pages/$2html'
}

filter中的key是一个字符串形式的正则表达式,value是被替换的字符串

九,去啊 App(>=5.1.1) 中,H5 离线包推包调试

针对ios设备需要首先生成zip文件,构建完成后,build/里的zip文件即是要发布的离线包文件,推送到Android中,使用命令:

sh ./push.sh

1. IOS 设备导入zip包

安装去啊App,链接到电脑,用iTools打开去啊App的设备目录,找到library/data/resource目录,导入zip文件

2. Andoird 设备导入本地文件

Android不需要导入zip包,直接将build_offline里的文件覆盖Android里源文件即可,需要一台root权限的Android手机,链接到电脑,电脑安装好adb

在项目根目录下执行

sh ./push.sh

导入完成

十,轻便的 Mock:Juicer Mock 写法

Clam的本地服务是基于flex-combo来实现的,flexcombo支持Juicer Mock的语法来写带有数据的模板

在生成的H5页面或者PC页面目录中,都会带有一个mock.tms.html。这里的内容是典型的数据加模板的形式,模板语法遵循Juicer。类似这样:

<html>
<body>
	<!-- 定义Mock数据 -->
	<!--#def
		{"list": [
				{"name":" guokai", "show": true},
				{"name":" benben", "show": false},
				{"name":" dierbaby", "show": true}
			]}
	-->
	<ul>
		{@each list as it,index}
			<li>${it.name} (index: ${index})</li>
		{@/each}
	</ul>
</body>
</html>

开启服务后浏览器中访问它,将输出:

<html>
	<body>
		<!-- 定义Mock数据 -->
		<!--#def {"list": [ {"name":" guokai", "show": true}, 
		{"name":" benben","show": false}, 
		{"name":" dierbaby", "show": true} ]} -->
		<ul>
			<li>guokai (index: 0)</li>
			<li>benben (index: 1)</li>
			<li>dierbaby (index: 2)</li>
		</ul>
	</body>
</html>

即,数据和juicer模板混合输出了正确的结果。如果源文件中存在Mock数据字段<!--#def ... -->,则服务将会解析文件中的juicer模板

十一,Clam 项目中的 HTML 文件引用

本地服务支持标准SSI(Server Side Include)。

<!--#include virtual="../src/file-path.html" -->

引用线上文件可以直接写线上地址即可

<!--#include virtual="http://www.taobao.com" -->

十二,TMS 标签的引用

根据AWP规范,HTML页面中可以通过这种标示来引用外部静态文件

<!--HTTP:http://www.taobao.com/go/tms/dump.php,utf8:HTTP-->

AWP平台和Clam自带的本地服务都支持这种解析

此外,还支持TMS标签引用,比如

<!--TMS:/rgn/trip/smartbanner.php,gbk,181:TMS-->

需要注意的是,H5 项目的离线包的构建,会将这种格式的引用做过滤,详情阅读这里

十三,flexCombo 如何映射本地 HTML 片段

我们经常使用 Fiddler 和 Charles 工具把线上 URL 映射到本地资源,那么,可否将线上页面里的一段 HTML 片段映射为本地文件呢?FlexCombo 就可以做到。

本地服务的 debug 模式可以映射线上页面中的html片段到本地,配置方法见html-proxy

通过项目配置文件abc.json来配置,类似

"htmlProxy": [{
	"urlReg": "^http://trip.taobao.com/index$",
	"demoPage": "http://trip.taobao.com/index.php",
	"replacements": [{
		"fragment": "mods/demo/index.html",
		"selector": "#lg"
	}, {
		"fragment": "mods/nav/index.html",
		"selector": "#nv"
	}]
}],

例子:http://gitlab.alibaba-inc.com/trip/trip-home-slide

检出代码,依次执行:

git clone git@gitlab.alibaba-inc.com:trip/trip-home-slide.git
cd trip-home-slide
tnpm install
grunt debug

打开浏览器,绑定本机的8080端口,访问http://trip.taobao.com/index.php,看到首焦图片被替换了。done

这种模式非常有用,特别对于跨团队协作、高模块化的项目中尤其有用,比如在淘宝首页便民中心,便民中心的代码就可以被拆出来,以一个HTML片段(非整个项目)作为一个独立的项目,Clam 工具的这个特性将提供非常方便的调试入口

十四,组件代码的安装

如果要使用现成的组件,可以通过bower命令来安装,比如要使用calendar组件,则需要在src/widgets目录中执行:

bower install mpi/calendar

即可

十五,其他重要资料

每个项目的配置信息存放在abc.json中,组件代码仓库存放在pi中。组件源码在(mpitpi中)。

感谢这些开源项目

社区开源项目:

  1. grunt
  2. yeoman
  3. bower
  4. LessSass

内部开源:

  1. mpiCss
  2. kissy
  3. kissy-Mini
  4. grunt-kmc
  5. Juicer
  6. grunt-flexcombo
  7. flexcombo

内部重要资料:

  1. 本地开发与调试环境
  2. AWPP 发布工具使用
  3. generator-clam 工具手册(内部使用)

十六,Q & A

参照这里

十七,更新记录

  1. 0.1.x
    1. 脚手架基础功能,代码片段整理
    2. 完善flex-combo,gruntfile.js
    3. 完善grunt demo 和grunt debug调试模式
    4. 完成文档0.1版本,并确定工具的范围和中远期规划
  2. 0.1.73
    1. 离线包构建功能完善
    2. 更新flexcombo的离线包配置
    3. 文档更新
  3. 0.2.x
    1. H5 项目和PC项目独立区分
    2. H5项目的在线包和离线包的区分和分别打包
    3. AWPP 工具从clam剥离出来,形成独立的规范
    4. 和Gitlab、AWP 平台的更贴切的整合

Package Sidebar

Install

npm i generator-clam

Weekly Downloads

5

Version

0.1.86

License

none

Last publish

Collaborators

  • bachi
  • wayfind
  • gourdboy
  • paulguo
  • aloysious
  • enmaai
  • wylking2000
  • dickeylth