在做fekit本地vm模拟开发的时候,时常需要与服务端的数据交互,不同开发者有不同的做法,有的直接把url指向到一个静态json文件,联调的时候再改回来,有的要借助第三方软件来实现跳转控制,不管哪种方式都需要很多成本,一两个页如此可能能接受,但长期如此也会让人疲惫。如今fekit自身也能支持数据模拟了,妈妈再也不用担心我的工作了。

服务启动

启动 fekit server 时,可以通过读取配置,进行不同的 mock 处理 如: fekit server -m mock.js

配置文件

module.exports = {
    "/exact/match/1": "exact.json",
    "/exact/match/2": "exact.mockjson",
    "/exact/match/3": "https://raw.githubusercontent.com/rinh/fekit/master/docs/mock/exact.json",
    "/exact/match/4": "exact.js",
    rules: [{
        pattern: "/exact/match/5",
        respondwith: "exact.json"
    }, {
        pattern: /^\/regex\/match\/a\/\d+/,
        respondwith: "regex.json",
        jsonp: "__jscallback"
    }, {
        pattern: /^\/regex\/match\/b\/\d+/,
        respondwith: function(req, res, context) {
            res.end(JSON.stringify(Object.keys(context)));
        }
    }]
};
  • 配置文件定义一个 node 模块
  • keypattern 属性是字符串,准确匹配 url(包括 query)
  • pattern 属性是正则表达式,正则匹配 url
  • jsonp 属性指定 jsonp 请求的回调函数名,默认为 "callback"
  • value 或 respondwith 属性给定文件均为配置文件相对路径
  • value 或 respondwith 属性有如下方案:

raw

"/exact/match/1""/exact/match/5"/^\/regex\/match\/a\/\d+/,指定文件是 .json 文件,.json 文件内容原样返回

mockjson

"/exact/match/2",指定文件是 .mockjson 文件,如下:

{
    "fathers|5-10": [{
        "id|+1": 0,
        "married|0-1": true,
        "name": "@MALE_FIRST_NAME @LAST_NAME",
        "sons": null,
        "daughters|0-3": [{
            "age|0-31": 0,
            "name": "@FEMALE_FIRST_NAME"
        }]
    }]
}

遵循 mockJSON 的写法,生成随机数据返回。

proxy_pass

"/exact/match/3",代理请求指定地址,并将请求结果返回。

action

"/exact/match/4",自定义请求处理函数,给定 js 文件代码如下:

module.exports = function(req, res, context) {
    res.end(JSON.stringify({
        "exact": true
    }));
};

或如 /^\/regex\/match\/b\/\d+/ 直接写在配置文件中

为什么要使用fekit代理

使用代理可以截获任意请求,并把它改成你想要的内容或转发到其它服务器,过程如下:

请求www.163.com ----> |浏览器| ----> |fekit proxy| -----> |线上|

经过fekit proxy时,可以把 www.163.com 截获下来。

如何使用

最低版本要求

0.2.87

###配置 ~/fekit.hosts

# 与一般的 hosts 配置一样
127.0.0.1 qunarzz.com

# 可以将其它请求截获,由本地处理
proxy_pass http://www.baidu.com/(.*)\.do http://127.0.0.1/123/baidu/$1.html

使用

第一步:

fekit server -o 启动后会有log [LOG] fekit proxy server 运行成功, 端口为 10180.

第二步:

将浏览器的代理服务器设置,设置为 127.0.0.1 ,端口是10180 即可

组件源:http://l-registry.fe.dev.cn6.qunar.com

你的配置

公司内网有 fekit 组件源服务器,如果你想使用它,需要在你的用户主目录,放置一个文件:.fekitrc , 内容为

{
    "registry" : "l-registry.fe.dev.cn6.qunar.com:3300"
}

fekit.config

要成为一个包,在 fekit 项目内应包括 fekit.config 文件,它是用来安装及发布的依据。

{
     "name" : "包名称" ,
     "author" : "rinh" ,
     "email" : "rinh@abc.com" ,
     //指定某个文件作为包入口, 该路径以src目录为根.  默认使用 src/index  
     "main" : "home" ,                   
     "version" : "1.2.3" , //遵循semver
     "dependencies" : {
           "dialog" : "1.2.x"    
     } ,
     "description" : "" ,
     "scripts" : {}
}

