在线本地调试大观

线上页面有 bug 了,或者需要修改或增加某项功能时,传统的开发/调试方法如下:

  1. 在本地搭建一套完整的开发环境,前后端代码甚至数据库等全在本机。想修改啥就修改啥,修改验证好了发布上线即可。好处是全盘控制非常强大,坏处是环境越复杂越麻烦。当本地与线上存在差异时,有些 bug 甚至无法重现。对于云时代的前端开发攻城师来说,这种方式太笨重了。
  2. 本地仅保存前端代码,修改后,提交到测试环境验证。这种方式无需搭建本地环境,但调试起来麻烦,遇到棘手的 bug 时,很可能需要反复 修改代码 -> 提交代码 -> 验证功能 -> 再次修改。虽然可以通过脚本部分实现自动化,但还是不够方便。
  3. 将线上页面保存到本地,直接修改页面中的 css/js 引用。这招非常简明快捷,在某些场合下的确是上上之选。但坏处也很明显,页面稍微复杂一点,就有可能失灵。

为了过上快乐幸福的生活,爱折腾的攻城师们想出了一个好点子:在线本地调试

名词解释

在线本地调试是指:

  1. 在线是指环境。环境是线上的,包括数据请求、cookie 等等,不是高仿,是货真价实的正品。
  2. 本地是指前端代码在本地,包括 js/css 等静态资源。
  3. 调试是指修改本地代码 + 刷新页面即可看到效果。

基本原理

很多事情,没有做不到,只有想不到。一旦开始追求美好的调试生活,立刻就能发现原理非常简单:

只要能将需要调试的代码映射到本地即可。

对前端来说,需要调试的代码一般是 js/css 文件。

html 代码有时也需要修改,可以搭建本地环境或用 Fiddler 等工具来实现,这篇博客里就不多说了。

我们将关注点聚焦到 js/css 文件的本地映射。

方式一:客户端工具

在 Windows 系统下,可以用大名鼎鼎的 Fiddler 来实现:AutoResponder Reference . 阿里巴巴中文站 UED 博客有图文教程:使用 Fiddler 提高前端工作效率

在 Mac 系统下,也有类似的工具:Charles .

客户端工具的好处是灵活,想映射什么就映射什么,想映射到哪就映射到哪。

坏处是要安装软件。在云时代,安装客户端软件显得太 out 啦。更恼人的是,Fiddler 依赖 Microsoft .NET Framework. Charles 更不用说了,是收费的。

方式二:服务端代理

比如在淘宝,可以先让所有攻城师都修改 hosts:

1 10.1.2.3    a.tbcdn.cn

使得 js/css 文件都通过内部代理服务器来访问。既然是内部服务器,就可以进一步通过 samba 等服务 mount 到本地。

好处是可定制性高,可以实现本地、测试、预发和线上等环境的自由切换等等功能。

坏处是对内网环境有依赖,在外网使用时,需要开启 VPN 软件。其次,要从服务器端代理回本机目录时,要通过 HFS 等客户端软件来实现,有点小麻烦。还有一个小缺陷是,当同时使用的人数过多时,服务器的性能和稳定性很重要。一旦出故障,攻城师就只能看美女了。

无论如何,淘宝聪明的攻城师们已实现了一个内部方案:UCool. 非常赞非常好用,内部人士不容错过。

方式三:利用虚拟主机与文件重写

作为攻城师,工作电脑上开一个 web 服务是家常便饭。假设我们使用的是老牌的 apache. 通过 Virtual Host 和 Rewrite Module 就可以实现本地映射。下面以淘宝为例来说明。

淘宝的 js/css 文件存放在 cdn 上,有两个域名:a.tbcdn.cn 和 assets.taobaocdn.com. 绝大部分线上页面使用的是a.tbcdn.cn. 因此我们可以绑定 a.tbcdn.cn 到本地,同时保持 assets.taobaocdn.com 依旧指向线上:

1 127.0.0.1            a.tbcdn.cn

接着修改 apache 的配置文件:

