2014-07-13 by niuzhixiang
- SVN需要有一个主干(trunk),而若干个分支(branch)只能合并到主干,分支之间不能直接合并。相当于必须要以主干作为中转,才能实现分支的合并。
- Git中没有主干的概念,只有分支的概念。其中一个名为master的分支作为主分支,类似于SVN中的主干。但是master本质上也只是一个分支,与其他分支无异。Git可以支持分支之间直接合并,比较灵活,适用于互联网前端开发这种需求变化较大的应用场景。
- SVN的提交操作(commit)是直接将本地代码上传到远程仓库中。
- Git的提交操作是先将本地代码提交到本地仓库(通过git commit命令),然后再将本地仓库中的代码“推送”到远程仓库中(通过Git的push命令)。
- SVN中的版本控制是以“文件”为单元的,项目中的每一个文件都有自己的版本历史。
- Git中的版本控制是以整个项目为单元的,整个项目作为一个整体,有一个统一的版本历史。
- SVN远程仓库中存储的是各个版本的全量拷贝。
- Git远程仓库中存储的是各个版本之间的增量变化(实际上是每个版本的“快照”),因此所需的存储空间较小。
- 从Git远程仓库中将项目复制到本地,使用
git clone
命令(该命令类似于SVN中的checkout
,但在Git中checkout
命令用于切换本地分支)。举例:git clone [email protected]:drogba321/alibaba-learning-docs.git
- 新建一个项目以后,首先要使用
git init
命令进行git初始化(创建.git隐藏文件夹,表示这是一个git项目)。然后使用git remote add
命令创建远程仓库。举例:git remote add origin [email protected]:trip/h5-test.git
(该命令的意思是,创建一个名为origin的远程仓库,其git地址为[email protected]:trip/h5-test.git
)。 - 新增文件、修改文件和删除文件后,要首先将这些变化添加到版本控制中,使用
git add
命令(类似于SVN中的add
)。举例:git add .
(圆点符“.”代表将当前目录下的所有内容都添加到版本控制中)。 - Git add之后,要完成提交,第一步需要将代码提交到本地仓库,使用
git commit
命令。举例:git commit -m 'this is the first commit'
(引号中的内容为该版本的提交信息)。 - 第二步是将本地仓库中的代码“推送”到远程仓库,使用
git push
命令,举例:git push origin daily/0.1.1:daily/0.1.1
(origin为远程仓库的名称,第一个daily/0.1.1是本地分支的名字,第二个daily/0.1.1是远程分支的名字。该命令的意思是,将本地分支daily/0.1.1的代码推送到远程仓库origin的分支daily/0.1.1下)。 - 将远程仓库中的代码更新到本地,使用
git pull
命令(类似于SVN中的update
)。举例:git pull origin daily/0.1.1
(该命令的意思是,将远程仓库origin的内容更新到本地分支daily/0.1.1);或者git pull origin master:daily/0.1.1
(该命令的意思是,将远程仓库origin的远程分支master更新到本地分支daily/0.1.1。该命令可能会被reject,原因有待研究)。 - 切换本地分支,使用
git checkout
命令。举例:git checkout master
(该命令的意思是,将本地分支切换到master分支)。 - 查看当前状态,包括当前本地所处的分支,有哪些修改等等,使用
git status
命令。 - 查看本地与远程分支的列表,使用
git branch
命令。如果只想查看远程分支的列表,使用git branch -r
命令。如果要新建分支,使用git branch [newBranchName]
命令(其中newBranchName为新分支名)
- 首先,在浏览器中开启正向代理
127.0.0.1:8080
。 - 然后,进入项目根目录(也即
Gruntfile.js
所在目录)执行grunt demo
(源码调试,一般调试的是src目录下的代码)或者grunt debug
(目标代码调试,一般调试的是build目录下的代码)。该指令会开启两个服务:本机8080端口上的反向代理服务,以及本机8081端口上的flexcombo服务(这两个服务的端口号默认分别为8080和8081,不过也可以自己配置)。 - 最后,用浏览器访问
demo.com/{path}
或demo.com/{path}?ks-debug
(后者开启了kissy调试功能),进行代码的调试。
在浏览器开启正向代理“127.0.0.1:8080”后,所有在浏览器地址栏输入的url都会交给该代理来处理,即交给本机的8080端口来处理;而执行grunt demo
或grunt debug
命令后,在本机的8080端口上会开启一个反向代理服务(这个端口由配置参数proxyport
指定,默认为8080)。于是url请求便由反向代理接管。如果请求地址为配置参数proxyHosts
指定的域名(例如demo.com
)或[ag].tbcdn.cn
,则反向代理服务器会将请求转发至flexcombo服务器(flexcombo服务器也是由grunt demo/debug
启动的,flexcombo的端口由配置参数port
指定,默认为80),flexcombo服务器接收到url请求后,会去配置参数target
指定的本地路径取文件;如果请求地址是其它域名,则反向代理服务器去公网取文件。这种方式可以模拟真实环境的调试(例如在淘宝首页中调试Slide组件:淘宝首页引用Slide组件的路径是http://g.tbcdn.cn/kg/slide/1.2/index.js
,在开启浏览器正向代理和grunt debug
后,由于该请求域名为g.tbcdn.cn
,所以该请求最终会返回本地build目录下的目标代码文件./build/index.js
,从而实现本地代码模拟真实线上环境的调试)。以下是Gruntfile.js
中关于flexcombo配置的代码片段。
grunt.initConfig({
// FlexCombo服务配置
// https://npmjs.org/package/grunt-flexcombo
//
// 注意:urls 字段末尾不能有'/'
flexcombo : {
// 源码调试服务
demo : {
options : {
//反向代理服务器的端口,一般取8080
proxyport : '8080',
//flexcombo将特定域名下的请求映射到的本地路径,源码调试一般为'src/',目标代码调试一般为'build/'
target : 'src/',
//flexcombo将[ag].tbcdn.cn域名下的该url请求映射到target指定的本地路径下,例如http://g.tbcdn.cn/kg/slide/index.js => ./src/index.js
urls : '/kg/<%= pkg.name %>/',
//flexcombo服务器的端口,默认为80,一般取8081
port : '8081',
//flexcombo对这些域名的请求也映射到target指定的本地路径下,例如http://demo.com/d1.html => ./src/d1.html
proxyHosts : ['demo', 'demo.com'],
servlet : '?',
longPolling : false,
separator : ',',
charset : 'utf8'
}
},
// 目标代码调试服务
debug : {
options : {
// 无线H5项目调试,可打开host配置,用法参照
// https://speakerdeck.com/lijing00333/grunt-flexcombo
target : 'build/',
proxyport : '8080',
urls : '/kg/<%= pkg.name %>/<%= pkg.version %>',
port : '8081',
proxyHosts : ['demo', 'demo.com', 'h5.m.taobao.com'],
servlet : '?',
separator : ',',
longPolling : false,
charset : 'utf8',
filter : {
'-min\\.js' : '.js',
}
}
}
}
});
另外,flexcombo在处理请求url时,还会读取src/config.js
中的配置,如果请求url后面挂着“?ks-debug”,则说明是开启kissy调试,flexcombo会返回本地的js文件,这样可以供调试js代码用;如果请求url后面没有挂着“?ks-debug”,则说明未开启kissy调试,flexcombo会返回“g.assets.daily.taobao.net”(预发环境)或“g.tbcdn.cn”(线上环境)域名下面的js文件,而如果此时代码还未预发到预发环境,或还未正式发布到线上环境,则这些域名下就不会有相应的js文件,就无法进行js代码的调试了。(注:如果是线上环境g.tbcdn.cn
域名下,则该请求最终仍会由flexcombo映射到本地文件,具体详情请自行深入分析~)以下是src/config.js
的源代码示例。
(function(){
KISSY.config('tag', null);
var debug = (location.search.indexOf('ks-debug') >= 0);
if (debug) {
var srcPath = "../../";
KISSY.config({
combine:false,
packages:[
{
/*注:这里的name对应于在使用Kissy模块时的包名。例如在使用这个模块时:
KISSY.use('h5-2banner-active/pages/secondpage/index', ...);
其中使用的包名'h5-2banner-active'就对应于这里的name参数。它的路径
由path参数指定,此处即'../../'。因此最终实际使用的是在这个路径下
'../../pages/secondpage/index.js'的模块。*/
name:"h5-2banner-active",
path:srcPath,
charset:"utf-8",
ignorePackageNameInUri:true,
debug:true
}
]
});
} else {
if (location.host.match(/(waptest\.taobao|wapa.taobao|daily.taobao.net)/)) {
KISSY.Config.daily = true;
}
var srcHost = KISSY.Config.daily ?
'g.assets.daily.taobao.net' :
'g.tbcdn.cn';
KISSY.config({
combine:true,
packages: [
{
name: 'h5-2banner-active',
path: 'http://' + srcHost +'/trip/h5-2banner-active/@@version',
ignorePackageNameInUri: true
}
]
});
}
})();
- build:执行构建(包括将src目录下的源码文件进行kmc合并、less/sass编译、代码压缩等操作,最后生成build目录下的目标代码文件)。
- demo:进行源码调试(调试src目录下的源代码)。
- debug:进行目标代码调试(调试build目录下的目标代码)。
- newbranch:创建一个新的本地日常分支,并切换到该分支下。
- prepub:预发布资源文件(js、css文件等),将资源文件发布到日常环境(“g.assets.daily.taobao.net”域名下)。事实上,该任务就是使用git push命令将代码提交到日常分支(daily分支)。
- publish:正式发布资源文件,将资源文件发布到线上环境(“g.tbcdn.cn”域名下)。事实上,该任务就是使用git push命令将代码提交到线上分支(publish分支)。
- awpp:发布H5页面。可以选择发布到“日常”/“预发”/“预上线”/“上线”这四个环境中。
- 备注:对于H5页面文件,一共有四个环境:日常(
wapp.waptest.taobao.com
)、预发(wapp.wapa.taobao.com
)、预上线(不清楚~)和上线(h5.m.taobao.com
)(均通过grunt awpp任务发布,执行该任务时命令行会提示选择具体发布到哪个环境);而对于js、css等资源文件,一共只有两个环境:预发(g.assets.daily.taobao.net
)(或称日常,通过grunt prepub任务发布)和线上(g.tbcdn.cn
)(通过grunt publish任务发布)。
- yo clam:初始化一个标准的项目。包括生成该项目的
Gruntfile.js
、package.json
、abc.json
等配置文件;生成src目录等等。 - yo clam:h5:初始化一个H5页面。该命令应当在
src/pages
目录下执行,会生成标准的页面模板index.html
,并自动生成配套的index.js
、index.less
等文件。 - yo clam:mod:初始化一个模块。应在
src/mods
目录下执行。 - yo clam:widget:初始化一个widget(即一个标准的kissy组件),应在
src/widgets
目录下执行。 - yo clam:h:显示帮助信息。
grunt任务都是在Gruntfile.js
和package.json
配置文件中定义并注册的。每个任务本质上就是一个命令集合,是对常用命令的进一步封装。如果想要自定义一个新任务或者修改已有任务的执行方式,直接编辑Gruntfile.js
源文件即可。以下代码为Gruntfile.js
配置文件中对于任务“build”的定义。可以看出,build任务就是按顺序执行copy、less、sass、kmc、tms等等这些子任务(这些子任务在别处已经定义过了)。
// build任务
grunt.registerTask('exec_build', '执行构建脚本', function () {
var actions = [
'clean:build',
//'tpl_compiler',
'copy',
'less',
'sass',
/*'mytps',*/
'kmc',
'tms'
];
if(isH5){
actions = actions.concat([
'inline-assets'
]);
}
actions = actions.concat([
'combohtml',
'replace:dist',
'uglify',
'cssmin'
]);
task.run(actions);
});
此外,这些构建任务中所使用到的nodejs模块都放在node_modules目录下了,例如grunt-flexcombo模块、grunt-kmc模块等等,必要时也可以直接修改这些模块的源代码。
对于一个典型的H5项目(例如汽车票项目h5-car),代码正式发布后,项目中的js和css文件会部署到Assests CDN服务器(域名为g.tbcdn.cn
),项目中的html文件会部署到CDN服务器(域名为h5.m.taobao.com
)。