README.md

你必须在项目根目录下,放置一个 README.md 文件,它的语法格式是 markdown(请参考)

如何安装,发布?

fekit install xxx
fekit publish
fekit unpublish xxxx@1.2.3

在不同的环境(local,dev,prd)可以使用宏(即环境变量)来方便开发。

使用场景

我们会在不同的环境设置一个接口的url:

本地开发的时候:

var url = "http://l-test1.dev.cn6.qunar.com"

开发机联调的时候:

var url = "http://l-test1.beta.cn6.qunar.com"

发到线上后:

var url = "http://hotel.qunar.com"

所以需要一种机制,来根据环境变更 url 的内容。

如何使用

配置文件

在 fekit.config 同级目录,创建 environment.yaml(使用yaml格式) 内容为:

local:
    DEBUG: true

dev:
    DEBUG: true

prd:
    DEBUG: false

这样,在不同环境下,DEBUG变量的值就是不同的。

如果你更喜欢用 json ,也可以创建 environment.json 内容为:

{
 "local": {
     "DEBUG": true
 } ,
 "dev": {
    "DEBUG": true
 } ,
 "prd": {
    "DEBUG": false
 }
}

最后,如果你如力神一般洁癖,不想有那么多文件在根目录,也可以把配置写到 fekit.config

{
    "compiler": "modular",
    "name": "macro",
    "version": "0.0.0",
    "dependencies": {},
    "alias": {},
    "export": [
        "index.js"
    ],
    "environment" : {
         "local": {
             "DEBUG": true
         } ,
         "dev": {
            "DEBUG": true
         } ,
         "prd": {
            "DEBUG": false
         }
    }
}

源码

在源码中,使用环境变量的方法是通过特殊的写法来调用,如:

/*[变量名]*/
var isDebug = /*[DEBUG]*/;

编译后的结果就是:

var isDebug = true; // 这是在本地的时候

环境

local : 指的是使用 fekit server 的环境
dev : 指的是 fekit pack 后的代码环境
prd : 指的是 fekit min 后的代码环境

目前, fekit min 后,会生成2种不同的version,如下面例子:

├── prd
│   ├── loader@fe769d38cb00b17ba0f1e9bd47c65711.js
│   ├── moduleA@74ee0c143d4c353b478652feaaea343c.js
│   ├── moduleB@a4ac5f422a22a41ac6efbf42e377de0f.js
│   └── moduleC@817dc24c667eec004cab96b26a24256c.js
├── src
│   ├── loader.js
│   ├── moduleA.js
│   ├── moduleB.js
│   └── moduleC.js
└── ver
    ├── loader.js.ver
    ├── moduleA.js.ver
    ├── moduleB.js.ver
    ├── moduleC.js.ver
    └── versions.mapping

/ver/ 目录

其中包含所有与 /prd/ 下文件路径一致的版本号文件。 如:

/prd/loader@fe769d38cb00b17ba0f1e9bd47c65711.js 这个文件就有对应的版本号文件为 /ver/loader.js.ver

而 ver目录中的内容大概会这么用:

在 html/jsp/php 页面中:

源码为:
<script src="http://qunarzz.com/hotel_fekit/prd/scripts/base@<!-- include("/ver/scripts/base.js.ver") -->.js"></script>
上线后变为:
<script src="http://qunarzz.com/hotel_fekit/prd/scripts/base@d7dadc627df2c525fc695a60bcba9f18.js"></script>

使用这种方案,因为没有缓存,所以在发布 app 项目后可以不重启即生效,但会增加io压力。

mapping 文件

fekit min 后会生成 /var/versions.mapping ,内容如:

loader.js#fe769d38cb00b17ba0f1e9bd47c65711
moduleA.js#74ee0c143d4c353b478652feaaea343c
moduleB.js#a4ac5f422a22a41ac6efbf42e377de0f
moduleC.js#817dc24c667eec004cab96b26a24256c

所以,使用 jsp/php 的项目,可以读取这个文件后形成一个 HashMap。 然后在页面中

