Natty Precise Maverick

    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 平台的更贴切的整合

    Install

    npm i generator-clam

    DownloadsWeekly Downloads

    10

    Version

    0.1.86

    License

    none

    Last publish

    Collaborators

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