01 <VirtualHost *:80>
02   DocumentRoot "/Users/lifesinger/Sites/svn/assets/"
03   ServerName a.tbcdn.cn
04   RewriteEngine On
05   #
06   # handle combo url "/??path/to/a.js,path/to/b.js"
07   #
08   RewriteCond %{QUERY_STRING} ^\?.*\.(?:js|css)(?:,|$) [NC]
09   RewriteRule ^/.*$ /combo.php [QSA,L,NS,NC]
10   #
11   # redirect to online version when the requested file does not exist in local file system.
12   #
13   RewriteCond /Users/lifesinger/Sites/svn/assets/%{REQUEST_FILENAME} !-F
14   RewriteRule ^/(.+)$ http://assets.taobaocdn.com/$1 [QSA,P,L,NC]
15 </VirtualHost>

combo.php 的内容如下:

01 <?php
02  
03 $LOCAL_ROOT = "/Users/lifesinger/Sites/svn/assets";
04 $REAL_CDN = "http://assets.taobaocdn.com";
05  
06 $parts = explode("??", $_SERVER["REQUEST_URI"]);
07 $base = $parts[0];
08 $files = explode(",", $parts[1]);
09  
10 if (strpos($files[0], ".js")) {
11   header("Content-type: application/x-javascript");
12 } else {
13   header("Content-type: text/css");
14 }
15  
16 foreach($files as $file) {
17   $url = $base.$file;
18   $root = $REAL_CDN;
19  
20   if(file_exists($LOCAL_ROOT.$url)) {
21     echo "/* fetched from local file system */\n";
22     $root = $LOCAL_ROOT;
23   }
24  
25   echo file_get_contents($root.$url);
26 }

这样,要调试某个文件时,仅需要在本地 assets 目录下,按照线上的目录结构,放上需要修改的文件即可。本地没有的文件,会依旧访问线上。

这种方式很灵活强大,稍微修改修改,对绝大部分项目都适用。缺点是稍有门槛,要自己配置。对于爱折腾的攻城师来说,强烈推荐这种方式。

方式四:基于 seajs 的本地映射

如果一个页面是用 seajs 组织的,意味着所有用 seajs 加载的 js/css, 都可以映射到任意路径。我们以 markzhi.com 为例来说明。

正常访问 markzhi.com 时,加载的 js 文件都是线上的:

要将线上文件映射到本地,首先需要在访问地址上加上标识 http://markzhi.com/?seajs-debug. 注意右下角的悬浮层:

在输入框里填写上映射配置文件:http://localhost/seajs-map.js

seajs-map.js 的内容为:

01 define(function() {
02   var rules = [];
03  
04   // the map rules for markzhi.com
05   rules.push([
07     'http://localhost/~lifesinger/markzhi/portal/src/main/webapp/assets/'
08   ]);
09  
10   seajs.config({'map': rules});
11 });

rules 还可以是正则,比如:

1 // replace compressed version to debug version
2 rules.push([
3   /^(.*)\.js$/i,
4   '$1-debug\.js'
5 ]);

点击 SeaJS Debug Console 悬浮层的 Refresh 按钮,就可以看到除了 seajs 自身,其他文件到映射到本地了:

成功映射后,可以点击 Hide 按钮隐藏掉悬浮层,点击 Exit 按钮是退出 debug 模式,还原到正常状态。

注意:在 debug 状态时,页面的 title 会自动添加 [debug] 前缀以供辨识。

除了通过 ?seajs-debug 的方式来开启调试控制层,还可以通过 bookmarklet 的方式来开启:映射插件

这种方式的好处是:方便快捷,对调试页面所在机器无要求,开发机器上也只需要有 www 服务即可。比如对于 iPad 来说,可以用 ?seajs-debug 打开配置层,让配置文件指向开发机器。这样,就可以在开发机器上写代码,刷新 iPad 上的页面立刻就可以看到修改后的效果。这种便捷,是其他几种方式很难做到的。

坏处是:要调试的代码必须是通过 seajs 加载的,这是前提条件,必不可少。除此之外,暂时想不到有什么不妥之处。

小结

我最常用的方式是:

  1. 基于 seajs 的本地映射。如果要调试的文件是用 seajs 加载的,这种开发调试方式非常便捷。
  2. 利用虚拟主机和文件重写。当要调试的文件不是用 seajs 加载的,通过这种方式,可以一次配置,永久受用。

调试方式就如编辑器一样,没有最好,只有最合适。偶尔,notepad 会比 IDE 还方便,保存到本地的调试方式也有可能比其他任何方式都快捷。清晰地知道各种方式的利弊,合理选择就好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值