源码为:
<script src="http://qunarzz.com/hotel_fekit/prd/scripts/base@<%=VERSION_MAP.get("loader.js")%>.js"></script>
上线后变为:
<script src="http://qunarzz.com/hotel_fekit/prd/scripts/base@d7dadc627df2c525fc695a60bcba9f18.js"></script>

使用这种方案,一般都是在发布后先读取 versions.mapping 文件并缓存。 优点是没有 io压力, 但发布 app 后需要重新读取 versions.mapping。

要解决的问题

将velocity(vm)的代码放到前端项目(qzz)中,并且解决发布联调的问题。

为什么要这么做

  • 前端工程师可以在项目中直接写 vm 模板
  • 可以做以前做不到的事情,比如将 js 压缩后放到页面中
  • 等等

前提条件

  • 需要升级fekit至 0.2.85
  • 如果想看看后端是如何工作,必须安装java,maven,以及把maven按照公司的settings.xml进行设置

DEMO

直接上实例:

前端项目: git@gitlab.corp.qunar.com:fe/q_dvelocity.git

后端项目: git@gitlab.corp.qunar.com:scmtest/dvelocity_web.git

DEMO如何联调

DEMO要展示的,是在前端项目中针对 vm 目录中的修改如何同步到后端项目中。

前端

执行 fekit pack && fekit sync, 这时 sync 会将你的代码上传到nexus仓库, 但前端可以完全不用关心这点。

后端

执行 mvn clean package -Dmaven.test.skip=true -U

仔细观查 src/main/webapp/WEB-INF/refs/vm 中的内容,就是前端项目的内容

如何实现的?

[前端] refs

fekit.config 中,新增 refs 配置。 refs是个特殊目录,它是自动生成的,在部署的时候,它会按配置部署到后端项目中。

关于配置,可以参考官网的配置项说明

[前端] pom.xml 中的版本号

在 pom.xml 有以下内容

<!--version由bds生成的btag/rtag来决定-->
<version>1.0.2-dev-SNAPSHOT</version>

其中 version 的内容,是在创建分支的时候,自动填写的。 所以它一般应该是分支名-SNAPSHOT,无需手动更改。

[前端] fekit sync 变慢了

在 sync 的时候,发现会变慢。 其实是将代码上传到nexus仓库了。

[后端] pom.xml 中的配置

基本没有变化,依照 CM给的配置 即可。

[后端] 如何得到前端的vm内容

让前端同学 fekit pack && fekit sync ,然后确认*分支名-SNAPSHO*填写正确,执行 mvn clean package -Dmaven.test.skip=true -U 即可。

Fekit 中使用 domain_mapping 分散 css 中背景图片域名

一句话

配置格式

{
    "domain_mapping": "原域名1 原域名2 原域名3 => 新域名1 新域名2 新域名3"
}

方式一:文件级(单页面适用)

配置在 fekit.config 的 export 节点中:

{
    "export": [{
        "path": "index.css",
        "domain_mapping": "source.qunar.com => simg1.qunarzz.com simg2.qunarzz.com simg3.qunarzz.com"
    }]
}

方式二:频道全局级(推荐)

配置在 fekit.config 的 export_global_config 节点中:

{
    "export_global_config": {
        "domain_mapping": "source.qunar.com => simg1.qunarzz.com simg2.qunarzz.com simg3.qunarzz.com"
    }
}

优先级:文件级>频道全局级

本地开发调试

只要启动了fekit server,剩下的都是自动滴。

开发机host

127.0.0.1 quanrzz.com # 或者任何一台你喜欢的qzz开发机IP
192.168.237.71 source.qunar.com simg1.qunarzz.com simg2.qunarzz.com simg3.qunarzz.com simg4.qunarzz.com

引言

在开发中,可能会遇到 https://qunarzz.com 这样的需求,如何使用 fekit 进行开发呢

下载证书文件

请先下载以下文件,并放到同一个目录中(比如 c:\cert\)

server.crtserver.key

启动选项

fekit 在 0.2.63 版本支持 https,使用方式为:

fekit server -s c:\cert\server.crt

浏览器端

https://qunarzz.com, 直接访问可能会被拦截,因为证书不是被信任的,可以点击临时信任解决这个问题。

