淘北京前端Assest环境和构建工具
工具介绍PPT:Speakerdeck。
- 目标:是通过
yo clam
来将你引路到Grunt,帮助你更熟练的使用Grunt。 - 面向人群:面向阿里系前端工程师,帮助你创建标准的KISSY项目结构代码和Widgets代码。
- 愿景:打造一款无负担的前端开发脚手架工具,打破产品间的代码共享壁垒,让你的代码充满幸福。
环境依赖:Node、Npm,视频演示:http://ascii.io/a/4384。
npm install yo grunt-cli -g
安装Generator-Clam:
npm install -g generator-clam generator-kissy-gallery
命令:
yo clam:h
:打印帮助yo clam
:初始化一个标准的Projectyo clam:mod
:初始化一个模块yo clam:page
:初始化一个Pageyo clam:widget
:初始化一个标准kissy组件,首先创建组件空目录,进入空目录后执行此命令yo clam:widget x.y
:生成一个标准kissy组件的版本,进入到组件目录后执行。其中x.y是版本号yo clam:on
:启动web服务,服务支持SSI,推荐使用grunt server
yo clam:install <git>
:(TODO)git可以是git地址,也可以是Gallery模块名称,都将对应的git项目源码下载到本地,类似svn export
yo clam:search <name>
:(TODO)在Gallery中查找现有的匹配的模块名称
依赖Bower
sudo npm install -g bower
安装最新包
bower install tpi/button
使用老的包
bower install tpi/button#publish/0.1.0
更新包
bower update tpi/button
初始化完成的项目包含Gruntfile.js
模板,可以辅助你完成:
grunt
: 执行构建grunt prepub
:执行预发grunt publish
:执行发布grunt info
:查看当前库git地址grunt newbranch
:创建新daily分支,基于当前版本累加grunt watch
:监听文件修改,实时编译grunt server
:开启本地Demo调试模式grunt debug
:开启生产环境Debug模式grunt combohtml
:构建包含SSI的html,合并页面中的css和jsgrunt build
:默认构建流程
本地调试调用了flex-combo,访问绝对路径时和本地目录有一个映射关系,比如绝对地址映射到项目的src
目录:
http://g.tbcdn.cn/group/project/ => ./src/
启动本地服务:grunt server
Gruntfile.js
是Grunt脚本规则文件,此外项目基本参数存放在abc.json
中,生成好的abc.json
格式如下:
{
"name": "h5-test",
"desc": "description of your app",
"type": "clam",
"port":"80",
"group":"trip",
"src":"false",
"version":"0.0.1",
"author": {
"name": "",
"email": ""
},
"repository": {
"type": "git",
"url": "http://gitlab.alibaba-inc.com/trip/h5-test"
}
}
生成一个新的daily分支(grunt newbranch
)时会自动更新abc.json
的version
字段。
ps:grunt构建任务依赖
grunt-mytps
子任务,该子任务(上传本地图片到CDN并替换地址)依赖python,并需要安装tpsmate。
- flexcombo FlexCombo,本地服务器的核心
- Grunt-combohtml,合并SSI的html,生成合并好的js和css
- Grunt-flexcombo,flexcombo的grunt版本
- Grunt-mytps,上传本地图片到tps服务器,依赖python
- Grunt-toascii,把文件中的非英文字符转码成对应的ascii码
- Grunt-cssimage,对css文件中的图片进行压缩替换,支持远程图片抓取
- jayli-server,Simple-SSI Server,包含flexcombo模块
- kissy-gallery,kissy gallery 组件构建工具
- Grunt-kmc,KISSY 模块构建工具(Grunt版本)
- KMC,KISSY 模块构建工具
1,创建新项目
yo clam
构建新项目时会生成Gruntfile.js。之后你只需特别关注Gruntfile.js即可。
2,接手项目
如果你要接手一个项目,代码检出后即可进行调试;在运行grunt
命令之前需要运行npm install
。
3,标准格式的KISSY组件
KISSY标准组件的构建使用yo kissy-gallery x.y
,已经被映射为yo clam:widget
,KISSY标准组件是可以直接构建为可发布到淘宝CDN的代码,并提交至kissy gallery
中。因此,你的项目中所有widgets都应当和KISSY标准组件格式保持一致,方便被其他项目使用。
推荐使用方法2
Generator-clam 提供一个轻服务(只提供静态文件服务器、Flex-Combo 和SSI支持),启动服务后你可以这样访问Demo:
http://localhost:8888/src/pages/detail.html?ks-debug
这里的SSI兼容apache,这个Server只提供Demo环境,且不支持脚本,如果需要,可以使用apache+php来作为本地demo服务,Clam只作为构建工具使用。
Grunt中模板中提供grunt server
方法,开启本地Demo服务,默认开启在80端口,在abc.json
中修改端口配置。grunt server
封装了flexcombo
,提供一种最基本的服务:即线上CDN环境映射到本地目录,直接访问屏幕提示给出的URL即可(g.tbcdn.cn host指向本地)
[bachi@yahoo ~/temp/h5-test]> sudo grunt server
Running "server" task
Running "flexcombo:main" (flexcombo) task
Preview: http://g.tbcdn.cn/trip/h5-test/
Flex Combo Server running at http://127.0.0.1:80
访问demo时应当带上?ks-debug
,上线后的项目引用config.js
的绝对地址即可。
如果想测试build完成后的代码,可以在本地创建软连接,映射线上版本号,通过grunt server
启动服务来测试:
ln -s build src/0.1.8
访问http://g.tbcdn.cn/group/project/0.1.8/.../demo.html
本地环境依赖flexcombo,更多用法参照官方帮助
如果你的项目用clam生成,且已经上线了,如何debug其中一个源JS?
1,将项目git源码checkout到本地(比如目录path/to/local_pro/
)
2,开启Debug模式
sudo grunt debug
这时开启了本地服务,并将目录映射到了build/
下,同时开启了对src/
中文件修改的监听
3,在'src'
目录中给你的js加断点即可
移动终端不能配host,但是可以配置代理的,我们使用 apache 做正向代理来访问源码,代理配置(例如开启apache的8080端口,Node服务采用80端口):
ProxyRequests On
ProxyVia On
<Proxy *>
Order deny,allow
Deny from all
Allow from all
</Proxy>
<VirtualHost *:8080>
ProxyPreserveHost On
ProxyRequests Off
ServerName g.tbcdn.cn
# 如果代理服务器和源码在一台电脑上,指向localhost即可,否则填写源码所在的机器IP
ProxyPass / http://localhost/
ProxyPassReverse / http://localhost/
</VirtualHost>
同时源码直接开启 Debug 模式,调试构建好的代码
为了限制在daily分支上发布,我们将grunt构建也加了限制,非daily分支上禁止构建,不建议将此限制去掉,只有build目录中的文件会被发布,所发布的项目中build目录中的文件地址为如下两种,前缀自选
http://a.tbcdn.cn/g/group-name/project-name/x.y.z/mods.js
对应到 g.tbcdn.cn 的地址:
http://g.tbcdn.cn/group-name/project-name/x.y.z/mods.js
代码发布命令:
grunt prepub
预发grunt publish
发布
2013年淘系全面推广基于Gitlab的Assets发布,Generator-Clam 延续了Clam模块化的思想,结合Yeoman和Grunt提供了面向淘系前端环境构建脚手架工具,包含前端开发/构建/发布的全流程。Generator-Clam 对代码单元做更自由的定义,根据适用范围,任何代码单元从三个维度管理:
- 项目(project)(代码集合最大单位)
- 模块(module)(业务功能单元,部分业务之间可共用)
- 组件(widget)(可全局共用)
最初Clam独立出了Page,Page本身也是一个模块,这里统一用模块来管理。这里的yo clam:page
只是生成一个引用了KISSY种子的空页面。
代码单元有自身属性,自身属性只是为了区分其适用范围和生命周期,为了保持约定简单,代码单元在层级上不再做规定,所有模块单元都相互平行,代码之间的依赖和相互引用,取决于你对业务的拆解,不是脚手架的职责。
最重要的,互联网项目的需求是涌现式的,项目的前端架构和设计是在开发中不断调整修改而来,而非开始就设计完成不再动了,这也是代码组织结构尽可能保持和业务弱相关的原因。
最最重要的,组件级(widget)代码从开始就保持标准规范(Kissy Gallery),抽离出项目更方便,这在无常的Web项目中是唯一的促成积累、沉淀代码的方法。
yo clam
可以引导你创建三种格式的目录结构,
第一种,src
目录和build
目录平行,src
目录中直接承载代码单元,推荐第一种
./
├── build/ - 构建完成后发布目录
├── doc/ - 生成的文档目录
├── Gruntfile.js
└── src/ - 项目源码目录
├── ~page1/ - 页面1
│ ├── img/
│ ├── index.css
│ ├── index.html
│ ├── demo.html
│ └── index.js
├── mod1/ - 模块1
│ ├── img/
│ ├── index.css
│ ├── index.html
│ └── index.js
├── mod2/ - 模块2
│ ├── img/
│ ├── index.css
│ ├── index.html
│ └── index.js
└── widget1/ - 一个Kissy组件
├── 1.0
│ ├── build/
│ ├── demo/
│ │ └── index.html
│ ├── guide/
│ │ └── index.md
│ ├── index.js
│ ├── meta/
│ │ ├── alias.js
│ │ └── modules.js
│ ├── plugin/
│ └── spec/
└── Gruntfile.js
第二种,src
目录中划分出pages
/mods
/widgets
三个目录,主要是为了兼容老的Clam项目
第三种,代码单元和build
目录平行,即无src
目录:
./
├── build/
├── doc/
├── Gruntfile.js
├── index.css - 入口css文件样板
├── index.html - 入口html文件样板
├── index.js - 入口js文件样板
├── mod1/ - 模块1
│ ├── img/
│ ├── index.css
│ ├── index.html
│ └── index.js
├── mod2/ - 模块2
│ ├── img
│ ├── index.css
│ ├── index.html
│ └── index.js
└── widget1/ - 一个kissy组件
├── 1.0/
│ ├── build/
│ ├── demo/
│ │ └── index.html
│ ├── guide/
│ │ └── index.md
│ ├── index.js
│ ├── meta/
│ │ ├── alias.js
│ │ └── modules.js
│ ├── plugin/
│ └── spec/
└── Gruntfile.js
以上三种目录结构中,widget均和KissyGallery标准组件保持一致。
1,'yo clam'安装node模块的时候报错?
npm ERR! Error: EACCES, mkdir '/usr/local/lib/node_modules/grunt-xx'
- 原因:没有sudo
- 解决办法:在当前目录执行
sudo npm install
2,tpsmate安装完了还是不能把图片自动上传CDN?
- 原因:需要首先找到
node_modules
中手动执行一次 - 解决办法:进入
node_modules/grunt-mytps/tasks/lib/tpsmate/src
,执行python ./cli.py upload
,这时提示你输入TMS用户名和密码,完成即可
详细文档参照:https://github.com/sodabiscuit/tpsmate
3,tpsmate安装完成,但执行报错?
-
原因:依赖包不完整
-
解决办法:安装tpsmate的依赖
pip install -r node_modules/grunt-mytps/tasks/lib/tpsmate/src/requirements.txt
4,yo clam 构建好目录结构后安装npm包时间太长,怎么办?
- 原因:构建项目最后使用
npm install
安装npm包 - 解决办法:在首次构建项目的时候最后一步询问是否安装本地
node_modules
,输入N
,在当前目录使用npm install --link
,将包安装到全局。以后每次yo clam
最后都不安装本地包,使用npm install --link
来安装,速度会很快。
5,yo clam:mod 构建好一个模块后,怎么运行它?
直接访问生成好的html文件,xx/index.html?ks-debug
,会有弹框"ok"。
6,生成的默认Gruntfile.js只根据入口文件合并JS,我如何生成依赖关系表mods.js ?
修改Gruntfile.js,参照注释修改kmc任务。有一点需要注意,如果要生成依赖关系表,你的JS源文件必须带有模块名定义,比如:
// 模块名不能省略
KISSY.add('grp/header/index',function(S){
// your code
});
7,grunt server
启动报错Error: listen EACCES。
在Mac/Linux下需要root权限才能启用80端口,加上sudo
sudo grunt server
8,grunt server
提示Error: listen EADDRINUSE。
Flex Combo所需要使用的端口正在被使用中,如果这个端口是80端口,你需要检查系统中是否有其他web容器,比如Apache、Nginx等是否使用了80端口。如果不是,你需要检查是否系统中有其他Flex Combo正在运行。
9,运行grunt server
时报错:“Error: EMFILE, too many open files”
运行:
ulimit -n 10000
10,依赖的yeoman工具版本
该程序在yeoman 1.0.0-rc.1.1 版本下测试通过
11,grunt server后,访问我的文件报错:Fatal error: Cannot read property 'host' of undefined
是因为你访问的JS或CSS文件在本地不存在,且在线上也不存在,保证本地文件存在即可
默认情况下,你需要保证访问地址的host是g.tbcdn.cn或a.tbcdn.cn,如果使用别的域名,需要在~/.flex-combo/config.json
中修改配置项:
hosts:{
'a.tbcdn.cn':'122.255.67.241',
'g.tbcdn.cn':'155.238.23.250',
'your.host.name':'155.238.23.250'//ip地址配置到对应的cdn地址
}
12,SSI 不起作用?
看你是不是格式写的不对?<!--#include virtual="path.html" -->
,#
之前不要有空格
13,在windows下开启服务后,访问http://localhost
或者http://127.0.0.1
报错?
需要直接访问你的项目所在的目录http://localhost/group/pro/
- JSON接口模拟和映射
- juicer 模板的各种平台的转换
yo clam:install
/yo clam:search
,安装和查找Gallery模块