前端开发环境——fede2

2015-11-27 · 25 min read

这次介绍下自己搭建的前端开发环境:fede2(https://github.com/keenwon/generator-fede2)。今年 6 月底入职新公司,经过一段时间的熟悉后,开始渐渐参与到前端开发,发现不少问题:

  • 老东家的开发方式:后端使用 freemarker 模板。重构写好 html 和 css 后,前端改为 freemarker 模板,拿到后端的接口文档,基于一个叫 fed 的开源模块(https://www.npmjs.com/package/fed),解析 freemarker,模拟接口,让前端项目跑起来,实现前后端分离开发。
  • 新公司的开发方式:使用 jsp,各种乱七八糟的引用,各种乱七八糟的测试环境,没有接口文档,没有……

做了几个简单需求,前端调用不到后端的接口,各种跑不起来,各种环境(至少有测试和开发)参数要手动配置,前后端联调的时间超长,测试过程中 bug 极多,程序质量极低……终于忍无可忍,开始动手搭建合适的前端开发环境,于是就有了 fede 和 fede2。

fede 和 fede2 的区别#

这两个项目全都发到 github 上了,有兴趣的朋友可以看看,他们都是基于 express 实现接口模拟和拦截,基于 gulp 实现自动化,使用 bower 安装前端依赖包(可选),不同之处在于:

fede 是 AMD 模块,开发过程使用 require.js,使用 r.js 打包 AMD 模块(r.js 超难用!!),线上环境使用轻量级的 almond.js;使用 handlebar 模板引擎代替普通的 html 文件,利用 handlebar 的 helper 来区分不同的环境(开发,测试和生产);使用简单的 express 中间件拦截目标请求,mock 接口。

fede2 是 CommonJS 模块,使用 webpack 打包 CommonJS 模块;使用 jade 代替 handlebars,可实现复杂的嵌套,区分环境;基于 express mock 接口,使用 webpack 的 plugins 将线上请求拦截到本地;

总的来说,require.js\&AMD 这种奇淫巧计迟早 out,CommonJS 和 ES6 才是趋势;webpack 比 r.js 和 browserify 要好用、强大、灵活的多(browserify 没有深入了解,但是 webpack 几乎都能做到,直接跳过);jade 虽然丑,但是却和灵活强大,更适合用在服务端,handlebar 更适合用在客户端(其实 fede2 最终生成的还是 html,算是应用在“服务端”)。

fede2 的功能#

1、区分环境#

这个功能依赖于 jade(fede 依赖于 handlebars 的 helper),用过 jade 的都知道,jade 中可以定义变量,使用 if/else 做逻辑判断:

if development link(href='测试环境地址/index.css' type='text/css', rel='stylesheet') else
if production link(href='cdn地址/index.css' type='text/css', rel='stylesheet') else
link(href='css/index.css' type='text/css', rel='stylesheet')

使用 express 启动的时候,不带环境参数,默认使用本地文件。在 gulp 编译时,输入相应的参数,生成出引用不同 css 的 html 文件。其他与环境有关的处理方式类似。

2、模拟接口#

这个功能其实就是 express 的路由,例如:

'use strict'
module.exports = function (app) {
  app.post('/jisuanqi', function (req, res) {
    res.json({
      data: '123',
      code: '0',
      message: '',
    })
  })
}

然后使用类似http://localhost:3000/jisuanqi 的 url 就可以访问到该接口,我们可以根据后端提供的文档,在本地实现相应的接口,不用等待后端,实现前后端分离开发(什么后端 bug,测试环境挂了之类的最烦了,我都不记得测试环境的地址,反正我不依赖那不靠谱的测试环境)。

此外,前端模拟接口还有个好处就是可以覆盖各种场景,例如一个表单,当用户的手机号是 150XXXXXXXX 时,我们报错,是 130XXXXXXXX 时,我们返回成功。方便快捷的覆盖各种情景,提高前端代码质量。(公司有个实际场景是,根据手机号显示图形验证码,测试环境想要随心所欲的显现或不显示图形验证码,是很难的,而我们在开发的过程中,可以简单的通过输入的手机不同,控制验证码的显示隐藏)。

3、接口的拦截#

在这个功能上花的心思最多,但是用的比较少,具体原因后面说。先说下接口拦截是什么意思,例如我的线上接口地址是http://a.com/jisuanqi ,而我们模拟的接口在http://localhost:3000/jisuanqi 或者/jisuanqu ,难道要在发布的时候手动修改?或者用 gulp 批量修改?强迫症犯了,我希望的是类似 fiddler 的功能,直接在服务启动的时候,将线上 url 拦截到本地,而不修改 js 文件。

fede 的实现方案是在 express 静态资源中间件之前加一层 js 的拦截器,使用 nodejs 的 fs 模块读取 js 文件的内容,根据_map.js 文件定义的映射规则替换 js 文件中路径,响应给浏览器。这样不需要修改 js 文件,而在浏览器里打开的 js 文件接口地址已被拦截。

而 fede2 是基于 Webpack+Commonjs 的,所以自己实现了一个简单的 webpack plugins,同样根据_map.js 文件的映射规则修改 js 文件,返回给浏览器。具体的代码实现可以看 github(fedefede2

回答前面的问题,这个功能用的少,一般把接口地址配置在 html 页面上,使用 jade 区分环境,例如:

if production script(type='text/javascript'). var url = "生产环境url"; else
script(type='text/javascript'). var url = "本地url";

使用方法#

1、安装#

可以直接 clone github 上的项目,然后修改,也可以使用 yeoman 自动构建:

npm install -g generator-fede yo
yo fede

2、运行#

都是基于 gulp 的,可以查看gulpfile.js 文件。编译项目:

#带不带环境要看具体的配置
gulp build -e production

调试运行:

gulp server

问题#

有问题可以新建 issue 交流:https://github.com/keenwon/fede2/issues