如果想永久解决,请按这个操作 添加自签发的SSL证书为受信任的根证书

问题

注意: 这个证书解决的是 qunarzz.com 域名,如果你的 https 是其它域名,你需要生成自己的证书。 请参考

443端口被vmware-hostd.exe占用的问题可参考 http://www.cnblogs.com/minideas/p/3559508.html

fekit gist 是干什么用的?

  • 当你为自己的技术分享写了一个demo,但它依赖很多js,css,image等文件,找不到地方放,怎么办?
  • 当你希望有一个地方专门管理自己的代码片断,但是申请机器不靠谱,又没有比较合适的办法,怎么办?
  • 当你希望有一个既提供http服务,又非常方便的支持上传下载,怎么办?
  • 当你写了一个README.md,但是需要把它以编译方式show给别人看,怎么办?

以上一切,就是 fekit gist 主要解决的问题。

fekit gist 如何工作?

请访问 http://gist.corp.qunar.com

如何使用

安装

npm install fekit-extension-gist -g

安装完后,在命令行输入fekit看看有没有gist指令,如果没有,需要如下操作:

创建文件

 ~/.fekit/.extensions/gist.js

文件内容是:

exports.version = '0.0.6';
exports.path = '/usr/local/lib/node_modules/fekit-extension-gist/index.js';

注册用户

首先需要有2个前提:

  1. 请先用 fekit login 登录,如果已经登录就不用再做这步了
  2. 需要在 l-registry.fe.dev.cn6 这台机器上有帐号,请用 cloud.corp.qunar.com 申请

确认好这2点后,只要

fekit gist --register

就可以了。

上传某个目录

假设在 /home/hao.lin/demo1 有这么个目录,其中有你写的代码:

cd /home/hao.lin/demo1
fekit gist
[LOG] 上传 /home/hao.lin/demo1 至 http://gist.corp.qunar.com/hao.lin/demo1
[ASK] 是否确认? (yes/no):

输入 y 或 yes 即可上传。

下载某个目录

fekit gist http://gist.corp.qunar.com/hao.lin/demo1

即可将 demo1 目录下载到当前目录中

删除线上目录

fekit gist -d http://gist.corp.qunar.com/hao.lin/demo1

克隆别人的项目

fekit gist -c http://gist.corp.qunar.com/hao.lin/demo1

当然不能克隆自己的项目哦!

清空自己的线上目录!!

mkdir empty_dir && cd empty_dir && fekit gist.

该方法基本上毁灭性质的,一旦操作基本不能恢复!!

实现原理

其实基本上是使用了 rsync 的同步的功能。 所以你机器上一定要有 rsync 才能用哦!

当遇到这种情况...

我们平时开发时,会使用 fekit server 进行本地调试。

比如某项目结构是:

.
├── README.md
├── build
│   ├── build.coffee
│   └── runtime.coffee
├── fekit.config
├── index.html
└── src
    ├── loader.js
    ├── moduleA.js
    ├── moduleB.js
    └── moduleC.js

loader.js 依赖 jquery。

依赖渲染的普通模式

启动 fekit server 后,

当加载 http://localhost/prd/loader.js 后,内容为:

document.write('<script src="http://localhost/fekit_modules/jquery/prd/jquery.js?no_dependencies=true"></script>');
document.write('<script src="http://localhost/fekit_modules/jquery/prd/index.js?no_dependencies=true"></script>');
document.write('<script src="http://localhost/prd/loader.js?no_dependencies=true"></script>');

自定义渲染模式

当出于某些目的,想把返回的结果变为:

loader.load('http://localhost/fekit_modules/jquery/prd/jquery.js?no_dependencies=true')
loader.load('http://localhost/fekit_modules/jquery/prd/index.js?no_dependencies=true')
loader.load('http://localhost/prd/loader.js?no_dependencies=true')

只要配置 fekit.config 中的

"development":{
    "custom_render_dependencies" : "./build/runtime.coffee"
}

请参考项目

http://gist.corp.qunar.com/hao.lin/loader-test

注意!!!

该功能只影响 fekit server 生成的代码,不会影响最终内容。 也就是,如果你依赖这种模式做 lazyload,它也只会在本地开发的时候有作用。